oh-my-codex 0.16.3 → 0.16.4

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 (278) hide show
  1. package/Cargo.lock +5 -5
  2. package/Cargo.toml +1 -1
  3. package/README.md +3 -3
  4. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +9 -0
  5. package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -1
  6. package/dist/cli/__tests__/cleanup.test.js +27 -0
  7. package/dist/cli/__tests__/cleanup.test.js.map +1 -1
  8. package/dist/cli/__tests__/codex-plugin-layout.test.js +7 -5
  9. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  10. package/dist/cli/__tests__/doctor-warning-copy.test.js +101 -6
  11. package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
  12. package/dist/cli/__tests__/index.test.js +131 -2
  13. package/dist/cli/__tests__/index.test.js.map +1 -1
  14. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +2 -0
  15. package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
  16. package/dist/cli/__tests__/ralph.test.js +47 -0
  17. package/dist/cli/__tests__/ralph.test.js.map +1 -1
  18. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +2 -2
  19. package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
  20. package/dist/cli/__tests__/setup-install-mode.test.js +272 -26
  21. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  22. package/dist/cli/__tests__/setup-refresh.test.js +85 -3
  23. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  24. package/dist/cli/__tests__/setup-scope.test.js +1 -1
  25. package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
  26. package/dist/cli/__tests__/setup-skills-overwrite.test.js +2 -1
  27. package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
  28. package/dist/cli/__tests__/team.test.js +108 -0
  29. package/dist/cli/__tests__/team.test.js.map +1 -1
  30. package/dist/cli/__tests__/ultragoal.test.js +69 -0
  31. package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
  32. package/dist/cli/__tests__/uninstall.test.js +54 -8
  33. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  34. package/dist/cli/cleanup.d.ts.map +1 -1
  35. package/dist/cli/cleanup.js +8 -4
  36. package/dist/cli/cleanup.js.map +1 -1
  37. package/dist/cli/codex-feature-probe.d.ts +9 -0
  38. package/dist/cli/codex-feature-probe.d.ts.map +1 -0
  39. package/dist/cli/codex-feature-probe.js +28 -0
  40. package/dist/cli/codex-feature-probe.js.map +1 -0
  41. package/dist/cli/doctor.d.ts +1 -0
  42. package/dist/cli/doctor.d.ts.map +1 -1
  43. package/dist/cli/doctor.js +152 -17
  44. package/dist/cli/doctor.js.map +1 -1
  45. package/dist/cli/index.d.ts +9 -2
  46. package/dist/cli/index.d.ts.map +1 -1
  47. package/dist/cli/index.js +135 -17
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cli/mcp-parity.js +8 -8
  50. package/dist/cli/mcp-parity.js.map +1 -1
  51. package/dist/cli/plugin-marketplace.d.ts +3 -0
  52. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  53. package/dist/cli/plugin-marketplace.js +88 -0
  54. package/dist/cli/plugin-marketplace.js.map +1 -1
  55. package/dist/cli/ralph.d.ts.map +1 -1
  56. package/dist/cli/ralph.js +21 -0
  57. package/dist/cli/ralph.js.map +1 -1
  58. package/dist/cli/setup-preferences.d.ts +4 -0
  59. package/dist/cli/setup-preferences.d.ts.map +1 -1
  60. package/dist/cli/setup-preferences.js +7 -0
  61. package/dist/cli/setup-preferences.js.map +1 -1
  62. package/dist/cli/setup.d.ts +5 -3
  63. package/dist/cli/setup.d.ts.map +1 -1
  64. package/dist/cli/setup.js +114 -44
  65. package/dist/cli/setup.js.map +1 -1
  66. package/dist/cli/ultragoal.d.ts +1 -1
  67. package/dist/cli/ultragoal.d.ts.map +1 -1
  68. package/dist/cli/ultragoal.js +64 -5
  69. package/dist/cli/ultragoal.js.map +1 -1
  70. package/dist/cli/uninstall.d.ts +2 -0
  71. package/dist/cli/uninstall.d.ts.map +1 -1
  72. package/dist/cli/uninstall.js +12 -3
  73. package/dist/cli/uninstall.js.map +1 -1
  74. package/dist/config/__tests__/codex-feature-flags.test.d.ts +2 -0
  75. package/dist/config/__tests__/codex-feature-flags.test.d.ts.map +1 -0
  76. package/dist/config/__tests__/codex-feature-flags.test.js +35 -0
  77. package/dist/config/__tests__/codex-feature-flags.test.js.map +1 -0
  78. package/dist/config/__tests__/codex-hooks.test.js +7 -0
  79. package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
  80. package/dist/config/__tests__/generator-idempotent.test.js +70 -9
  81. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  82. package/dist/config/__tests__/generator-notify.test.js +116 -11
  83. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  84. package/dist/config/__tests__/wiki-config-contract.test.js +6 -3
  85. package/dist/config/__tests__/wiki-config-contract.test.js.map +1 -1
  86. package/dist/config/codex-feature-flags.d.ts +21 -0
  87. package/dist/config/codex-feature-flags.d.ts.map +1 -0
  88. package/dist/config/codex-feature-flags.js +56 -0
  89. package/dist/config/codex-feature-flags.js.map +1 -0
  90. package/dist/config/codex-hooks.d.ts +2 -0
  91. package/dist/config/codex-hooks.d.ts.map +1 -1
  92. package/dist/config/codex-hooks.js +25 -3
  93. package/dist/config/codex-hooks.js.map +1 -1
  94. package/dist/config/generator.d.ts +11 -2
  95. package/dist/config/generator.d.ts.map +1 -1
  96. package/dist/config/generator.js +221 -123
  97. package/dist/config/generator.js.map +1 -1
  98. package/dist/config/omx-first-party-mcp.d.ts +3 -1
  99. package/dist/config/omx-first-party-mcp.d.ts.map +1 -1
  100. package/dist/config/omx-first-party-mcp.js +2 -2
  101. package/dist/config/omx-first-party-mcp.js.map +1 -1
  102. package/dist/hooks/__tests__/keyword-detector.test.js +92 -2
  103. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  104. package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js +125 -1
  105. package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js.map +1 -1
  106. package/dist/hooks/__tests__/skill-catalog-hygiene.test.d.ts +2 -0
  107. package/dist/hooks/__tests__/skill-catalog-hygiene.test.d.ts.map +1 -0
  108. package/dist/hooks/__tests__/skill-catalog-hygiene.test.js +84 -0
  109. package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -0
  110. package/dist/hooks/agents-overlay.js +2 -2
  111. package/dist/hooks/agents-overlay.js.map +1 -1
  112. package/dist/hooks/keyword-detector.d.ts +1 -0
  113. package/dist/hooks/keyword-detector.d.ts.map +1 -1
  114. package/dist/hooks/keyword-detector.js +7 -5
  115. package/dist/hooks/keyword-detector.js.map +1 -1
  116. package/dist/hud/__tests__/state.test.js +164 -0
  117. package/dist/hud/__tests__/state.test.js.map +1 -1
  118. package/dist/hud/state.d.ts.map +1 -1
  119. package/dist/hud/state.js +4 -5
  120. package/dist/hud/state.js.map +1 -1
  121. package/dist/mcp/__tests__/state-paths.test.js +61 -0
  122. package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
  123. package/dist/mcp/__tests__/state-server.test.js +166 -0
  124. package/dist/mcp/__tests__/state-server.test.js.map +1 -1
  125. package/dist/mcp/state-paths.d.ts.map +1 -1
  126. package/dist/mcp/state-paths.js +23 -2
  127. package/dist/mcp/state-paths.js.map +1 -1
  128. package/dist/modes/__tests__/base-session-scope.test.js +22 -0
  129. package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
  130. package/dist/modes/__tests__/base-tmux-pane.test.js +57 -26
  131. package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
  132. package/dist/modes/base.d.ts.map +1 -1
  133. package/dist/modes/base.js +5 -0
  134. package/dist/modes/base.js.map +1 -1
  135. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.d.ts +2 -0
  136. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.d.ts.map +1 -0
  137. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js +316 -0
  138. package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -0
  139. package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.d.ts +2 -0
  140. package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.d.ts.map +1 -0
  141. package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.js +481 -0
  142. package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.js.map +1 -0
  143. package/dist/planning/__tests__/artifacts.test.js +533 -4
  144. package/dist/planning/__tests__/artifacts.test.js.map +1 -1
  145. package/dist/planning/__tests__/context-pack-status.test.js +524 -0
  146. package/dist/planning/__tests__/context-pack-status.test.js.map +1 -1
  147. package/dist/planning/__tests__/markdown-structure.test.d.ts +2 -0
  148. package/dist/planning/__tests__/markdown-structure.test.d.ts.map +1 -0
  149. package/dist/planning/__tests__/markdown-structure.test.js +459 -0
  150. package/dist/planning/__tests__/markdown-structure.test.js.map +1 -0
  151. package/dist/planning/__tests__/ready-context-pack-role-refs.test.js +523 -1
  152. package/dist/planning/__tests__/ready-context-pack-role-refs.test.js.map +1 -1
  153. package/dist/planning/artifacts.d.ts +1 -1
  154. package/dist/planning/artifacts.d.ts.map +1 -1
  155. package/dist/planning/artifacts.js +227 -28
  156. package/dist/planning/artifacts.js.map +1 -1
  157. package/dist/planning/context-pack-status.d.ts +25 -0
  158. package/dist/planning/context-pack-status.d.ts.map +1 -1
  159. package/dist/planning/context-pack-status.js +272 -31
  160. package/dist/planning/context-pack-status.js.map +1 -1
  161. package/dist/planning/markdown-structure.d.ts +20 -0
  162. package/dist/planning/markdown-structure.d.ts.map +1 -0
  163. package/dist/planning/markdown-structure.js +137 -0
  164. package/dist/planning/markdown-structure.js.map +1 -0
  165. package/dist/ralph/__tests__/completion-audit.test.d.ts +2 -0
  166. package/dist/ralph/__tests__/completion-audit.test.d.ts.map +1 -0
  167. package/dist/ralph/__tests__/completion-audit.test.js +121 -0
  168. package/dist/ralph/__tests__/completion-audit.test.js.map +1 -0
  169. package/dist/ralph/completion-audit.d.ts +8 -0
  170. package/dist/ralph/completion-audit.d.ts.map +1 -0
  171. package/dist/ralph/completion-audit.js +99 -0
  172. package/dist/ralph/completion-audit.js.map +1 -0
  173. package/dist/scripts/__tests__/codex-native-hook.test.js +220 -13
  174. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  175. package/dist/scripts/__tests__/notify-dispatcher.test.d.ts +2 -0
  176. package/dist/scripts/__tests__/notify-dispatcher.test.d.ts.map +1 -0
  177. package/dist/scripts/__tests__/notify-dispatcher.test.js +126 -0
  178. package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -0
  179. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  180. package/dist/scripts/codex-native-hook.js +133 -54
  181. package/dist/scripts/codex-native-hook.js.map +1 -1
  182. package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
  183. package/dist/scripts/codex-native-pre-post.js +4 -2
  184. package/dist/scripts/codex-native-pre-post.js.map +1 -1
  185. package/dist/scripts/notify-dispatcher.js +30 -1
  186. package/dist/scripts/notify-dispatcher.js.map +1 -1
  187. package/dist/scripts/notify-hook.js +3 -1
  188. package/dist/scripts/notify-hook.js.map +1 -1
  189. package/dist/state/__tests__/workflow-transition.test.js +102 -27
  190. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  191. package/dist/state/operations.d.ts.map +1 -1
  192. package/dist/state/operations.js +9 -3
  193. package/dist/state/operations.js.map +1 -1
  194. package/dist/state/skill-active.d.ts +7 -0
  195. package/dist/state/skill-active.d.ts.map +1 -1
  196. package/dist/state/skill-active.js +25 -8
  197. package/dist/state/skill-active.js.map +1 -1
  198. package/dist/state/workflow-transition-reconcile.d.ts +1 -0
  199. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  200. package/dist/state/workflow-transition-reconcile.js +22 -15
  201. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  202. package/dist/state/workflow-transition.js +3 -3
  203. package/dist/state/workflow-transition.js.map +1 -1
  204. package/dist/team/__tests__/approved-execution.test.js +39 -0
  205. package/dist/team/__tests__/approved-execution.test.js.map +1 -1
  206. package/dist/team/__tests__/runtime.test.js +5 -0
  207. package/dist/team/__tests__/runtime.test.js.map +1 -1
  208. package/dist/team/__tests__/scaling.test.js +497 -2
  209. package/dist/team/__tests__/scaling.test.js.map +1 -1
  210. package/dist/team/__tests__/state-root.test.js +1 -1
  211. package/dist/team/__tests__/state-root.test.js.map +1 -1
  212. package/dist/team/__tests__/worker-bootstrap.test.js +8 -0
  213. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  214. package/dist/team/approved-execution.d.ts.map +1 -1
  215. package/dist/team/approved-execution.js +3 -0
  216. package/dist/team/approved-execution.js.map +1 -1
  217. package/dist/team/scaling.d.ts.map +1 -1
  218. package/dist/team/scaling.js +43 -0
  219. package/dist/team/scaling.js.map +1 -1
  220. package/dist/team/state-root.d.ts.map +1 -1
  221. package/dist/team/state-root.js +4 -0
  222. package/dist/team/state-root.js.map +1 -1
  223. package/dist/team/state.d.ts.map +1 -1
  224. package/dist/team/state.js +2 -6
  225. package/dist/team/state.js.map +1 -1
  226. package/dist/ultragoal/__tests__/artifacts.test.js +124 -1
  227. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  228. package/dist/ultragoal/__tests__/docs-contract.test.js +21 -0
  229. package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
  230. package/dist/ultragoal/artifacts.d.ts +44 -2
  231. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  232. package/dist/ultragoal/artifacts.js +197 -13
  233. package/dist/ultragoal/artifacts.js.map +1 -1
  234. package/dist/wiki/lifecycle.js +1 -1
  235. package/dist/wiki/lifecycle.js.map +1 -1
  236. package/package.json +1 -1
  237. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  238. package/plugins/oh-my-codex/.mcp.json +5 -5
  239. package/plugins/oh-my-codex/skills/analyze/SKILL.md +0 -2
  240. package/plugins/oh-my-codex/skills/autopilot/SKILL.md +2 -2
  241. package/plugins/oh-my-codex/skills/code-review/SKILL.md +1 -3
  242. package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +5 -7
  243. package/plugins/oh-my-codex/skills/doctor/SKILL.md +2 -2
  244. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +3 -3
  245. package/plugins/oh-my-codex/skills/pipeline/SKILL.md +3 -3
  246. package/plugins/oh-my-codex/skills/plan/SKILL.md +3 -6
  247. package/plugins/oh-my-codex/skills/ralph/SKILL.md +9 -10
  248. package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +36 -3
  249. package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +21 -24
  250. package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +8 -8
  251. package/plugins/oh-my-codex/skills/wiki/SKILL.md +13 -13
  252. package/skills/analyze/SKILL.md +0 -2
  253. package/skills/ask-claude/SKILL.md +5 -3
  254. package/skills/ask-gemini/SKILL.md +5 -3
  255. package/skills/autopilot/SKILL.md +2 -2
  256. package/skills/code-review/SKILL.md +1 -3
  257. package/skills/deep-interview/SKILL.md +5 -7
  258. package/skills/doctor/SKILL.md +2 -2
  259. package/skills/ecomode/SKILL.md +105 -1
  260. package/skills/frontend-ui-ux/SKILL.md +4 -26
  261. package/skills/git-master/SKILL.md +2 -4
  262. package/skills/omx-setup/SKILL.md +3 -3
  263. package/skills/pipeline/SKILL.md +3 -3
  264. package/skills/plan/SKILL.md +3 -6
  265. package/skills/ralph/SKILL.md +9 -10
  266. package/skills/swarm/SKILL.md +5 -3
  267. package/skills/tdd/SKILL.md +95 -1
  268. package/skills/ultragoal/SKILL.md +36 -3
  269. package/skills/ultraqa/SKILL.md +21 -24
  270. package/skills/ultrawork/SKILL.md +8 -8
  271. package/skills/web-clone/SKILL.md +348 -1
  272. package/skills/wiki/SKILL.md +13 -13
  273. package/src/scripts/__tests__/codex-native-hook.test.ts +231 -13
  274. package/src/scripts/__tests__/notify-dispatcher.test.ts +153 -0
  275. package/src/scripts/codex-native-hook.ts +160 -43
  276. package/src/scripts/codex-native-pre-post.ts +4 -1
  277. package/src/scripts/notify-dispatcher.ts +40 -1
  278. package/src/scripts/notify-hook.ts +3 -1
