oh-my-customcode 0.12.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +8 -11
  2. package/dist/cli/index.js +137 -336
  3. package/dist/index.js +99 -260
  4. package/package.json +2 -4
  5. package/templates/.claude/skills/codex-exec/SKILL.md +123 -0
  6. package/templates/.claude/skills/codex-exec/scripts/codex-wrapper.cjs +413 -0
  7. package/templates/CLAUDE.md.en +1 -0
  8. package/templates/CLAUDE.md.ko +1 -0
  9. package/templates/.codex/agents/arch-documenter.md +0 -33
  10. package/templates/.codex/agents/arch-speckit-agent.md +0 -47
  11. package/templates/.codex/agents/be-express-expert.md +0 -30
  12. package/templates/.codex/agents/be-fastapi-expert.md +0 -43
  13. package/templates/.codex/agents/be-go-backend-expert.md +0 -43
  14. package/templates/.codex/agents/be-nestjs-expert.md +0 -28
  15. package/templates/.codex/agents/be-springboot-expert.md +0 -40
  16. package/templates/.codex/agents/db-postgres-expert.md +0 -36
  17. package/templates/.codex/agents/db-redis-expert.md +0 -36
  18. package/templates/.codex/agents/db-supabase-expert.md +0 -35
  19. package/templates/.codex/agents/de-airflow-expert.md +0 -34
  20. package/templates/.codex/agents/de-dbt-expert.md +0 -34
  21. package/templates/.codex/agents/de-kafka-expert.md +0 -81
  22. package/templates/.codex/agents/de-pipeline-expert.md +0 -32
  23. package/templates/.codex/agents/de-snowflake-expert.md +0 -36
  24. package/templates/.codex/agents/de-spark-expert.md +0 -36
  25. package/templates/.codex/agents/fe-svelte-agent.md +0 -29
  26. package/templates/.codex/agents/fe-vercel-agent.md +0 -37
  27. package/templates/.codex/agents/fe-vuejs-agent.md +0 -30
  28. package/templates/.codex/agents/infra-aws-expert.md +0 -47
  29. package/templates/.codex/agents/infra-docker-expert.md +0 -47
  30. package/templates/.codex/agents/lang-golang-expert.md +0 -43
  31. package/templates/.codex/agents/lang-java21-expert.md +0 -39
  32. package/templates/.codex/agents/lang-kotlin-expert.md +0 -43
  33. package/templates/.codex/agents/lang-python-expert.md +0 -43
  34. package/templates/.codex/agents/lang-rust-expert.md +0 -43
  35. package/templates/.codex/agents/lang-typescript-expert.md +0 -43
  36. package/templates/.codex/agents/mgr-claude-code-bible.md +0 -58
  37. package/templates/.codex/agents/mgr-creator.md +0 -39
  38. package/templates/.codex/agents/mgr-gitnerd.md +0 -45
  39. package/templates/.codex/agents/mgr-sauron.md +0 -161
  40. package/templates/.codex/agents/mgr-supplier.md +0 -35
  41. package/templates/.codex/agents/mgr-sync-checker.md +0 -38
  42. package/templates/.codex/agents/mgr-updater.md +0 -33
  43. package/templates/.codex/agents/qa-engineer.md +0 -32
  44. package/templates/.codex/agents/qa-planner.md +0 -73
  45. package/templates/.codex/agents/qa-writer.md +0 -27
  46. package/templates/.codex/agents/sys-memory-keeper.md +0 -43
  47. package/templates/.codex/agents/sys-naggy.md +0 -37
  48. package/templates/.codex/agents/tool-bun-expert.md +0 -26
  49. package/templates/.codex/agents/tool-npm-expert.md +0 -30
  50. package/templates/.codex/agents/tool-optimizer.md +0 -34
  51. package/templates/.codex/codex-native-hash.txt +0 -1
  52. package/templates/.codex/contexts/dev.md +0 -20
  53. package/templates/.codex/contexts/ecomode.md +0 -63
  54. package/templates/.codex/contexts/index.yaml +0 -41
  55. package/templates/.codex/contexts/research.md +0 -28
  56. package/templates/.codex/contexts/review.md +0 -23
  57. package/templates/.codex/hooks/hooks.json +0 -150
  58. package/templates/.codex/install-hooks.sh +0 -100
  59. package/templates/.codex/rules/MAY-optimization.md +0 -29
  60. package/templates/.codex/rules/MUST-agent-design.md +0 -57
  61. package/templates/.codex/rules/MUST-agent-identification.md +0 -29
  62. package/templates/.codex/rules/MUST-continuous-improvement.md +0 -25
  63. package/templates/.codex/rules/MUST-intent-transparency.md +0 -42
  64. package/templates/.codex/rules/MUST-language-policy.md +0 -27
  65. package/templates/.codex/rules/MUST-orchestrator-coordination.md +0 -128
  66. package/templates/.codex/rules/MUST-parallel-execution.md +0 -97
  67. package/templates/.codex/rules/MUST-permissions.md +0 -30
  68. package/templates/.codex/rules/MUST-safety.md +0 -23
  69. package/templates/.codex/rules/MUST-sync-verification.md +0 -125
  70. package/templates/.codex/rules/MUST-tool-identification.md +0 -82
  71. package/templates/.codex/rules/SHOULD-agent-teams.md +0 -39
  72. package/templates/.codex/rules/SHOULD-ecomode.md +0 -37
  73. package/templates/.codex/rules/SHOULD-error-handling.md +0 -33
  74. package/templates/.codex/rules/SHOULD-hud-statusline.md +0 -32
  75. package/templates/.codex/rules/SHOULD-interaction.md +0 -34
  76. package/templates/.codex/rules/SHOULD-memory-integration.md +0 -39
  77. package/templates/.codex/rules/index.yaml +0 -141
  78. package/templates/.codex/skills/airflow-best-practices/SKILL.md +0 -56
  79. package/templates/.codex/skills/audit-agents/SKILL.md +0 -116
  80. package/templates/.codex/skills/aws-best-practices/SKILL.md +0 -280
  81. package/templates/.codex/skills/claude-code-bible/SKILL.md +0 -100
  82. package/templates/.codex/skills/claude-code-bible/scripts/fetch-docs.js +0 -272
  83. package/templates/.codex/skills/create-agent/SKILL.md +0 -91
  84. package/templates/.codex/skills/dbt-best-practices/SKILL.md +0 -54
  85. package/templates/.codex/skills/de-lead-routing/SKILL.md +0 -243
  86. package/templates/.codex/skills/dev-lead-routing/SKILL.md +0 -94
  87. package/templates/.codex/skills/dev-refactor/SKILL.md +0 -123
  88. package/templates/.codex/skills/dev-review/SKILL.md +0 -81
  89. package/templates/.codex/skills/docker-best-practices/SKILL.md +0 -275
  90. package/templates/.codex/skills/fastapi-best-practices/SKILL.md +0 -270
  91. package/templates/.codex/skills/fix-refs/SKILL.md +0 -107
  92. package/templates/.codex/skills/go-backend-best-practices/SKILL.md +0 -338
  93. package/templates/.codex/skills/go-best-practices/SKILL.md +0 -203
  94. package/templates/.codex/skills/help/SKILL.md +0 -125
  95. package/templates/.codex/skills/intent-detection/SKILL.md +0 -215
  96. package/templates/.codex/skills/intent-detection/patterns/agent-triggers.yaml +0 -349
  97. package/templates/.codex/skills/kafka-best-practices/SKILL.md +0 -52
  98. package/templates/.codex/skills/kotlin-best-practices/SKILL.md +0 -256
  99. package/templates/.codex/skills/lists/SKILL.md +0 -78
  100. package/templates/.codex/skills/memory-management/SKILL.md +0 -195
  101. package/templates/.codex/skills/memory-recall/SKILL.md +0 -152
  102. package/templates/.codex/skills/memory-save/SKILL.md +0 -126
  103. package/templates/.codex/skills/monitoring-setup/SKILL.md +0 -115
  104. package/templates/.codex/skills/npm-audit/SKILL.md +0 -72
  105. package/templates/.codex/skills/npm-publish/SKILL.md +0 -63
  106. package/templates/.codex/skills/npm-version/SKILL.md +0 -75
  107. package/templates/.codex/skills/optimize-analyze/SKILL.md +0 -55
  108. package/templates/.codex/skills/optimize-bundle/SKILL.md +0 -67
  109. package/templates/.codex/skills/optimize-report/SKILL.md +0 -74
  110. package/templates/.codex/skills/pipeline-architecture-patterns/SKILL.md +0 -83
  111. package/templates/.codex/skills/postgres-best-practices/SKILL.md +0 -66
  112. package/templates/.codex/skills/python-best-practices/SKILL.md +0 -222
  113. package/templates/.codex/skills/qa-lead-routing/SKILL.md +0 -290
  114. package/templates/.codex/skills/react-best-practices/SKILL.md +0 -101
  115. package/templates/.codex/skills/redis-best-practices/SKILL.md +0 -83
  116. package/templates/.codex/skills/result-aggregation/SKILL.md +0 -164
  117. package/templates/.codex/skills/rust-best-practices/SKILL.md +0 -267
  118. package/templates/.codex/skills/sauron-watch/SKILL.md +0 -144
  119. package/templates/.codex/skills/secretary-routing/SKILL.md +0 -203
  120. package/templates/.codex/skills/snowflake-best-practices/SKILL.md +0 -65
  121. package/templates/.codex/skills/spark-best-practices/SKILL.md +0 -52
  122. package/templates/.codex/skills/springboot-best-practices/SKILL.md +0 -218
  123. package/templates/.codex/skills/status/SKILL.md +0 -153
  124. package/templates/.codex/skills/supabase-postgres-best-practices/SKILL.md +0 -99
  125. package/templates/.codex/skills/typescript-best-practices/SKILL.md +0 -321
  126. package/templates/.codex/skills/update-docs/SKILL.md +0 -140
  127. package/templates/.codex/skills/update-external/SKILL.md +0 -149
  128. package/templates/.codex/skills/vercel-deploy/SKILL.md +0 -73
  129. package/templates/.codex/skills/web-design-guidelines/SKILL.md +0 -118
  130. package/templates/.codex/skills/writing-clearly-and-concisely/SKILL.md +0 -64
  131. package/templates/.codex/uninstall-hooks.sh +0 -52
  132. package/templates/AGENTS.md.en +0 -39
  133. package/templates/AGENTS.md.ko +0 -39
  134. package/templates/manifest.codex.json +0 -43