package/dist/cli/setup.js CHANGED
@@ -9,7 +9,7 @@ import { spawnSync } from "child_process";
9
9
  import { createInterface } from "readline/promises";
10
10
  import { homedir } from "os";
11
11
  import { codexHome, codexConfigPath, codexPromptsDir, codexAgentsDir, userSkillsDir, omxStateDir, detectLegacySkillRootOverlap, omxPlansDir, omxLogsDir, } from "../utils/paths.js";
12
- import { buildMergedConfig, getRootModelName, getRootTomlArray, hasLegacyOmxTeamRunTable, isOmxManagedNotifyCommand, stripExistingOmxBlocks, stripExistingSharedMcpRegistryBlock, stripOmxEnvSettings, stripOmxFeatureFlags, stripOmxSeededBehavioralDefaults, upsertPluginModeRuntimeFeatureFlags, upsertManagedCodexHookTrustState, stripManagedCodexHookTrustState, OMX_PLUGIN_DEVELOPER_INSTRUCTIONS, } from "../config/generator.js";
12
+ import { buildMergedConfig, getRootModelName, getRootTomlArray, hasLegacyOmxTeamRunTable, isOmxManagedNotifyCommand, sanitizePreviousNotifyCommand, stripExistingOmxBlocks, stripExistingSharedMcpRegistryBlock, mergeSharedMcpRegistryBlock, stripOmxEnvSettings, stripOmxFeatureFlags, stripOmxSeededBehavioralDefaults, upsertPluginModeRuntimeFeatureFlags, upsertManagedCodexHookTrustState, stripManagedCodexHookTrustState, OMX_PLUGIN_DEVELOPER_INSTRUCTIONS, } from "../config/generator.js";
13
13
  import { mergeManagedCodexHooksConfig } from "../config/codex-hooks.js";
14
14
  import { getLegacyUnifiedMcpRegistryCandidate, getUnifiedMcpRegistryCandidates, loadUnifiedMcpRegistry, planClaudeCodeMcpSettingsSync, } from "../config/mcp-registry.js";
15
15
  import { generateAgentToml } from "../agents/native-config.js";
@@ -22,8 +22,9 @@ import { tryReadCatalogManifest } from "../catalog/reader.js";
22
22
  import { DEFAULT_FRONTIER_MODEL } from "../config/models.js";
23
23
  import { addGeneratedAgentsMarker, hasOmxManagedAgentsSections, isOmxGeneratedAgentsMd, upsertManagedAgentsBlock, } from "../utils/agents-md.js";
24
24
  import { DEFAULT_HUD_CONFIG } from "../hud/types.js";
25
- import { SETUP_INSTALL_MODES, SETUP_SCOPES, getSetupScopeFilePath, readPersistedSetupPreferences, } from "./setup-preferences.js";
26
- import { OMX_LOCAL_MARKETPLACE_NAME, resolvePackagedOmxMarketplace, upsertLocalOmxMarketplaceRegistration, } from "./plugin-marketplace.js";
25
+ import { SETUP_INSTALL_MODES, SETUP_MCP_MODES, SETUP_SCOPES, getSetupScopeFilePath, readPersistedSetupPreferences, } from "./setup-preferences.js";
26
+ import { OMX_LOCAL_MARKETPLACE_NAME, resolvePackagedOmxMarketplace, upsertLocalOmxMarketplaceRegistration, upsertLocalOmxPluginEnablement, upsertLocalOmxPluginMcpServerEnablement, } from "./plugin-marketplace.js";
27
+ import { resolveCodexHookFeatureFlagForCli } from "./codex-feature-probe.js";
27
28
  async function resolveStatusLinePresetForSetup(projectRoot, options) {
28
29
  if (options.force) {
29
30
  return DEFAULT_HUD_CONFIG.statusLine.preset;
@@ -44,7 +45,7 @@ async function resolveStatusLinePresetForSetup(projectRoot, options) {
44
45
  return undefined;
45
46
  }
46
47
  import { resolveAgentsModelTableContext, upsertAgentsModelTable, } from "../utils/agents-model-table.js";
47
- export { SETUP_INSTALL_MODES, SETUP_SCOPES };
48
+ export { SETUP_INSTALL_MODES, SETUP_MCP_MODES, SETUP_SCOPES };
48
49
  const PROJECT_GITIGNORE_ENTRIES = [
49
50
  ".omx/",
50
51
  ".codex/*",
@@ -58,6 +59,7 @@ const PROJECT_GITIGNORE_ENTRIES = [
58
59
  ];
59
60
  const LEGACY_PROJECT_GITIGNORE_ENTRIES = [".codex/"];
60
61
  const SETUP_ONLY_INSTALLABLE_SKILLS = new Set(["wiki"]);
62
+ const DEFAULT_SETUP_MCP_MODE = "none";
61
63
  const HARD_DEPRECATED_SKILL_NAMES = new Set(["web-clone"]);
62
64
  function isCatalogInstallableStatus(status) {
63
65
  return status === "active" || status === "internal";
@@ -354,6 +356,7 @@ function formatPersistedSetupPreferenceSummary(preferences) {
354
356
  return [
355
357
  `scope=${preferences.scope ?? "not recorded"}`,
356
358
  `installMode=${preferences.installMode ?? "not recorded"}`,
359
+ `mcpMode=${preferences.mcpMode ?? "not recorded"}`,
357
360
  ].join(", ");
358
361
  }
359
362
  async function promptForPersistedSetupReview(preferences) {
@@ -628,6 +631,17 @@ async function refreshOmxPluginDiscoveryCache(pkgRoot, options) {
628
631
  staleDirs,
629
632
  };
630
633
  }
634
+ function resolveSetupMcpMode(scope, requestedMcpMode, persistedReviewDecision, persistedPreferences) {
635
+ if (requestedMcpMode) {
636
+ return { mcpMode: requestedMcpMode, source: "cli" };
637
+ }
638
+ if (persistedPreferences?.mcpMode &&
639
+ persistedReviewDecision === "keep" &&
640
+ persistedPreferences.scope === scope) {
641
+ return { mcpMode: persistedPreferences.mcpMode, source: "persisted" };
642
+ }
643
+ return { mcpMode: DEFAULT_SETUP_MCP_MODE, source: "default" };
644
+ }
631
645
  async function resolveSetupInstallMode(projectRoot, scope, requestedInstallMode, installModePrompt, persistedReviewDecision = "keep", persistedPreferences) {
632
646
  if (requestedInstallMode) {
633
647
  return { installMode: requestedInstallMode, source: "cli" };
@@ -888,7 +902,7 @@ function insertRootTomlKey(config, line) {
888
902
  const after = lines.slice(firstTableIndex);
889
903
  return [...before, line, "", ...after].join("\n") + "\n";
890
904
  }
891
- async function ensurePluginMarketplaceRegistration(configPath, pkgRoot, backupContext, summary, options) {
905
+ async function ensurePluginMarketplaceRegistration(configPath, pkgRoot, mcpMode, backupContext, summary, options) {
892
906
  const packagedMarketplace = await resolvePackagedOmxMarketplace(pkgRoot);
893
907
  if (!packagedMarketplace) {
894
908
  summary.skipped += 1;
@@ -897,7 +911,7 @@ async function ensurePluginMarketplaceRegistration(configPath, pkgRoot, backupCo
897
911
  const existingConfig = existsSync(configPath)
898
912
  ? await readFile(configPath, "utf-8")
899
913
  : "";
900
- const nextConfig = upsertLocalOmxMarketplaceRegistration(existingConfig, pkgRoot);
914
+ const nextConfig = upsertLocalOmxMarketplaceRegistration(upsertLocalOmxPluginMcpServerEnablement(upsertLocalOmxPluginEnablement(existingConfig), mcpMode === "compat"), pkgRoot);
901
915
  const destinationExists = existsSync(configPath);
902
916
  if (nextConfig === existingConfig) {
903
917
  summary.unchanged += 1;
@@ -920,7 +934,7 @@ async function applyPluginModeHooksConfig(configPath, hooksPath, pkgRoot, backup
920
934
  const existingConfig = existsSync(configPath)
921
935
  ? await readFile(configPath, "utf-8")
922
936
  : "";
923
- const nextConfig = upsertManagedCodexHookTrustState(upsertPluginModeRuntimeFeatureFlags(stripManagedCodexHookTrustState(existingConfig)), pkgRoot, hooksPath);
937
+ const nextConfig = upsertManagedCodexHookTrustState(upsertPluginModeRuntimeFeatureFlags(stripManagedCodexHookTrustState(existingConfig), options.codexHookFeatureFlag), pkgRoot, hooksPath);
924
938
  if (nextConfig !== existingConfig) {
925
939
  if (await ensureBackup(configPath, existsSync(configPath), backupContext, options)) {
926
940
  summary.backedUp += 1;
@@ -1028,7 +1042,7 @@ async function cleanupPluginModeLegacyAgentsMd(agentsMdPath, backupContext, opti
1028
1042
  return true;
1029
1043
  }
1030
1044
  export async function setup(options = {}) {
1031
- const { force = false, dryRun = false, installMode: requestedInstallMode, scope: requestedScope, verbose = false, setupScopePrompt, persistedSetupReviewPrompt, installModePrompt, modelUpgradePrompt, pluginAgentsMdPrompt, pluginDeveloperInstructionsPrompt, pluginDeveloperInstructionsOverwritePrompt, } = options;
1045
+ const { force = false, dryRun = false, installMode: requestedInstallMode, mcpMode: requestedMcpMode, scope: requestedScope, verbose = false, setupScopePrompt, persistedSetupReviewPrompt, installModePrompt, modelUpgradePrompt, pluginAgentsMdPrompt, pluginDeveloperInstructionsPrompt, pluginDeveloperInstructionsOverwritePrompt, } = options;
1032
1046
  const pkgRoot = getPackageRoot();
1033
1047
  const projectRoot = process.cwd();
1034
1048
  const persistedPreferences = await readPersistedSetupPreferences(projectRoot, { warnOnLegacyScope: true });
@@ -1039,8 +1053,12 @@ export async function setup(options = {}) {
1039
1053
  Boolean(persistedPreferences?.installMode) &&
1040
1054
  (!persistedPreferences?.scope ||
1041
1055
  persistedPreferences.scope === effectiveScopeForInstallMode);
1056
+ const wouldUsePersistedMcpMode = !requestedMcpMode &&
1057
+ Boolean(persistedPreferences?.mcpMode) &&
1058
+ (!persistedPreferences?.scope ||
1059
+ persistedPreferences.scope === effectiveScopeForInstallMode);
1042
1060
  const shouldReviewPersistedSetup = hasPersistedSetupPreferences(persistedPreferences) &&
1043
- (wouldUsePersistedScope || wouldUsePersistedInstallMode) &&
1061
+ (wouldUsePersistedScope || wouldUsePersistedInstallMode || wouldUsePersistedMcpMode) &&
1044
1062
  (typeof persistedSetupReviewPrompt === "function" ||
1045
1063
  (process.stdin.isTTY && process.stdout.isTTY));
1046
1064
  if (shouldReviewPersistedSetup) {
@@ -1051,6 +1069,7 @@ export async function setup(options = {}) {
1051
1069
  }
1052
1070
  const resolvedScope = await resolveSetupScope(projectRoot, requestedScope, persistedReviewDecision, persistedPreferences, setupScopePrompt);
1053
1071
  const resolvedInstallMode = await resolveSetupInstallMode(projectRoot, resolvedScope.scope, requestedInstallMode, installModePrompt, persistedReviewDecision, persistedPreferences);
1072
+ const resolvedMcpMode = resolveSetupMcpMode(resolvedScope.scope, requestedMcpMode, persistedReviewDecision, persistedPreferences);
1054
1073
  const scopeDirs = resolveScopeDirectories(resolvedScope.scope, projectRoot);
1055
1074
  const scopeSourceMessage = resolvedScope.source === "persisted" ? " (from .omx/setup-scope.json)" : "";
1056
1075
  const backupContext = getBackupContext(resolvedScope.scope, projectRoot);
@@ -1077,6 +1096,10 @@ export async function setup(options = {}) {
1077
1096
  : "";
1078
1097
  console.log(`Using setup install mode: ${resolvedInstallMode.installMode}${installModeSourceMessage}\n`);
1079
1098
  }
1099
+ const mcpModeSourceMessage = resolvedMcpMode.source === "persisted"
1100
+ ? " (from .omx/setup-scope.json)"
1101
+ : "";
1102
+ console.log(`Using setup MCP mode: ${resolvedMcpMode.mcpMode}${mcpModeSourceMessage}\n`);
1080
1103
  // Step 1: Ensure directories exist
1081
1104
  console.log("[1/8] Creating directories...");
1082
1105
  const dirs = isPluginInstallMode
@@ -1102,16 +1125,15 @@ export async function setup(options = {}) {
1102
1125
  if (verbose)
1103
1126
  console.log(` mkdir ${dir}`);
1104
1127
  }
1105
- const setupPreferencesToPersist = resolvedInstallMode &&
1106
- (resolvedScope.scope === "user" ||
1107
- resolvedInstallMode.installMode === "plugin")
1108
- ? {
1109
- scope: resolvedScope.scope,
1110
- installMode: resolvedInstallMode.installMode,
1111
- }
1112
- : {
1113
- scope: resolvedScope.scope,
1114
- };
1128
+ const setupPreferencesToPersist = {
1129
+ scope: resolvedScope.scope,
1130
+ mcpMode: resolvedMcpMode.mcpMode,
1131
+ ...(resolvedInstallMode &&
1132
+ (resolvedScope.scope === "user" ||
1133
+ resolvedInstallMode.installMode === "plugin")
1134
+ ? { installMode: resolvedInstallMode.installMode }
1135
+ : {}),
1136
+ };
1115
1137
  await persistSetupPreferences(projectRoot, setupPreferencesToPersist, {
1116
1138
  dryRun,
1117
1139
  verbose,
@@ -1217,6 +1239,35 @@ export async function setup(options = {}) {
1217
1239
  console.log("[5/8] Updating config.toml...");
1218
1240
  let resolvedConfig = "";
1219
1241
  let omxManagesTui = false;
1242
+ const codexHookFeatureFlag = resolveCodexHookFeatureFlagForCli({
1243
+ codexFeaturesProbe: options.codexFeaturesProbe,
1244
+ codexVersionProbe: options.codexVersionProbe,
1245
+ });
1246
+ if (verbose) {
1247
+ console.log(` Native Codex hook feature flag: [features].${codexHookFeatureFlag}`);
1248
+ }
1249
+ const shouldSyncSharedMcpRegistry = resolvedMcpMode.mcpMode === "compat";
1250
+ const registryCandidates = getUnifiedMcpRegistryCandidates();
1251
+ const defaultRegistryCandidates = registryCandidates.slice(0, 1);
1252
+ const sharedMcpRegistry = shouldSyncSharedMcpRegistry
1253
+ ? await loadUnifiedMcpRegistry({
1254
+ candidates: options.mcpRegistryCandidates ?? defaultRegistryCandidates,
1255
+ })
1256
+ : { servers: [], warnings: [] };
1257
+ const legacyRegistryCandidate = getLegacyUnifiedMcpRegistryCandidate();
1258
+ if (shouldSyncSharedMcpRegistry &&
1259
+ !options.mcpRegistryCandidates &&
1260
+ !sharedMcpRegistry.sourcePath &&
1261
+ existsSync(legacyRegistryCandidate) &&
1262
+ !existsSync(defaultRegistryCandidates[0])) {
1263
+ console.log(` warning: legacy shared MCP registry detected at ${legacyRegistryCandidate} but ignored by default; move or copy it to ${defaultRegistryCandidates[0]} and rerun setup with --mcp compat if you still want setup to sync those servers`);
1264
+ }
1265
+ if (verbose && sharedMcpRegistry.sourcePath) {
1266
+ console.log(` shared MCP registry: ${sharedMcpRegistry.sourcePath} (${sharedMcpRegistry.servers.length} servers)`);
1267
+ }
1268
+ for (const warning of sharedMcpRegistry.warnings) {
1269
+ console.log(` warning: ${warning}`);
1270
+ }
1220
1271
  if (isPluginInstallMode) {
1221
1272
  const configCleaned = await cleanupPluginModeLegacyConfig(scopeDirs.codexConfigFile, backupContext, { dryRun, verbose });
1222
1273
  if (configCleaned)
@@ -1224,8 +1275,8 @@ export async function setup(options = {}) {
1224
1275
  console.log(configCleaned
1225
1276
  ? ` ${dryRun ? "Would clean" : "Cleaned"} legacy OMX config entries for plugin mode.\n`
1226
1277
  : " Config refresh skipped; no legacy OMX config entries found.\n");
1227
- await applyPluginModeHooksConfig(scopeDirs.codexConfigFile, scopeDirs.codexHooksFile, pkgRoot, backupContext, summary.config, { dryRun, verbose });
1228
- const pluginMarketplaceResult = await ensurePluginMarketplaceRegistration(scopeDirs.codexConfigFile, pkgRoot, backupContext, summary.config, { dryRun, verbose });
1278
+ await applyPluginModeHooksConfig(scopeDirs.codexConfigFile, scopeDirs.codexHooksFile, pkgRoot, backupContext, summary.config, { dryRun, verbose, codexHookFeatureFlag });
1279
+ const pluginMarketplaceResult = await ensurePluginMarketplaceRegistration(scopeDirs.codexConfigFile, pkgRoot, resolvedMcpMode.mcpMode, backupContext, summary.config, { dryRun, verbose });
1229
1280
  if (pluginMarketplaceResult === "unavailable") {
1230
1281
  console.log(` warning: packaged ${OMX_LOCAL_MARKETPLACE_NAME} Codex plugin marketplace metadata not found; /skills plugin discovery was not registered.`);
1231
1282
  }
@@ -1245,6 +1296,12 @@ export async function setup(options = {}) {
1245
1296
  else if (pluginCacheRefresh.status === "unchanged") {
1246
1297
  console.log(" Codex plugin discovery cache already matches packaged plugin metadata.");
1247
1298
  }
1299
+ if (shouldSyncSharedMcpRegistry) {
1300
+ resolvedConfig = await syncSharedMcpRegistryIntoConfig(scopeDirs.codexConfigFile, sharedMcpRegistry, summary.config, backupContext, { dryRun, verbose });
1301
+ if (resolvedScope.scope === "user") {
1302
+ await syncClaudeCodeMcpSettings(sharedMcpRegistry, summary.config, backupContext, { dryRun, verbose });
1303
+ }
1304
+ }
1248
1305
  resolvedConfig = existsSync(scopeDirs.codexConfigFile)
1249
1306
  ? await readFile(scopeDirs.codexConfigFile, "utf-8")
1250
1307
  : "";
@@ -1270,38 +1327,21 @@ export async function setup(options = {}) {
1270
1327
  }
1271
1328
  }
1272
1329
  else {
1273
- const registryCandidates = getUnifiedMcpRegistryCandidates();
1274
- const defaultRegistryCandidates = registryCandidates.slice(0, 1);
1275
- const legacyRegistryCandidate = getLegacyUnifiedMcpRegistryCandidate();
1276
- const sharedMcpRegistry = await loadUnifiedMcpRegistry({
1277
- candidates: options.mcpRegistryCandidates ?? defaultRegistryCandidates,
1278
- });
1279
- if (!options.mcpRegistryCandidates &&
1280
- !sharedMcpRegistry.sourcePath &&
1281
- existsSync(legacyRegistryCandidate) &&
1282
- !existsSync(defaultRegistryCandidates[0])) {
1283
- console.log(` warning: legacy shared MCP registry detected at ${legacyRegistryCandidate} but ignored by default; move it to ${defaultRegistryCandidates[0]} if you still want setup to sync those servers`);
1284
- }
1285
- if (verbose && sharedMcpRegistry.sourcePath) {
1286
- console.log(` shared MCP registry: ${sharedMcpRegistry.sourcePath} (${sharedMcpRegistry.servers.length} servers)`);
1287
- }
1288
- for (const warning of sharedMcpRegistry.warnings) {
1289
- console.log(` warning: ${warning}`);
1290
- }
1291
1330
  const statusLinePreset = await resolveStatusLinePresetForSetup(projectRoot, { force });
1292
- const managedConfig = await updateManagedConfig(scopeDirs.codexConfigFile, scopeDirs.codexHooksFile, pkgRoot, sharedMcpRegistry, resolvedScope.scope, scopeDirs.codexHomeDir, summary.config, backupContext, {
1331
+ const managedConfig = await updateManagedConfig(scopeDirs.codexConfigFile, scopeDirs.codexHooksFile, pkgRoot, sharedMcpRegistry, resolvedMcpMode.mcpMode, resolvedScope.scope, scopeDirs.codexHomeDir, summary.config, backupContext, {
1293
1332
  dryRun,
1294
1333
  modelUpgradePrompt,
1295
1334
  verbose,
1296
1335
  statusLinePreset,
1297
1336
  forceStatusLinePreset: force,
1337
+ codexHookFeatureFlag,
1298
1338
  });
1299
1339
  resolvedConfig = managedConfig.finalConfig;
1300
1340
  omxManagesTui = managedConfig.omxManagesTui;
1301
1341
  if (managedConfig.repairedLegacyTeamRunTable) {
1302
1342
  console.log(" Removed retired [mcp_servers.omx_team_run] config during refresh.");
1303
1343
  }
1304
- if (resolvedScope.scope === "user") {
1344
+ if (shouldSyncSharedMcpRegistry && resolvedScope.scope === "user") {
1305
1345
  await syncClaudeCodeMcpSettings(sharedMcpRegistry, summary.config, backupContext, { dryRun, verbose });
1306
1346
  }
1307
1347
  console.log(` Config refresh complete (${scopeDirs.codexConfigFile}).\n`);
@@ -2059,13 +2099,17 @@ async function buildNotifyMergePlan(existingConfig, pkgRoot, codexHomeDir, scope
2059
2099
  const previousNotify = metadata.previousNotify;
2060
2100
  if (Array.isArray(previousNotify) &&
2061
2101
  previousNotify.every((item) => typeof item === "string")) {
2102
+ const sanitizedPreviousNotify = sanitizePreviousNotifyCommand(previousNotify, pkgRoot);
2103
+ if (!sanitizedPreviousNotify) {
2104
+ return { notifyCommand: omxNotify };
2105
+ }
2062
2106
  return {
2063
2107
  notifyCommand: dispatcherNotify,
2064
2108
  metadataPath,
2065
2109
  metadata: {
2066
2110
  managedBy: "oh-my-codex",
2067
2111
  version: 1,
2068
- previousNotify,
2112
+ previousNotify: sanitizedPreviousNotify,
2069
2113
  omxNotify,
2070
2114
  dispatcherNotify,
2071
2115
  },
@@ -2083,13 +2127,13 @@ async function buildNotifyMergePlan(existingConfig, pkgRoot, codexHomeDir, scope
2083
2127
  metadata: {
2084
2128
  managedBy: "oh-my-codex",
2085
2129
  version: 1,
2086
- previousNotify: existingNotify,
2130
+ previousNotify: sanitizePreviousNotifyCommand(existingNotify, pkgRoot),
2087
2131
  omxNotify,
2088
2132
  dispatcherNotify,
2089
2133
  },
2090
2134
  };
2091
2135
  }
2092
- async function updateManagedConfig(configPath, hooksPath, pkgRoot, sharedMcpRegistry, scope, codexHomeDir, summary, backupContext, options) {
2136
+ async function updateManagedConfig(configPath, hooksPath, pkgRoot, sharedMcpRegistry, mcpMode, scope, codexHomeDir, summary, backupContext, options) {
2093
2137
  const existing = existsSync(configPath)
2094
2138
  ? await readFile(configPath, "utf-8")
2095
2139
  : "";
@@ -2113,6 +2157,7 @@ async function updateManagedConfig(configPath, hooksPath, pkgRoot, sharedMcpRegi
2113
2157
  const finalConfig = buildMergedConfig(existing, pkgRoot, {
2114
2158
  includeTui: omxManagesTui,
2115
2159
  codexHooksFile: hooksPath,
2160
+ codexHookFeatureFlag: options.codexHookFeatureFlag,
2116
2161
  modelOverride,
2117
2162
  sharedMcpServers: sharedMcpRegistry.servers,
2118
2163
  sharedMcpRegistrySource: sharedMcpRegistry.sourcePath,
@@ -2120,6 +2165,7 @@ async function updateManagedConfig(configPath, hooksPath, pkgRoot, sharedMcpRegi
2120
2165
  statusLinePreset: options.statusLinePreset,
2121
2166
  forceStatusLinePreset: options.forceStatusLinePreset,
2122
2167
  notifyCommand: notifyPlan.notifyCommand,
2168
+ includeFirstPartyMcp: mcpMode === "compat",
2123
2169
  });
2124
2170
  const changed = existing !== finalConfig;
2125
2171
  if (!changed) {
@@ -2156,6 +2202,30 @@ async function updateManagedConfig(configPath, hooksPath, pkgRoot, sharedMcpRegi
2156
2202
  repairedLegacyTeamRunTable: hadLegacyTeamRunTable && !hasLegacyOmxTeamRunTable(finalConfig),
2157
2203
  };
2158
2204
  }
2205
+ async function syncSharedMcpRegistryIntoConfig(configPath, sharedMcpRegistry, summary, backupContext, options) {
2206
+ if (sharedMcpRegistry.servers.length === 0) {
2207
+ return existsSync(configPath) ? await readFile(configPath, "utf-8") : "";
2208
+ }
2209
+ const existing = existsSync(configPath)
2210
+ ? await readFile(configPath, "utf-8")
2211
+ : "";
2212
+ const finalConfig = mergeSharedMcpRegistryBlock(existing, sharedMcpRegistry.servers, sharedMcpRegistry.sourcePath);
2213
+ if (existing === finalConfig) {
2214
+ summary.unchanged += 1;
2215
+ return finalConfig;
2216
+ }
2217
+ if (await ensureBackup(configPath, existsSync(configPath), backupContext, options)) {
2218
+ summary.backedUp += 1;
2219
+ }
2220
+ if (!options.dryRun) {
2221
+ await writeFile(configPath, finalConfig);
2222
+ }
2223
+ summary.updated += 1;
2224
+ if (options.verbose) {
2225
+ console.log(` ${options.dryRun ? "would sync" : "synced"} shared MCP registry servers into ${configPath}`);
2226
+ }
2227
+ return finalConfig;
2228
+ }
2159
2229
  function getClaudeCodeSettingsPath(homeDir = homedir()) {
2160
2230
  return join(homeDir, ".claude", "settings.json");
2161
2231
  }