package/dist/index.js CHANGED
@@ -384,7 +384,6 @@ function getDefaultConfig() {
384
384
  configVersion: CURRENT_CONFIG_VERSION,
385
385
  version: "0.0.0",
386
386
  language: "en",
387
- provider: "auto",
388
387
  installedAt: "",
389
388
  lastUpdated: "",
390
389
  installedComponents: [],
@@ -759,61 +758,36 @@ import { readFile as fsReadFile, writeFile as fsWriteFile, rename } from "node:f
759
758
  import { basename, join as join3 } from "node:path";
760
759
 
761
760
  // src/core/layout.ts
762
- var PROVIDER_LAYOUTS = {
763
- claude: {
764
- provider: "claude",
765
- rootDir: ".claude",
766
- entryFile: "CLAUDE.md",
767
- entryTemplatePrefix: "CLAUDE.md",
768
- manifestFile: "manifest.json",
769
- backupDirPrefix: ".claude-backup-",
770
- directoryStructure: [
771
- ".claude",
772
- ".claude/rules",
773
- ".claude/hooks",
774
- ".claude/contexts",
775
- ".claude/agents",
776
- ".claude/skills",
777
- "guides"
778
- ]
779
- },
780
- codex: {
781
- provider: "codex",
782
- rootDir: ".codex",
783
- entryFile: "AGENTS.md",
784
- entryTemplatePrefix: "AGENTS.md",
785
- manifestFile: "manifest.codex.json",
786
- backupDirPrefix: ".codex-backup-",
787
- directoryStructure: [
788
- ".codex",
789
- ".codex/rules",
790
- ".codex/hooks",
791
- ".codex/contexts",
792
- ".codex/agents",
793
- ".codex/skills",
794
- "guides"
795
- ]
796
- }
761
+ var CLAUDE_LAYOUT = {
762
+ rootDir: ".claude",
763
+ entryFile: "CLAUDE.md",
764
+ entryTemplatePrefix: "CLAUDE.md",
765
+ manifestFile: "manifest.json",
766
+ backupDirPrefix: ".claude-backup-",
767
+ directoryStructure: [
768
+ ".claude",
769
+ ".claude/rules",
770
+ ".claude/hooks",
771
+ ".claude/contexts",
772
+ ".claude/agents",
773
+ ".claude/skills",
774
+ "guides"
775
+ ]
797
776
  };
798
- function getProviderLayout(provider) {
799
- return PROVIDER_LAYOUTS[provider];
777
+ function getProviderLayout() {
778
+ return CLAUDE_LAYOUT;
800
779
  }
801
- function getEntryTemplateName(provider, language) {
802
- const layout = getProviderLayout(provider);
803
- return `${layout.entryTemplatePrefix}.${language}`;
780
+ function getEntryTemplateName(language) {
781
+ return `CLAUDE.md.${language}`;
804
782
  }
805
- function getComponentPath(provider, component) {
806
- const layout = getProviderLayout(provider);
783
+ function getComponentPath(component) {
807
784
  if (component === "entry-md") {
808
- return layout.entryFile;
785
+ return "CLAUDE.md";
809
786
  }
810
787
  if (component === "guides") {
811
788
  return "guides";
812
789
  }
813
- return `${layout.rootDir}/${component}`;
814
- }
815
- function getDefaultProvider() {
816
- return "claude";
790
+ return `.claude/${component}`;
817
791
  }
818
792
 
819
793
  // src/core/installer.ts
@@ -838,21 +812,21 @@ async function ensureTargetDirectory(targetDir) {
838
812
  await ensureDirectory(targetDir);
839
813
  }
840
814
  }
841
- async function handleBackup(targetDir, provider, shouldBackup, result) {
815
+ async function handleBackup(targetDir, shouldBackup, result) {
842
816
  if (!shouldBackup)
843
817
  return;
844
- const backupPaths = await backupExistingInstallation(targetDir, provider);
818
+ const backupPaths = await backupExistingInstallation(targetDir);
845
819
  result.backedUpPaths.push(...backupPaths);
846
820
  if (backupPaths.length > 0) {
847
821
  info("install.backup", { path: backupPaths[0] });
848
822
  }
849
823
  }
850
- async function checkAndWarnExisting(targetDir, provider, force, backup, result) {
824
+ async function checkAndWarnExisting(targetDir, force, backup, result) {
851
825
  if (force || backup)
852
826
  return;
853
- const existingPaths = await checkExistingPaths(targetDir, provider);
827
+ const existingPaths = await checkExistingPaths(targetDir);
854
828
  if (existingPaths.length > 0) {
855
- const layout = getProviderLayout(provider);
829
+ const layout = getProviderLayout();
856
830
  warn("install.exists", { rootDir: layout.rootDir });
857
831
  result.warnings.push(`Existing files found: ${existingPaths.join(", ")}. Use --force to overwrite or --backup to backup first.`);
858
832
  }
@@ -863,15 +837,15 @@ async function verifyTemplateDirectory() {
863
837
  throw new Error(`Template directory not found: ${templateDir}`);
864
838
  }
865
839
  }
866
- async function installAllComponents(targetDir, provider, options, result) {
840
+ async function installAllComponents(targetDir, options, result) {
867
841
  const components = options.components || getAllComponents();
868
842
  for (const component of components) {
869
- await installSingleComponent(targetDir, provider, component, options, result);
843
+ await installSingleComponent(targetDir, component, options, result);
870
844
  }
871
845
  }
872
- async function installSingleComponent(targetDir, provider, component, options, result) {
846
+ async function installSingleComponent(targetDir, component, options, result) {
873
847
  try {
874
- const installed = await installComponent(targetDir, provider, component, options);
848
+ const installed = await installComponent(targetDir, component, options);
875
849
  if (installed) {
876
850
  result.installedComponents.push(component);
877
851
  } else {
@@ -882,36 +856,34 @@ async function installSingleComponent(targetDir, provider, component, options, r
882
856
  result.warnings.push(`Failed to install ${component}: ${message}`);
883
857
  }
884
858
  }
885
- async function installEntryDocWithTracking(targetDir, provider, options, result) {
859
+ async function installEntryDocWithTracking(targetDir, options, result) {
886
860
  const language = options.language ?? DEFAULT_LANGUAGE;
887
861
  const overwrite = !!(options.force || options.backup);
888
- const installed = await installEntryDoc(targetDir, provider, language, overwrite);
862
+ const installed = await installEntryDoc(targetDir, language, overwrite);
889
863
  if (installed) {
890
864
  result.installedComponents.push("entry-md");
891
865
  } else {
892
866
  result.skippedComponents.push("entry-md");
893
867
  }
894
868
  }
895
- async function updateInstallConfig(targetDir, provider, options, installedComponents) {
869
+ async function updateInstallConfig(targetDir, options, installedComponents) {
896
870
  const config = await loadConfig(targetDir);
897
871
  config.language = options.language ?? DEFAULT_LANGUAGE;
898
- config.provider = provider;
899
872
  config.installedAt = new Date().toISOString();
900
873
  config.installedComponents = installedComponents;
901
874
  await saveConfig(targetDir, config);
902
875
  }
903
876
  async function install(options) {
904
877
  const result = createInstallResult(options.targetDir);
905
- const provider = options.provider ?? "claude";
906
878
  try {
907
879
  info("install.start", { targetDir: options.targetDir });
908
880
  await ensureTargetDirectory(options.targetDir);
909
- await handleBackup(options.targetDir, provider, !!options.backup, result);
910
- await checkAndWarnExisting(options.targetDir, provider, !!options.force, !!options.backup, result);
881
+ await handleBackup(options.targetDir, !!options.backup, result);
882
+ await checkAndWarnExisting(options.targetDir, !!options.force, !!options.backup, result);
911
883
  await verifyTemplateDirectory();
912
- await installAllComponents(options.targetDir, provider, options, result);
913
- await installEntryDocWithTracking(options.targetDir, provider, options, result);
914
- await updateInstallConfig(options.targetDir, provider, options, result.installedComponents);
884
+ await installAllComponents(options.targetDir, options, result);
885
+ await installEntryDocWithTracking(options.targetDir, options, result);
886
+ await updateInstallConfig(options.targetDir, options, result.installedComponents);
915
887
  result.success = true;
916
888
  success("install.success");
917
889
  } catch (err) {
@@ -930,16 +902,16 @@ async function copyTemplates(targetDir, templatePath, options) {
930
902
  preserveTimestamps: true
931
903
  });
932
904
  }
933
- async function createDirectoryStructure(targetDir, provider = "claude") {
934
- const layout = getProviderLayout(provider);
905
+ async function createDirectoryStructure(targetDir) {
906
+ const layout = getProviderLayout();
935
907
  for (const dir of layout.directoryStructure) {
936
908
  const fullPath = join3(targetDir, dir);
937
909
  await ensureDirectory(fullPath);
938
910
  }
939
911
  }
940
- async function getTemplateManifest(provider = "claude") {
912
+ async function getTemplateManifest() {
941
913
  const packageRoot = getPackageRoot();
942
- const layout = getProviderLayout(provider);
914
+ const layout = getProviderLayout();
943
915
  const manifestPath = join3(packageRoot, "templates", layout.manifestFile);
944
916
  if (await fileExists(manifestPath)) {
945
917
  return readJsonFile(manifestPath);
@@ -949,7 +921,7 @@ async function getTemplateManifest(provider = "claude") {
949
921
  lastUpdated: new Date().toISOString(),
950
922
  components: getAllComponents().map((name) => ({
951
923
  name,
952
- path: getComponentPath(provider, name),
924
+ path: getComponentPath(name),
953
925
  description: `${name} component`,
954
926
  files: 0
955
927
  })),
@@ -959,11 +931,11 @@ async function getTemplateManifest(provider = "claude") {
959
931
  function getAllComponents() {
960
932
  return ["rules", "agents", "skills", "guides", "hooks", "contexts"];
961
933
  }
962
- async function installComponent(targetDir, provider, component, options) {
934
+ async function installComponent(targetDir, component, options) {
963
935
  if (component === "entry-md") {
964
936
  return false;
965
937
  }
966
- const templatePath = getComponentPath(provider, component);
938
+ const templatePath = getComponentPath(component);
967
939
  if (!templatePath) {
968
940
  return false;
969
941
  }
@@ -991,9 +963,9 @@ function renderGitWorkflowSection(targetDir, language) {
991
963
  const result = detectGitWorkflow(targetDir) ?? getDefaultWorkflow();
992
964
  return language === "ko" ? renderGitWorkflowKO(result) : renderGitWorkflowEN(result);
993
965
  }
994
- async function installEntryDoc(targetDir, provider, language, overwrite = false) {
995
- const layout = getProviderLayout(provider);
996
- const templateFile = getEntryTemplateName(provider, language);
966
+ async function installEntryDoc(targetDir, language, overwrite = false) {
967
+ const layout = getProviderLayout();
968
+ const templateFile = getEntryTemplateName(language);
997
969
  const srcPath = resolveTemplatePath(templateFile);
998
970
  const destPath = join3(targetDir, layout.entryFile);
999
971
  if (!await fileExists(srcPath)) {
@@ -1020,8 +992,8 @@ async function backupExisting(sourcePath, backupDir) {
1020
992
  await rename(sourcePath, backupPath);
1021
993
  return backupPath;
1022
994
  }
1023
- async function checkExistingPaths(targetDir, provider) {
1024
- const layout = getProviderLayout(provider);
995
+ async function checkExistingPaths(targetDir) {
996
+ const layout = getProviderLayout();
1025
997
  const pathsToCheck = [layout.entryFile, layout.rootDir, "guides"];
1026
998
  const existingPaths = [];
1027
999
  for (const relativePath of pathsToCheck) {
@@ -1032,9 +1004,9 @@ async function checkExistingPaths(targetDir, provider) {
1032
1004
  }
1033
1005
  return existingPaths;
1034
1006
  }
1035
- async function backupExistingInstallation(targetDir, provider) {
1036
- const layout = getProviderLayout(provider);
1037
- const existingPaths = await checkExistingPaths(targetDir, provider);
1007
+ async function backupExistingInstallation(targetDir) {
1008
+ const layout = getProviderLayout();
1009
+ const existingPaths = await checkExistingPaths(targetDir);
1038
1010
  if (existingPaths.length === 0) {
1039
1011
  return [];
1040
1012
  }
@@ -1056,148 +1028,16 @@ async function backupExistingInstallation(targetDir, provider) {
1056
1028
  return backedUpPaths.length > 0 ? [backupDir] : [];
1057
1029
  }
1058
1030
  // src/core/provider.ts
1059
- import { join as join4 } from "node:path";
1060
- var ENV_SIGNALS = {
1061
- claude: [
1062
- "ANTHROPIC_API_KEY",
1063
- "CLAUDE_CODE",
1064
- "CLAUDE_CODE_EFFORT_LEVEL",
1065
- "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS",
1066
- "CLAUDE_CODE_ENABLE_TELEMETRY"
1067
- ],
1068
- codex: ["OPENAI_API_KEY", "OPENAI_ORG_ID", "OPENAI_PROJECT", "CODEX_HOME", "CODEX_PROJECT"]
1069
- };
1070
- var PROVIDER_ENV_OVERRIDES = ["OMCUSTOM_PROVIDER", "LLM_SERVICE"];
1071
- function normalizeProvider(value) {
1072
- if (!value)
1073
- return null;
1074
- const normalized = value.toLowerCase().trim();
1075
- if (normalized === "claude" || normalized === "codex" || normalized === "auto") {
1076
- return normalized;
1077
- }
1078
- return null;
1079
- }
1080
- function detectFromEnv(env) {
1081
- for (const key of PROVIDER_ENV_OVERRIDES) {
1082
- const override = normalizeProvider(env[key]);
1083
- if (override && override !== "auto") {
1084
- return {
1085
- provider: override,
1086
- source: "override",
1087
- confidence: "high",
1088
- reason: `env:${key}`
1089
- };
1090
- }
1091
- }
1092
- const claudeSignals = ENV_SIGNALS.claude.filter((key) => Boolean(env[key]));
1093
- const codexSignals = ENV_SIGNALS.codex.filter((key) => Boolean(env[key]));
1094
- const hasClaude = claudeSignals.length > 0;
1095
- const hasCodex = codexSignals.length > 0;
1096
- if (hasClaude && !hasCodex) {
1097
- return {
1098
- provider: "claude",
1099
- source: "env",
1100
- confidence: "medium",
1101
- reason: `env:${claudeSignals[0]}`
1102
- };
1103
- }
1104
- if (hasCodex && !hasClaude) {
1105
- return {
1106
- provider: "codex",
1107
- source: "env",
1108
- confidence: "medium",
1109
- reason: `env:${codexSignals[0]}`
1110
- };
1111
- }
1112
- return null;
1113
- }
1114
- async function detectFromProject(targetDir) {
1115
- const claudeMarkers = [join4(targetDir, "CLAUDE.md"), join4(targetDir, ".claude")];
1116
- const codexMarkers = [join4(targetDir, "AGENTS.md"), join4(targetDir, ".codex")];
1117
- const claudeFound = await Promise.all(claudeMarkers.map((path) => fileExists(path)));
1118
- const codexFound = await Promise.all(codexMarkers.map((path) => fileExists(path)));
1119
- const hasClaude = claudeFound.some(Boolean);
1120
- const hasCodex = codexFound.some(Boolean);
1121
- if (hasClaude && !hasCodex) {
1122
- return {
1123
- provider: "claude",
1124
- source: "project",
1125
- confidence: "medium",
1126
- reason: "project:claude"
1127
- };
1128
- }
1129
- if (hasCodex && !hasClaude) {
1130
- return {
1131
- provider: "codex",
1132
- source: "project",
1133
- confidence: "medium",
1134
- reason: "project:codex"
1135
- };
1136
- }
1137
- return null;
1138
- }
1139
- async function detectFromConfig(targetDir) {
1140
- const configPath = join4(targetDir, ".omcustomrc.json");
1141
- if (!await fileExists(configPath)) {
1142
- return null;
1143
- }
1144
- try {
1145
- const config = await readJsonFile(configPath);
1146
- const provider = normalizeProvider(config.provider);
1147
- if (provider && provider !== "auto") {
1148
- return {
1149
- provider,
1150
- source: "config",
1151
- confidence: "high",
1152
- reason: "config:provider"
1153
- };
1154
- }
1155
- } catch {}
1156
- return null;
1157
- }
1158
- async function detectProvider(options = {}) {
1159
- const env = options.env ?? process.env;
1160
- const override = options.override;
1161
- const normalizedOverride = normalizeProvider(override);
1162
- if (normalizedOverride && normalizedOverride !== "auto") {
1163
- return {
1164
- provider: normalizedOverride,
1165
- source: "override",
1166
- confidence: "high",
1167
- reason: "override:option"
1168
- };
1169
- }
1170
- if (options.targetDir) {
1171
- const fromConfig = await detectFromConfig(options.targetDir);
1172
- if (fromConfig) {
1173
- return fromConfig;
1174
- }
1175
- }
1176
- if (options.targetDir && options.preferProject) {
1177
- const fromProject = await detectFromProject(options.targetDir);
1178
- if (fromProject) {
1179
- return fromProject;
1180
- }
1181
- }
1182
- const fromEnv = detectFromEnv(env);
1183
- if (fromEnv) {
1184
- return fromEnv;
1185
- }
1186
- if (options.targetDir && !options.preferProject) {
1187
- const fromProject = await detectFromProject(options.targetDir);
1188
- if (fromProject) {
1189
- return fromProject;
1190
- }
1191
- }
1031
+ async function detectProvider(_options = {}) {
1192
1032
  return {
1193
- provider: getDefaultProvider(),
1033
+ provider: "claude",
1194
1034
  source: "default",
1195
- confidence: "low",
1196
- reason: "default"
1035
+ confidence: "high",
1036
+ reason: "claude-only"
1197
1037
  };
1198
1038
  }
1199
1039
  // src/core/updater.ts
1200
- import { join as join5 } from "node:path";
1040
+ import { join as join4 } from "node:path";
1201
1041
 
1202
1042
  // src/core/entry-merger.ts
1203
1043
  var MANAGED_START = "<!-- omcustom:start -->";
@@ -1329,14 +1169,14 @@ function createUpdateResult() {
1329
1169
  warnings: []
1330
1170
  };
1331
1171
  }
1332
- async function handleBackupIfRequested(targetDir, provider, backup, result) {
1172
+ async function handleBackupIfRequested(targetDir, backup, result) {
1333
1173
  if (!backup)
1334
1174
  return;
1335
- const backupPath = await backupInstallation(targetDir, provider);
1175
+ const backupPath = await backupInstallation(targetDir);
1336
1176
  result.backedUpPaths.push(backupPath);
1337
1177
  info("update.backup_created", { path: backupPath });
1338
1178
  }
1339
- async function processComponentUpdate(targetDir, provider, component, updateCheck, customizations, options, result, config) {
1179
+ async function processComponentUpdate(targetDir, component, updateCheck, customizations, options, result, config) {
1340
1180
  const componentUpdate = updateCheck.updatableComponents.find((c) => c.name === component);
1341
1181
  if (!componentUpdate && !options.force) {
1342
1182
  result.skippedComponents.push(component);
@@ -1348,7 +1188,7 @@ async function processComponentUpdate(targetDir, provider, component, updateChec
1348
1188
  return;
1349
1189
  }
1350
1190
  try {
1351
- const preserved = await updateComponent(targetDir, provider, component, customizations, options, config);
1191
+ const preserved = await updateComponent(targetDir, component, customizations, options, config);
1352
1192
  result.updatedComponents.push(component);
1353
1193
  result.preservedFiles.push(...preserved);
1354
1194
  } catch (err) {
@@ -1357,13 +1197,13 @@ async function processComponentUpdate(targetDir, provider, component, updateChec
1357
1197
  result.skippedComponents.push(component);
1358
1198
  }
1359
1199
  }
1360
- async function updateAllComponents(targetDir, provider, components, updateCheck, customizations, options, result, config) {
1200
+ async function updateAllComponents(targetDir, components, updateCheck, customizations, options, result, config) {
1361
1201
  for (const component of components) {
1362
- await processComponentUpdate(targetDir, provider, component, updateCheck, customizations, options, result, config);
1202
+ await processComponentUpdate(targetDir, component, updateCheck, customizations, options, result, config);
1363
1203
  }
1364
1204
  }
1365
- function getEntryTemplateName2(provider, language) {
1366
- const layout = getProviderLayout(provider);
1205
+ function getEntryTemplateName2(language) {
1206
+ const layout = getProviderLayout();
1367
1207
  const baseName = layout.entryFile.replace(".md", "");
1368
1208
  return language === "ko" ? `${baseName}.md.ko` : `${baseName}.md.en`;
1369
1209
  }
@@ -1447,10 +1287,10 @@ function resolveCustomizations(customizations, configPreserveFiles, targetDir) {
1447
1287
  }
1448
1288
  return null;
1449
1289
  }
1450
- async function updateEntryDoc(targetDir, provider, config, options) {
1451
- const layout = getProviderLayout(provider);
1452
- const entryPath = join5(targetDir, layout.entryFile);
1453
- const templateName = getEntryTemplateName2(provider, config.language);
1290
+ async function updateEntryDoc(targetDir, config, options) {
1291
+ const layout = getProviderLayout();
1292
+ const entryPath = join4(targetDir, layout.entryFile);
1293
+ const templateName = getEntryTemplateName2(config.language);
1454
1294
  const templatePath = resolveTemplatePath(templateName);
1455
1295
  if (!await fileExists(templatePath)) {
1456
1296
  warn("update.entry_template_not_found", { template: templateName });
@@ -1487,9 +1327,8 @@ async function update(options) {
1487
1327
  try {
1488
1328
  info("update.start", { targetDir: options.targetDir });
1489
1329
  const config = await loadConfig(options.targetDir);
1490
- const provider = options.provider ?? (config.provider === "codex" ? "codex" : "claude");
1491
1330
  result.previousVersion = config.version;
1492
- const updateCheck = await checkForUpdates(options.targetDir, provider);
1331
+ const updateCheck = await checkForUpdates(options.targetDir);
1493
1332
  result.newVersion = updateCheck.latestVersion;
1494
1333
  if (!updateCheck.hasUpdates && !options.force) {
1495
1334
  info("update.no_updates");
@@ -1497,14 +1336,14 @@ async function update(options) {
1497
1336
  result.skippedComponents = options.components || getAllUpdateComponents();
1498
1337
  return result;
1499
1338
  }
1500
- await handleBackupIfRequested(options.targetDir, provider, !!options.backup, result);
1339
+ await handleBackupIfRequested(options.targetDir, !!options.backup, result);
1501
1340
  const manifestCustomizations = await resolveManifestCustomizations(options, options.targetDir);
1502
1341
  const configPreserveFiles = resolveConfigPreserveFiles(options, config);
1503
1342
  const customizations = resolveCustomizations(manifestCustomizations, configPreserveFiles, options.targetDir);
1504
1343
  const components = options.components || getAllUpdateComponents();
1505
- await updateAllComponents(options.targetDir, provider, components, updateCheck, customizations, options, result, config);
1344
+ await updateAllComponents(options.targetDir, components, updateCheck, customizations, options, result, config);
1506
1345
  if (!options.components || options.components.length === 0) {
1507
- await updateEntryDoc(options.targetDir, provider, config, options);
1346
+ await updateEntryDoc(options.targetDir, config, options);
1508
1347
  }
1509
1348
  config.version = result.newVersion;
1510
1349
  config.lastUpdated = new Date().toISOString();
@@ -1525,13 +1364,13 @@ async function update(options) {
1525
1364
  }
1526
1365
  return result;
1527
1366
  }
1528
- async function checkForUpdates(targetDir, provider = "claude") {
1367
+ async function checkForUpdates(targetDir) {
1529
1368
  const config = await loadConfig(targetDir);
1530
1369
  const currentVersion = config.version;
1531
- const latestVersion = await getLatestVersion(provider);
1370
+ const latestVersion = await getLatestVersion();
1532
1371
  const updatableComponents = [];
1533
1372
  for (const component of getAllUpdateComponents()) {
1534
- const hasUpdate = await componentHasUpdate(targetDir, provider, component, config);
1373
+ const hasUpdate = await componentHasUpdate(targetDir, component, config);
1535
1374
  if (hasUpdate) {
1536
1375
  updatableComponents.push({
1537
1376
  name: component,
@@ -1551,8 +1390,8 @@ async function checkForUpdates(targetDir, provider = "claude") {
1551
1390
  async function applyUpdates(targetDir, updates) {
1552
1391
  const fs = await import("node:fs/promises");
1553
1392
  for (const update2 of updates) {
1554
- const fullPath = join5(targetDir, update2.path);
1555
- await ensureDirectory(join5(fullPath, ".."));
1393
+ const fullPath = join4(targetDir, update2.path);
1394
+ await ensureDirectory(join4(fullPath, ".."));
1556
1395
  await fs.writeFile(fullPath, update2.content, "utf-8");
1557
1396
  debug("update.file_applied", { path: update2.path });
1558
1397
  }
@@ -1561,7 +1400,7 @@ async function preserveCustomizations(targetDir, customizations) {
1561
1400
  const preserved = new Map;
1562
1401
  const fs = await import("node:fs/promises");
1563
1402
  for (const filePath of customizations) {
1564
- const fullPath = join5(targetDir, filePath);
1403
+ const fullPath = join4(targetDir, filePath);
1565
1404
  if (await fileExists(fullPath)) {
1566
1405
  const content = await fs.readFile(fullPath, "utf-8");
1567
1406
  preserved.set(filePath, content);
@@ -1572,8 +1411,8 @@ async function preserveCustomizations(targetDir, customizations) {
1572
1411
  function getAllUpdateComponents() {
1573
1412
  return ["rules", "agents", "skills", "guides", "hooks", "contexts"];
1574
1413
  }
1575
- async function getLatestVersion(provider) {
1576
- const layout = getProviderLayout(provider);
1414
+ async function getLatestVersion() {
1415
+ const layout = getProviderLayout();
1577
1416
  const manifestPath = resolveTemplatePath(layout.manifestFile);
1578
1417
  if (await fileExists(manifestPath)) {
1579
1418
  const manifest = await readJsonFile(manifestPath);
@@ -1581,19 +1420,19 @@ async function getLatestVersion(provider) {
1581
1420
  }
1582
1421
  return "0.0.0";
1583
1422
  }
1584
- async function componentHasUpdate(_targetDir, provider, component, config) {
1423
+ async function componentHasUpdate(_targetDir, component, config) {
1585
1424
  const installedVersion = config.componentVersions?.[component];
1586
1425
  if (!installedVersion) {
1587
1426
  return true;
1588
1427
  }
1589
- const latestVersion = await getLatestVersion(provider);
1428
+ const latestVersion = await getLatestVersion();
1590
1429
  return installedVersion !== latestVersion;
1591
1430
  }
1592
- async function updateComponent(targetDir, provider, component, customizations, options, config) {
1431
+ async function updateComponent(targetDir, component, customizations, options, config) {
1593
1432
  const preservedFiles = [];
1594
- const componentPath = getComponentPath2(provider, component);
1433
+ const componentPath = getComponentPath2(component);
1595
1434
  const srcPath = resolveTemplatePath(componentPath);
1596
- const destPath = join5(targetDir, componentPath);
1435
+ const destPath = join4(targetDir, componentPath);
1597
1436
  const customComponents = config.customComponents || [];
1598
1437
  const skipPaths = [];
1599
1438
  if (customizations && !options.forceOverwriteAll) {
@@ -1607,7 +1446,7 @@ async function updateComponent(targetDir, provider, component, customizations, o
1607
1446
  }
1608
1447
  }
1609
1448
  const path = await import("node:path");
1610
- const normalizedSkipPaths = skipPaths.map((p) => path.relative(destPath, join5(targetDir, p)));
1449
+ const normalizedSkipPaths = skipPaths.map((p) => path.relative(destPath, join4(targetDir, p)));
1611
1450
  await copyDirectory(srcPath, destPath, {
1612
1451
  overwrite: true,
1613
1452
  skipPaths: normalizedSkipPaths.length > 0 ? normalizedSkipPaths : undefined
@@ -1618,35 +1457,35 @@ async function updateComponent(targetDir, provider, component, customizations, o
1618
1457
  });
1619
1458
  return preservedFiles;
1620
1459
  }
1621
- function getComponentPath2(provider, component) {
1622
- const layout = getProviderLayout(provider);
1460
+ function getComponentPath2(component) {
1461
+ const layout = getProviderLayout();
1623
1462
  if (component === "guides") {
1624
1463
  return "guides";
1625
1464
  }
1626
1465
  return `${layout.rootDir}/${component}`;
1627
1466
  }
1628
- async function backupInstallation(targetDir, provider) {
1467
+ async function backupInstallation(targetDir) {
1629
1468
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
1630
- const backupDir = join5(targetDir, `.omcustom-backup-${timestamp}`);
1469
+ const backupDir = join4(targetDir, `.omcustom-backup-${timestamp}`);
1631
1470
  const fs = await import("node:fs/promises");
1632
1471
  await ensureDirectory(backupDir);
1633
- const layout = getProviderLayout(provider);
1472
+ const layout = getProviderLayout();
1634
1473
  const dirsToBackup = [layout.rootDir, "guides"];
1635
1474
  for (const dir of dirsToBackup) {
1636
- const srcPath = join5(targetDir, dir);
1475
+ const srcPath = join4(targetDir, dir);
1637
1476
  if (await fileExists(srcPath)) {
1638
- const destPath = join5(backupDir, dir);
1477
+ const destPath = join4(backupDir, dir);
1639
1478
  await copyDirectory(srcPath, destPath, { overwrite: true });
1640
1479
  }
1641
1480
  }
1642
- const entryPath = join5(targetDir, layout.entryFile);
1481
+ const entryPath = join4(targetDir, layout.entryFile);
1643
1482
  if (await fileExists(entryPath)) {
1644
- await fs.copyFile(entryPath, join5(backupDir, layout.entryFile));
1483
+ await fs.copyFile(entryPath, join4(backupDir, layout.entryFile));
1645
1484
  }
1646
1485
  return backupDir;
1647
1486
  }
1648
1487
  async function loadCustomizationManifest(targetDir) {
1649
- const manifestPath = join5(targetDir, CUSTOMIZATION_MANIFEST_FILE);
1488
+ const manifestPath = join4(targetDir, CUSTOMIZATION_MANIFEST_FILE);
1650
1489
  if (await fileExists(manifestPath)) {
1651
1490
  return readJsonFile(manifestPath);
1652
1491
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oh-my-customcode",
3
- "version": "0.12.1",
4
- "description": "Batteries-included agent harness for Claude Code and OpenAI Codex",
3
+ "version": "0.12.3",
4
+ "description": "Batteries-included agent harness for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "omcustom": "./dist/cli/index.js"
@@ -59,8 +59,6 @@
59
59
  "keywords": [
60
60
  "claude",
61
61
  "claude-code",
62
- "codex",
63
- "codex-cli",
64
62
  "openai",
65
63
  "ai",
66
64
  "agent",