@stanco323/oh-my-claude-code 4.10.3 → 4.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.
Files changed (387) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +65 -18
  4. package/bridge/cli.cjs +3030 -1784
  5. package/bridge/mcp-server.cjs +128 -98
  6. package/bridge/runtime-cli.cjs +174 -136
  7. package/bridge/team-bridge.cjs +102 -96
  8. package/bridge/team-mcp.cjs +40 -29
  9. package/bridge/team.js +102 -88
  10. package/dist/__tests__/auto-update.test.js +8 -9
  11. package/dist/__tests__/auto-update.test.js.map +1 -1
  12. package/dist/__tests__/cli-config-stop-callback.test.js +26 -0
  13. package/dist/__tests__/cli-config-stop-callback.test.js.map +1 -1
  14. package/dist/__tests__/config-dir.test.d.ts +2 -0
  15. package/dist/__tests__/config-dir.test.d.ts.map +1 -0
  16. package/dist/__tests__/config-dir.test.js +184 -0
  17. package/dist/__tests__/config-dir.test.js.map +1 -0
  18. package/dist/__tests__/delegation-enforcement-levels.test.js +45 -1
  19. package/dist/__tests__/delegation-enforcement-levels.test.js.map +1 -1
  20. package/dist/__tests__/doctor-conflicts.test.js +9 -7
  21. package/dist/__tests__/doctor-conflicts.test.js.map +1 -1
  22. package/dist/__tests__/hooks-command-escaping.test.js +17 -10
  23. package/dist/__tests__/hooks-command-escaping.test.js.map +1 -1
  24. package/dist/__tests__/hud/cli-diagnostic.test.js +1 -1
  25. package/dist/__tests__/hud/cli-diagnostic.test.js.map +1 -1
  26. package/dist/__tests__/hud/usage-api-lock.test.js +5 -5
  27. package/dist/__tests__/hud/usage-api-lock.test.js.map +1 -1
  28. package/dist/__tests__/hud/usage-api-stale.test.js +2 -2
  29. package/dist/__tests__/hud/usage-api-stale.test.js.map +1 -1
  30. package/dist/__tests__/hud/usage-api.test.js +98 -0
  31. package/dist/__tests__/hud/usage-api.test.js.map +1 -1
  32. package/dist/__tests__/hud-api-key-source.test.js +2 -2
  33. package/dist/__tests__/hud-api-key-source.test.js.map +1 -1
  34. package/dist/__tests__/hud-marketplace-resolution.test.js +3 -1
  35. package/dist/__tests__/hud-marketplace-resolution.test.js.map +1 -1
  36. package/dist/__tests__/hud-windows.test.js +7 -6
  37. package/dist/__tests__/hud-windows.test.js.map +1 -1
  38. package/dist/__tests__/installer-omc-reference.test.js +122 -6
  39. package/dist/__tests__/installer-omc-reference.test.js.map +1 -1
  40. package/dist/__tests__/installer.test.js +33 -9
  41. package/dist/__tests__/installer.test.js.map +1 -1
  42. package/dist/__tests__/omc-tools-server.test.js +5 -5
  43. package/dist/__tests__/pre-tool-enforcer.test.js +34 -14
  44. package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
  45. package/dist/__tests__/preemptive-compaction-hook.test.d.ts +2 -0
  46. package/dist/__tests__/preemptive-compaction-hook.test.d.ts.map +1 -0
  47. package/dist/__tests__/preemptive-compaction-hook.test.js +163 -0
  48. package/dist/__tests__/preemptive-compaction-hook.test.js.map +1 -0
  49. package/dist/__tests__/purge-stale-cache.test.js +1 -1
  50. package/dist/__tests__/purge-stale-cache.test.js.map +1 -1
  51. package/dist/__tests__/release-generation.test.d.ts +2 -0
  52. package/dist/__tests__/release-generation.test.d.ts.map +1 -0
  53. package/dist/__tests__/release-generation.test.js +79 -0
  54. package/dist/__tests__/release-generation.test.js.map +1 -0
  55. package/dist/__tests__/runtime-guidance-plan-ralph.test.d.ts +2 -0
  56. package/dist/__tests__/runtime-guidance-plan-ralph.test.d.ts.map +1 -0
  57. package/dist/__tests__/runtime-guidance-plan-ralph.test.js +87 -0
  58. package/dist/__tests__/runtime-guidance-plan-ralph.test.js.map +1 -0
  59. package/dist/__tests__/session-history-search.test.js +31 -3
  60. package/dist/__tests__/session-history-search.test.js.map +1 -1
  61. package/dist/__tests__/setup-claude-md-script.test.js +9 -1
  62. package/dist/__tests__/setup-claude-md-script.test.js.map +1 -1
  63. package/dist/__tests__/setup-no-plugin-flag.test.d.ts +2 -0
  64. package/dist/__tests__/setup-no-plugin-flag.test.d.ts.map +1 -0
  65. package/dist/__tests__/setup-no-plugin-flag.test.js +15 -0
  66. package/dist/__tests__/setup-no-plugin-flag.test.js.map +1 -0
  67. package/dist/__tests__/shared-memory.test.js +40 -2
  68. package/dist/__tests__/shared-memory.test.js.map +1 -1
  69. package/dist/__tests__/skills.test.js +45 -1
  70. package/dist/__tests__/skills.test.js.map +1 -1
  71. package/dist/cli/__tests__/launch.test.js +48 -14
  72. package/dist/cli/__tests__/launch.test.js.map +1 -1
  73. package/dist/cli/commands/__tests__/team-role-shorthand.test.d.ts +2 -0
  74. package/dist/cli/commands/__tests__/team-role-shorthand.test.d.ts.map +1 -0
  75. package/dist/cli/commands/__tests__/team-role-shorthand.test.js +63 -0
  76. package/dist/cli/commands/__tests__/team-role-shorthand.test.js.map +1 -0
  77. package/dist/cli/commands/__tests__/team.test.js +21 -0
  78. package/dist/cli/commands/__tests__/team.test.js.map +1 -1
  79. package/dist/cli/commands/adapt.d.ts.map +1 -1
  80. package/dist/cli/commands/adapt.js.map +1 -1
  81. package/dist/cli/commands/doctor-conflicts.js +1 -1
  82. package/dist/cli/commands/doctor-conflicts.js.map +1 -1
  83. package/dist/cli/commands/team.d.ts.map +1 -1
  84. package/dist/cli/commands/team.js +30 -17
  85. package/dist/cli/commands/team.js.map +1 -1
  86. package/dist/cli/index.js +16 -7
  87. package/dist/cli/index.js.map +1 -1
  88. package/dist/cli/launch.d.ts.map +1 -1
  89. package/dist/cli/launch.js +22 -14
  90. package/dist/cli/launch.js.map +1 -1
  91. package/dist/commands/index.js +1 -1
  92. package/dist/commands/index.js.map +1 -1
  93. package/dist/constants/names.d.ts +1 -0
  94. package/dist/constants/names.d.ts.map +1 -1
  95. package/dist/constants/names.js +1 -0
  96. package/dist/constants/names.js.map +1 -1
  97. package/dist/features/auto-update.d.ts.map +1 -1
  98. package/dist/features/auto-update.js +4 -4
  99. package/dist/features/auto-update.js.map +1 -1
  100. package/dist/features/background-agent/manager.js +1 -1
  101. package/dist/features/background-agent/manager.js.map +1 -1
  102. package/dist/features/builtin-skills/runtime-guidance.d.ts.map +1 -1
  103. package/dist/features/builtin-skills/runtime-guidance.js +35 -3
  104. package/dist/features/builtin-skills/runtime-guidance.js.map +1 -1
  105. package/dist/features/builtin-skills/skills.d.ts.map +1 -1
  106. package/dist/features/builtin-skills/skills.js +53 -1
  107. package/dist/features/builtin-skills/skills.js.map +1 -1
  108. package/dist/features/session-history-search/index.d.ts.map +1 -1
  109. package/dist/features/session-history-search/index.js +1 -4
  110. package/dist/features/session-history-search/index.js.map +1 -1
  111. package/dist/hooks/__tests__/bridge-routing.test.js +4 -0
  112. package/dist/hooks/__tests__/bridge-routing.test.js.map +1 -1
  113. package/dist/hooks/__tests__/bridge.test.js +42 -1
  114. package/dist/hooks/__tests__/bridge.test.js.map +1 -1
  115. package/dist/hooks/auto-slash-command/executor.js +2 -2
  116. package/dist/hooks/auto-slash-command/executor.js.map +1 -1
  117. package/dist/hooks/autopilot/enforcement.d.ts.map +1 -1
  118. package/dist/hooks/autopilot/enforcement.js +20 -4
  119. package/dist/hooks/autopilot/enforcement.js.map +1 -1
  120. package/dist/hooks/bridge.d.ts +15 -0
  121. package/dist/hooks/bridge.d.ts.map +1 -1
  122. package/dist/hooks/bridge.js +38 -1
  123. package/dist/hooks/bridge.js.map +1 -1
  124. package/dist/hooks/factcheck/__tests__/factcheck.test.js +6 -5
  125. package/dist/hooks/factcheck/__tests__/factcheck.test.js.map +1 -1
  126. package/dist/hooks/factcheck/config.d.ts +2 -2
  127. package/dist/hooks/factcheck/config.d.ts.map +1 -1
  128. package/dist/hooks/factcheck/config.js +6 -4
  129. package/dist/hooks/factcheck/config.js.map +1 -1
  130. package/dist/hooks/index.d.ts +1 -1
  131. package/dist/hooks/index.d.ts.map +1 -1
  132. package/dist/hooks/index.js +1 -1
  133. package/dist/hooks/index.js.map +1 -1
  134. package/dist/hooks/learner/auto-invoke.js +1 -1
  135. package/dist/hooks/learner/auto-invoke.js.map +1 -1
  136. package/dist/hooks/learner/config.js +1 -1
  137. package/dist/hooks/learner/config.js.map +1 -1
  138. package/dist/hooks/learner/constants.js +1 -1
  139. package/dist/hooks/learner/constants.js.map +1 -1
  140. package/dist/hooks/omc-orchestrator/constants.d.ts +1 -1
  141. package/dist/hooks/omc-orchestrator/constants.d.ts.map +1 -1
  142. package/dist/hooks/omc-orchestrator/constants.js +2 -2
  143. package/dist/hooks/omc-orchestrator/constants.js.map +1 -1
  144. package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -1
  145. package/dist/hooks/omc-orchestrator/index.js +10 -7
  146. package/dist/hooks/omc-orchestrator/index.js.map +1 -1
  147. package/dist/hooks/permission-handler/index.js +1 -1
  148. package/dist/hooks/permission-handler/index.js.map +1 -1
  149. package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
  150. package/dist/hooks/persistent-mode/index.js +21 -4
  151. package/dist/hooks/persistent-mode/index.js.map +1 -1
  152. package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +91 -0
  153. package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
  154. package/dist/hooks/rules-injector/constants.d.ts +0 -2
  155. package/dist/hooks/rules-injector/constants.d.ts.map +1 -1
  156. package/dist/hooks/rules-injector/constants.js +0 -2
  157. package/dist/hooks/rules-injector/constants.js.map +1 -1
  158. package/dist/hooks/rules-injector/finder.d.ts +3 -3
  159. package/dist/hooks/rules-injector/finder.d.ts.map +1 -1
  160. package/dist/hooks/rules-injector/finder.js +7 -6
  161. package/dist/hooks/rules-injector/finder.js.map +1 -1
  162. package/dist/hooks/rules-injector/index.d.ts +1 -1
  163. package/dist/hooks/rules-injector/index.d.ts.map +1 -1
  164. package/dist/hooks/rules-injector/index.js +3 -6
  165. package/dist/hooks/rules-injector/index.js.map +1 -1
  166. package/dist/hooks/setup/__tests__/stdin-symlink.test.d.ts +2 -0
  167. package/dist/hooks/setup/__tests__/stdin-symlink.test.d.ts.map +1 -0
  168. package/dist/hooks/setup/__tests__/stdin-symlink.test.js +184 -0
  169. package/dist/hooks/setup/__tests__/stdin-symlink.test.js.map +1 -0
  170. package/dist/hooks/setup/index.d.ts +13 -0
  171. package/dist/hooks/setup/index.d.ts.map +1 -1
  172. package/dist/hooks/setup/index.js +100 -2
  173. package/dist/hooks/setup/index.js.map +1 -1
  174. package/dist/hooks/skill-bridge.cjs +19 -13
  175. package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
  176. package/dist/hooks/subagent-tracker/index.js +7 -3
  177. package/dist/hooks/subagent-tracker/index.js.map +1 -1
  178. package/dist/hooks/todo-continuation/index.js +1 -1
  179. package/dist/hooks/todo-continuation/index.js.map +1 -1
  180. package/dist/hooks/wiki/__tests__/ingest.test.d.ts +5 -0
  181. package/dist/hooks/wiki/__tests__/ingest.test.d.ts.map +1 -0
  182. package/dist/hooks/wiki/__tests__/ingest.test.js +180 -0
  183. package/dist/hooks/wiki/__tests__/ingest.test.js.map +1 -0
  184. package/dist/hooks/wiki/__tests__/lint.test.d.ts +5 -0
  185. package/dist/hooks/wiki/__tests__/lint.test.d.ts.map +1 -0
  186. package/dist/hooks/wiki/__tests__/lint.test.js +162 -0
  187. package/dist/hooks/wiki/__tests__/lint.test.js.map +1 -0
  188. package/dist/hooks/wiki/__tests__/query.test.d.ts +5 -0
  189. package/dist/hooks/wiki/__tests__/query.test.d.ts.map +1 -0
  190. package/dist/hooks/wiki/__tests__/query.test.js +119 -0
  191. package/dist/hooks/wiki/__tests__/query.test.js.map +1 -0
  192. package/dist/hooks/wiki/__tests__/session-hooks.test.d.ts +5 -0
  193. package/dist/hooks/wiki/__tests__/session-hooks.test.d.ts.map +1 -0
  194. package/dist/hooks/wiki/__tests__/session-hooks.test.js +40 -0
  195. package/dist/hooks/wiki/__tests__/session-hooks.test.js.map +1 -0
  196. package/dist/hooks/wiki/__tests__/storage.test.d.ts +5 -0
  197. package/dist/hooks/wiki/__tests__/storage.test.d.ts.map +1 -0
  198. package/dist/hooks/wiki/__tests__/storage.test.js +277 -0
  199. package/dist/hooks/wiki/__tests__/storage.test.js.map +1 -0
  200. package/dist/hooks/wiki/index.d.ts +13 -0
  201. package/dist/hooks/wiki/index.d.ts.map +1 -0
  202. package/dist/hooks/wiki/index.js +16 -0
  203. package/dist/hooks/wiki/index.js.map +1 -0
  204. package/dist/hooks/wiki/ingest.d.ts +20 -0
  205. package/dist/hooks/wiki/ingest.d.ts.map +1 -0
  206. package/dist/hooks/wiki/ingest.js +115 -0
  207. package/dist/hooks/wiki/ingest.js.map +1 -0
  208. package/dist/hooks/wiki/lint.d.ts +25 -0
  209. package/dist/hooks/wiki/lint.d.ts.map +1 -0
  210. package/dist/hooks/wiki/lint.js +166 -0
  211. package/dist/hooks/wiki/lint.js.map +1 -0
  212. package/dist/hooks/wiki/query.d.ts +27 -0
  213. package/dist/hooks/wiki/query.d.ts.map +1 -0
  214. package/dist/hooks/wiki/query.js +97 -0
  215. package/dist/hooks/wiki/query.js.map +1 -0
  216. package/dist/hooks/wiki/session-hooks.d.ts +42 -0
  217. package/dist/hooks/wiki/session-hooks.d.ts.map +1 -0
  218. package/dist/hooks/wiki/session-hooks.js +228 -0
  219. package/dist/hooks/wiki/session-hooks.js.map +1 -0
  220. package/dist/hooks/wiki/storage.d.ts +73 -0
  221. package/dist/hooks/wiki/storage.d.ts.map +1 -0
  222. package/dist/hooks/wiki/storage.js +343 -0
  223. package/dist/hooks/wiki/storage.js.map +1 -0
  224. package/dist/hooks/wiki/types.d.ts +136 -0
  225. package/dist/hooks/wiki/types.d.ts.map +1 -0
  226. package/dist/hooks/wiki/types.js +19 -0
  227. package/dist/hooks/wiki/types.js.map +1 -0
  228. package/dist/hud/custom-rate-provider.js +1 -1
  229. package/dist/hud/custom-rate-provider.js.map +1 -1
  230. package/dist/hud/elements/api-key-source.js +1 -1
  231. package/dist/hud/elements/api-key-source.js.map +1 -1
  232. package/dist/hud/index.js +1 -1
  233. package/dist/hud/index.js.map +1 -1
  234. package/dist/hud/state.js +1 -1
  235. package/dist/hud/state.js.map +1 -1
  236. package/dist/hud/usage-api.d.ts.map +1 -1
  237. package/dist/hud/usage-api.js +6 -2
  238. package/dist/hud/usage-api.js.map +1 -1
  239. package/dist/installer/__tests__/standalone-hook-reconcile.test.js +3 -0
  240. package/dist/installer/__tests__/standalone-hook-reconcile.test.js.map +1 -1
  241. package/dist/installer/hooks.d.ts +0 -2
  242. package/dist/installer/hooks.d.ts.map +1 -1
  243. package/dist/installer/hooks.js +1 -5
  244. package/dist/installer/hooks.js.map +1 -1
  245. package/dist/installer/index.d.ts +3 -0
  246. package/dist/installer/index.d.ts.map +1 -1
  247. package/dist/installer/index.js +176 -32
  248. package/dist/installer/index.js.map +1 -1
  249. package/dist/installer/mcp-registry.js +2 -2
  250. package/dist/installer/mcp-registry.js.map +1 -1
  251. package/dist/lib/release-generation.d.ts +20 -0
  252. package/dist/lib/release-generation.d.ts.map +1 -0
  253. package/dist/lib/release-generation.js +198 -0
  254. package/dist/lib/release-generation.js.map +1 -0
  255. package/dist/lib/shared-memory.d.ts +2 -1
  256. package/dist/lib/shared-memory.d.ts.map +1 -1
  257. package/dist/lib/shared-memory.js +4 -2
  258. package/dist/lib/shared-memory.js.map +1 -1
  259. package/dist/lib/worktree-paths.d.ts.map +1 -1
  260. package/dist/lib/worktree-paths.js +36 -10
  261. package/dist/lib/worktree-paths.js.map +1 -1
  262. package/dist/mcp/omc-tools-server.d.ts +2 -0
  263. package/dist/mcp/omc-tools-server.d.ts.map +1 -1
  264. package/dist/mcp/omc-tools-server.js +9 -2
  265. package/dist/mcp/omc-tools-server.js.map +1 -1
  266. package/dist/notifications/__tests__/config-merge.test.js +1 -1
  267. package/dist/notifications/__tests__/config-merge.test.js.map +1 -1
  268. package/dist/notifications/__tests__/profiles.test.js +1 -1
  269. package/dist/notifications/__tests__/profiles.test.js.map +1 -1
  270. package/dist/notifications/config.js +1 -1
  271. package/dist/notifications/config.js.map +1 -1
  272. package/dist/notifications/hook-config.js +1 -1
  273. package/dist/notifications/hook-config.js.map +1 -1
  274. package/dist/openclaw/__tests__/config.test.js +1 -1
  275. package/dist/openclaw/__tests__/config.test.js.map +1 -1
  276. package/dist/openclaw/config.js +1 -1
  277. package/dist/openclaw/config.js.map +1 -1
  278. package/dist/skills/__tests__/mingw-escape.test.js +1 -1
  279. package/dist/skills/__tests__/mingw-escape.test.js.map +1 -1
  280. package/dist/team/__tests__/api-interop.dispatch.test.js +2 -1
  281. package/dist/team/__tests__/api-interop.dispatch.test.js.map +1 -1
  282. package/dist/team/__tests__/bridge-integration.test.js +5 -3
  283. package/dist/team/__tests__/bridge-integration.test.js.map +1 -1
  284. package/dist/team/__tests__/edge-cases.test.js +6 -7
  285. package/dist/team/__tests__/edge-cases.test.js.map +1 -1
  286. package/dist/team/__tests__/inbox-outbox.test.js +2 -2
  287. package/dist/team/__tests__/inbox-outbox.test.js.map +1 -1
  288. package/dist/team/__tests__/message-router.test.js +6 -5
  289. package/dist/team/__tests__/message-router.test.js.map +1 -1
  290. package/dist/team/__tests__/outbox-reader.test.js +2 -2
  291. package/dist/team/__tests__/outbox-reader.test.js.map +1 -1
  292. package/dist/team/__tests__/runtime-v2.dispatch.test.js +4 -4
  293. package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -1
  294. package/dist/team/__tests__/shell-affinity.test.js +16 -0
  295. package/dist/team/__tests__/shell-affinity.test.js.map +1 -1
  296. package/dist/team/__tests__/team-registration.test.js +3 -2
  297. package/dist/team/__tests__/team-registration.test.js.map +1 -1
  298. package/dist/team/__tests__/team-status.test.js +3 -3
  299. package/dist/team/__tests__/team-status.test.js.map +1 -1
  300. package/dist/team/__tests__/tmux-session.test.js +6 -1
  301. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  302. package/dist/team/bridge-entry.js +1 -1
  303. package/dist/team/bridge-entry.js.map +1 -1
  304. package/dist/team/inbox-outbox.js +1 -1
  305. package/dist/team/inbox-outbox.js.map +1 -1
  306. package/dist/team/message-router.js +1 -1
  307. package/dist/team/message-router.js.map +1 -1
  308. package/dist/team/outbox-reader.js +1 -1
  309. package/dist/team/outbox-reader.js.map +1 -1
  310. package/dist/team/runtime-v2.d.ts.map +1 -1
  311. package/dist/team/runtime-v2.js +6 -17
  312. package/dist/team/runtime-v2.js.map +1 -1
  313. package/dist/team/task-file-ops.js +1 -1
  314. package/dist/team/task-file-ops.js.map +1 -1
  315. package/dist/team/team-registration.js +1 -1
  316. package/dist/team/team-registration.js.map +1 -1
  317. package/dist/team/team-status.js +1 -1
  318. package/dist/team/team-status.js.map +1 -1
  319. package/dist/team/tmux-session.d.ts +1 -1
  320. package/dist/team/tmux-session.d.ts.map +1 -1
  321. package/dist/team/tmux-session.js +39 -4
  322. package/dist/team/tmux-session.js.map +1 -1
  323. package/dist/team/unified-team.js +1 -1
  324. package/dist/team/unified-team.js.map +1 -1
  325. package/dist/tools/shared-memory-tools.d.ts.map +1 -1
  326. package/dist/tools/shared-memory-tools.js +2 -1
  327. package/dist/tools/shared-memory-tools.js.map +1 -1
  328. package/dist/tools/skills-tools.d.ts.map +1 -1
  329. package/dist/tools/skills-tools.js +3 -2
  330. package/dist/tools/skills-tools.js.map +1 -1
  331. package/dist/tools/wiki-tools.d.ts +74 -0
  332. package/dist/tools/wiki-tools.d.ts.map +1 -0
  333. package/dist/tools/wiki-tools.js +370 -0
  334. package/dist/tools/wiki-tools.js.map +1 -0
  335. package/dist/utils/config-dir.d.ts +21 -1
  336. package/dist/utils/config-dir.d.ts.map +1 -1
  337. package/dist/utils/config-dir.js +45 -4
  338. package/dist/utils/config-dir.js.map +1 -1
  339. package/dist/utils/paths.d.ts +0 -5
  340. package/dist/utils/paths.d.ts.map +1 -1
  341. package/dist/utils/paths.js +1 -8
  342. package/dist/utils/paths.js.map +1 -1
  343. package/docs/CLAUDE.md +1 -1
  344. package/hooks/hooks.json +15 -0
  345. package/package.json +1 -1
  346. package/scripts/cleanup-orphans.mjs +2 -2
  347. package/scripts/context-guard-stop.mjs +10 -4
  348. package/scripts/find-node.sh +13 -1
  349. package/scripts/keyword-detector.mjs +9 -2
  350. package/scripts/lib/config-dir.cjs +31 -0
  351. package/scripts/lib/config-dir.mjs +29 -0
  352. package/scripts/lib/config-dir.sh +18 -0
  353. package/scripts/lib/pre-tool-enforcer-preflight.mjs +63 -0
  354. package/scripts/persistent-mode.cjs +29 -6
  355. package/scripts/persistent-mode.mjs +24 -4
  356. package/scripts/plugin-setup.mjs +18 -7
  357. package/scripts/post-tool-verifier.mjs +200 -7
  358. package/scripts/pre-tool-enforcer.mjs +15 -56
  359. package/scripts/release.ts +158 -224
  360. package/scripts/session-start.mjs +6 -4
  361. package/scripts/session-summary.mjs +6 -1
  362. package/scripts/setup-claude-md.sh +4 -2
  363. package/scripts/setup-progress.sh +4 -1
  364. package/scripts/skill-injector.mjs +2 -1
  365. package/scripts/sync-version.sh +3 -3
  366. package/scripts/test-pr25.sh +9 -5
  367. package/scripts/uninstall.sh +5 -2
  368. package/scripts/wiki-pre-compact.mjs +17 -0
  369. package/scripts/wiki-session-end.mjs +17 -0
  370. package/scripts/wiki-session-start.mjs +17 -0
  371. package/skills/cancel/SKILL.md +4 -4
  372. package/skills/configure-notifications/SKILL.md +12 -12
  373. package/skills/hud/SKILL.md +4 -4
  374. package/skills/learner/SKILL.md +1 -1
  375. package/skills/omc-doctor/SKILL.md +25 -25
  376. package/skills/omc-setup/SKILL.md +1 -1
  377. package/skills/omc-setup/phases/02-configure.md +2 -2
  378. package/skills/omc-setup/phases/03-integrations.md +7 -7
  379. package/skills/omc-setup/phases/04-welcome.md +3 -3
  380. package/skills/ralph/SKILL.md +6 -2
  381. package/skills/skill/SKILL.md +9 -9
  382. package/skills/team/SKILL.md +1 -1
  383. package/skills/wiki/SKILL.md +67 -0
  384. package/templates/hooks/keyword-detector.mjs +4 -2
  385. package/templates/hooks/lib/config-dir.mjs +29 -0
  386. package/templates/hooks/persistent-mode.mjs +24 -4
  387. package/templates/hooks/session-start.mjs +7 -4
package/docs/CLAUDE.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- OMC:START -->
2
- <!-- OMC:VERSION:4.10.3 -->
2
+ <!-- OMC:VERSION:4.11.0 -->
3
3
 
4
4
  # oh-my-claudecode - Intelligent Multi-Agent Orchestration
5
5
 
package/hooks/hooks.json CHANGED
@@ -31,6 +31,11 @@
31
31
  "type": "command",
32
32
  "command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/project-memory-session.mjs",
33
33
  "timeout": 5
34
+ },
35
+ {
36
+ "type": "command",
37
+ "command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/wiki-session-start.mjs",
38
+ "timeout": 5
34
39
  }
35
40
  ]
36
41
  },
@@ -150,6 +155,11 @@
150
155
  "type": "command",
151
156
  "command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/project-memory-precompact.mjs",
152
157
  "timeout": 5
158
+ },
159
+ {
160
+ "type": "command",
161
+ "command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/wiki-pre-compact.mjs",
162
+ "timeout": 3
153
163
  }
154
164
  ]
155
165
  }
@@ -184,6 +194,11 @@
184
194
  "type": "command",
185
195
  "command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/session-end.mjs",
186
196
  "timeout": 30
197
+ },
198
+ {
199
+ "type": "command",
200
+ "command": "node \"$CLAUDE_PLUGIN_ROOT\"/scripts/run.cjs \"$CLAUDE_PLUGIN_ROOT\"/scripts/wiki-session-end.mjs",
201
+ "timeout": 30
187
202
  }
188
203
  ]
189
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stanco323/oh-my-claude-code",
3
- "version": "4.10.3",
3
+ "version": "4.11.0",
4
4
  "description": "Multi-agent orchestration system for Claude Code - Inspired by oh-my-opencode",
5
5
  "keywords": [
6
6
  "claude",
@@ -24,7 +24,7 @@
24
24
  import { existsSync } from 'node:fs';
25
25
  import { execSync } from 'node:child_process';
26
26
  import { join } from 'node:path';
27
- import { homedir } from 'node:os';
27
+ import { getClaudeConfigDir } from './lib/config-dir.mjs';
28
28
 
29
29
  const args = process.argv.slice(2);
30
30
  const teamNameIdx = args.indexOf('--team-name');
@@ -124,7 +124,7 @@ function getWindowsProcessListOutput() {
124
124
  * Check if a team's config still exists (i.e., team is still active).
125
125
  */
126
126
  function teamConfigExists(name) {
127
- const configDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
127
+ const configDir = getClaudeConfigDir();
128
128
  const configPath = join(configDir, 'teams', name, 'config.json');
129
129
  return existsSync(configPath);
130
130
  }
@@ -21,8 +21,9 @@
21
21
 
22
22
  import { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, openSync, readSync, closeSync } from 'node:fs';
23
23
  import { join, dirname, resolve } from 'node:path';
24
- import { tmpdir, homedir } from 'node:os';
24
+ import { tmpdir } from 'node:os';
25
25
  import { execSync } from 'node:child_process';
26
+ import { getClaudeConfigDir } from './lib/config-dir.mjs';
26
27
  import { readStdin } from './lib/stdin.mjs';
27
28
 
28
29
  const THRESHOLD = parseInt(process.env.OMC_CONTEXT_GUARD_THRESHOLD || '75', 10);
@@ -114,7 +115,7 @@ function resolveTranscriptPath(transcriptPath, cwd) {
114
115
  const lastSep = transcriptPath.lastIndexOf('/');
115
116
  const sessionFile = lastSep !== -1 ? transcriptPath.substring(lastSep + 1) : '';
116
117
  if (sessionFile) {
117
- const configDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
118
+ const configDir = getClaudeConfigDir();
118
119
  const projectsDir = join(configDir, 'projects');
119
120
  if (existsSync(projectsDir)) {
120
121
  const encodedMain = mainRepoRoot.replace(/[/\\]/g, '-');
@@ -173,9 +174,14 @@ function estimateContextPercent(transcriptPath) {
173
174
  * Prevents infinite block loops by capping at MAX_BLOCKS.
174
175
  */
175
176
  function getGuardFilePath(sessionId) {
176
- const configDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
177
+ const configDir = getClaudeConfigDir();
177
178
  const guardDir = join(configDir, 'projects', '.omc-guards');
178
- mkdirSync(guardDir, { recursive: true, mode: 0o700 });
179
+ try {
180
+ mkdirSync(guardDir, { recursive: true, mode: 0o700 });
181
+ } catch (err) {
182
+ // On Windows, concurrent hooks can throw EEXIST even with recursive:true
183
+ if (err?.code !== 'EEXIST') throw err;
184
+ }
179
185
  return join(guardDir, `context-guard-${sessionId}.json`);
180
186
  }
181
187
 
@@ -16,10 +16,22 @@
16
16
 
17
17
  NODE_BIN=""
18
18
 
19
+ case "$0" in
20
+ */*)
21
+ SCRIPT_DIR="${0%/*}"
22
+ ;;
23
+ *)
24
+ SCRIPT_DIR='.'
25
+ ;;
26
+ esac
27
+
28
+ SCRIPT_DIR="$(cd "$SCRIPT_DIR" && pwd)"
29
+ . "$SCRIPT_DIR/lib/config-dir.sh"
30
+
19
31
  # ---------------------------------------------------------------------------
20
32
  # 1. Read stored node path from OMC config
21
33
  # ---------------------------------------------------------------------------
22
- CLAUDE_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
34
+ CLAUDE_DIR="$(resolve_claude_config_dir)"
23
35
  CONFIG_FILE="$CLAUDE_DIR/.omc-config.json"
24
36
  if [ -f "$CONFIG_FILE" ]; then
25
37
  # POSIX-safe extraction without requiring jq
@@ -27,6 +27,7 @@ import { writeFileSync, readFileSync, mkdirSync, existsSync, unlinkSync } from '
27
27
  import { join, dirname } from 'path';
28
28
  import { homedir } from 'os';
29
29
  import { fileURLToPath } from 'url';
30
+ import { getClaudeConfigDir } from './lib/config-dir.mjs';
30
31
  import { readStdin } from './lib/stdin.mjs';
31
32
 
32
33
  // Resolve OMC package root: CLAUDE_PLUGIN_ROOT (plugin system) or derive from this script's location
@@ -309,13 +310,14 @@ function linkRalphTeam(directory, sessionId) {
309
310
 
310
311
  /**
311
312
  * Check if the team feature is enabled in Claude Code settings.
312
- * Reads ~/.claude/settings.json and checks for CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS env var.
313
+ * Reads settings.json from [$CLAUDE_CONFIG_DIR|~/.claude] and checks for
314
+ * CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS env var.
313
315
  * @returns {boolean} true if team feature is enabled
314
316
  */
315
317
  function isTeamEnabled() {
316
318
  try {
317
319
  // Check settings.json first (authoritative, user-controlled)
318
- const cfgDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
320
+ const cfgDir = getClaudeConfigDir();
319
321
  const settingsPath = join(cfgDir, 'settings.json');
320
322
  if (existsSync(settingsPath)) {
321
323
  const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
@@ -565,6 +567,11 @@ async function main() {
565
567
  matches.push({ name: 'analyze', args: '' });
566
568
  }
567
569
 
570
+ // Wiki keywords
571
+ if (hasActionableKeyword(cleanPrompt, /\b(wiki(?:\s+(?:this|add|lint|query))?)\b/i)) {
572
+ matches.push({ name: 'wiki', args: '' });
573
+ }
574
+
568
575
  // No matches - pass through
569
576
  if (matches.length === 0) {
570
577
  console.log(JSON.stringify({ continue: true, suppressOutput: true }));
@@ -0,0 +1,31 @@
1
+ const { homedir } = require('node:os');
2
+ const { join, normalize, parse, sep } = require('node:path');
3
+
4
+ function stripTrailingSep(p) {
5
+ if (!p.endsWith(sep)) {
6
+ return p;
7
+ }
8
+
9
+ return p === parse(p).root ? p : p.slice(0, -1);
10
+ }
11
+
12
+ function getClaudeConfigDir() {
13
+ const home = homedir();
14
+ const configured = process.env.CLAUDE_CONFIG_DIR?.trim();
15
+
16
+ if (!configured) {
17
+ return stripTrailingSep(normalize(join(home, '.claude')));
18
+ }
19
+
20
+ if (configured === '~') {
21
+ return stripTrailingSep(normalize(home));
22
+ }
23
+
24
+ if (configured.startsWith('~/') || configured.startsWith('~\\')) {
25
+ return stripTrailingSep(normalize(join(home, configured.slice(2))));
26
+ }
27
+
28
+ return stripTrailingSep(normalize(configured));
29
+ }
30
+
31
+ module.exports = { getClaudeConfigDir };
@@ -0,0 +1,29 @@
1
+ import { homedir } from 'node:os';
2
+ import { join, normalize, parse, sep } from 'node:path';
3
+
4
+ function stripTrailingSep(p) {
5
+ if (!p.endsWith(sep)) {
6
+ return p;
7
+ }
8
+
9
+ return p === parse(p).root ? p : p.slice(0, -1);
10
+ }
11
+
12
+ export function getClaudeConfigDir() {
13
+ const home = homedir();
14
+ const configured = process.env.CLAUDE_CONFIG_DIR?.trim();
15
+
16
+ if (!configured) {
17
+ return stripTrailingSep(normalize(join(home, '.claude')));
18
+ }
19
+
20
+ if (configured === '~') {
21
+ return stripTrailingSep(normalize(home));
22
+ }
23
+
24
+ if (configured.startsWith('~/') || configured.startsWith('~\\')) {
25
+ return stripTrailingSep(normalize(join(home, configured.slice(2))));
26
+ }
27
+
28
+ return stripTrailingSep(normalize(configured));
29
+ }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env sh
2
+
3
+ resolve_claude_config_dir() {
4
+ configured="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
5
+ configured="${configured%/}"
6
+ case "$configured" in
7
+ \~)
8
+ printf '%s\n' "$HOME"
9
+ ;;
10
+ \~/*)
11
+ configured="${configured#\~/}"
12
+ printf '%s/%s\n' "$HOME" "$configured"
13
+ ;;
14
+ *)
15
+ printf '%s\n' "$configured"
16
+ ;;
17
+ esac
18
+ }
@@ -0,0 +1,63 @@
1
+ import { closeSync, openSync, readSync, statSync } from 'fs';
2
+
3
+ const AGENT_HEAVY_TOOLS = new Set(['Task', 'TaskCreate', 'TaskUpdate']);
4
+ const DEFAULT_PREFLIGHT_CONTEXT_THRESHOLD = 72;
5
+
6
+ export function getPreflightContextThreshold(env = process.env) {
7
+ const parsed = Number.parseInt(env.OMC_AGENT_PREFLIGHT_CONTEXT_THRESHOLD || '72', 10);
8
+ if (Number.isNaN(parsed)) return DEFAULT_PREFLIGHT_CONTEXT_THRESHOLD;
9
+ return Math.max(1, Math.min(100, parsed));
10
+ }
11
+
12
+ export function estimateContextPercent(transcriptPath) {
13
+ if (!transcriptPath) return 0;
14
+
15
+ let fd = -1;
16
+ try {
17
+ const stat = statSync(transcriptPath);
18
+ if (stat.size === 0) return 0;
19
+
20
+ fd = openSync(transcriptPath, 'r');
21
+ const readSize = Math.min(4096, stat.size);
22
+ const buf = Buffer.alloc(readSize);
23
+ readSync(fd, buf, 0, readSize, stat.size - readSize);
24
+ closeSync(fd);
25
+ fd = -1;
26
+
27
+ const tail = buf.toString('utf-8');
28
+ const windowMatch = tail.match(/"context_window"\s{0,5}:\s{0,5}(\d+)/g);
29
+ const inputMatch = tail.match(/"input_tokens"\s{0,5}:\s{0,5}(\d+)/g);
30
+
31
+ if (!windowMatch || !inputMatch) return 0;
32
+
33
+ const lastWindow = parseInt(windowMatch[windowMatch.length - 1].match(/(\d+)/)[1], 10);
34
+ const lastInput = parseInt(inputMatch[inputMatch.length - 1].match(/(\d+)/)[1], 10);
35
+
36
+ if (lastWindow === 0) return 0;
37
+ return Math.round((lastInput / lastWindow) * 100);
38
+ } catch {
39
+ return 0;
40
+ } finally {
41
+ if (fd !== -1) try { closeSync(fd); } catch { /* ignore */ }
42
+ }
43
+ }
44
+
45
+ export function buildPreflightRecoveryAdvice(contextPercent, threshold = DEFAULT_PREFLIGHT_CONTEXT_THRESHOLD) {
46
+ return `[OMC] Preflight context guard: ${contextPercent}% used ` +
47
+ `(threshold: ${threshold}%). Avoid spawning additional agent-heavy tasks ` +
48
+ `until context is reduced. Safe recovery: (1) pause new Task fan-out, (2) run /compact now, ` +
49
+ `(3) if compact fails, open a fresh session and continue from .omc/state + .omc/notepad.md.`;
50
+ }
51
+
52
+ export function evaluateAgentHeavyPreflight({ toolName, transcriptPath, env = process.env }) {
53
+ if (!AGENT_HEAVY_TOOLS.has(toolName)) return null;
54
+
55
+ const threshold = getPreflightContextThreshold(env);
56
+ const contextPercent = estimateContextPercent(transcriptPath);
57
+ if (contextPercent < threshold) return null;
58
+
59
+ return {
60
+ decision: 'block',
61
+ reason: buildPreflightRecoveryAdvice(contextPercent, threshold),
62
+ };
63
+ }
@@ -22,7 +22,7 @@ const {
22
22
  statSync,
23
23
  } = require("fs");
24
24
  const { join, dirname, resolve, normalize } = require("path");
25
- const { homedir } = require("os");
25
+ const { getClaudeConfigDir } = require("./lib/config-dir.cjs");
26
26
 
27
27
  async function readStdin(timeoutMs = 2000) {
28
28
  return new Promise((resolve) => {
@@ -208,8 +208,28 @@ function getSafeReinforcementCount(value) {
208
208
  : 0;
209
209
  }
210
210
 
211
+ const AWAITING_CONFIRMATION_TTL_MS = 2 * 60 * 1000;
212
+
211
213
  function isAwaitingConfirmation(state) {
212
- return state?.awaiting_confirmation === true;
214
+ if (!state || state.awaiting_confirmation !== true) {
215
+ return false;
216
+ }
217
+
218
+ const setAt =
219
+ state.awaiting_confirmation_set_at ||
220
+ state.started_at ||
221
+ null;
222
+
223
+ if (!setAt) {
224
+ return false;
225
+ }
226
+
227
+ const setAtMs = new Date(setAt).getTime();
228
+ if (!Number.isFinite(setAtMs)) {
229
+ return false;
230
+ }
231
+
232
+ return Date.now() - setAtMs < AWAITING_CONFIRMATION_TTL_MS;
213
233
  }
214
234
 
215
235
  // ---------------------------------------------------------------------------
@@ -413,7 +433,7 @@ function countIncompleteTasks(sessionId) {
413
433
  if (!sessionId || typeof sessionId !== "string") return 0;
414
434
  if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId)) return 0;
415
435
 
416
- const cfgDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
436
+ const cfgDir = getClaudeConfigDir();
417
437
  const taskDir = join(cfgDir, "tasks", sessionId);
418
438
  if (!existsSync(taskDir)) return 0;
419
439
 
@@ -447,8 +467,7 @@ function countIncompleteTodos(sessionId, projectDir) {
447
467
  /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId)
448
468
  ) {
449
469
  const sessionTodoPath = join(
450
- homedir(),
451
- ".claude",
470
+ getClaudeConfigDir(),
452
471
  "todos",
453
472
  `${sessionId}.json`,
454
473
  );
@@ -529,14 +548,16 @@ const CRITICAL_CONTEXT_STOP_PERCENT = 95;
529
548
  function estimateContextPercent(transcriptPath) {
530
549
  if (!transcriptPath || !existsSync(transcriptPath)) return 0;
531
550
 
551
+ let fd = -1;
532
552
  try {
533
553
  const size = statSync(transcriptPath).size;
534
554
  const readSize = 4096;
535
555
  const offset = Math.max(0, size - readSize);
536
556
  const buf = Buffer.alloc(Math.min(readSize, size));
537
- const fd = openSync(transcriptPath, "r");
557
+ fd = openSync(transcriptPath, "r");
538
558
  readSync(fd, buf, 0, buf.length, offset);
539
559
  closeSync(fd);
560
+ fd = -1;
540
561
  const content = buf.toString("utf-8");
541
562
 
542
563
  const windowMatch = content.match(/"context_window"\s{0,5}:\s{0,5}(\d+)/g);
@@ -549,6 +570,8 @@ function estimateContextPercent(transcriptPath) {
549
570
  return Math.round((lastInput / lastWindow) * 100);
550
571
  } catch {
551
572
  return 0;
573
+ } finally {
574
+ if (fd !== -1) try { closeSync(fd); } catch { /* best-effort */ }
552
575
  }
553
576
  }
554
577
 
@@ -24,6 +24,7 @@ import {
24
24
  import { join, dirname, resolve, normalize } from "path";
25
25
  import { homedir } from "os";
26
26
  import { fileURLToPath, pathToFileURL } from "url";
27
+ import { getClaudeConfigDir } from "./lib/config-dir.mjs";
27
28
 
28
29
  const __filename = fileURLToPath(import.meta.url);
29
30
  const __dirname = dirname(__filename);
@@ -242,8 +243,28 @@ function getSafeReinforcementCount(value) {
242
243
  : 0;
243
244
  }
244
245
 
246
+ const AWAITING_CONFIRMATION_TTL_MS = 2 * 60 * 1000;
247
+
245
248
  function isAwaitingConfirmation(state) {
246
- return state?.awaiting_confirmation === true;
249
+ if (!state || state.awaiting_confirmation !== true) {
250
+ return false;
251
+ }
252
+
253
+ const setAt =
254
+ state.awaiting_confirmation_set_at ||
255
+ state.started_at ||
256
+ null;
257
+
258
+ if (!setAt) {
259
+ return false;
260
+ }
261
+
262
+ const setAtMs = new Date(setAt).getTime();
263
+ if (!Number.isFinite(setAtMs)) {
264
+ return false;
265
+ }
266
+
267
+ return Date.now() - setAtMs < AWAITING_CONFIRMATION_TTL_MS;
247
268
  }
248
269
 
249
270
  /**
@@ -398,7 +419,7 @@ function countIncompleteTasks(sessionId) {
398
419
  if (!sessionId || typeof sessionId !== "string") return 0;
399
420
  if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId)) return 0;
400
421
 
401
- const cfgDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
422
+ const cfgDir = getClaudeConfigDir();
402
423
  const taskDir = join(cfgDir, "tasks", sessionId);
403
424
  if (!existsSync(taskDir)) return 0;
404
425
 
@@ -432,8 +453,7 @@ function countIncompleteTodos(sessionId, projectDir) {
432
453
  /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/.test(sessionId)
433
454
  ) {
434
455
  const sessionTodoPath = join(
435
- homedir(),
436
- ".claude",
456
+ getClaudeConfigDir(),
437
457
  "todos",
438
458
  `${sessionId}.json`,
439
459
  );
@@ -5,19 +5,24 @@
5
5
  * Configures HUD statusline when plugin is installed.
6
6
  */
7
7
 
8
- import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, chmodSync } from 'node:fs';
8
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, chmodSync, copyFileSync } from 'node:fs';
9
9
  import { execFileSync, execSync } from 'node:child_process';
10
10
  import { createRequire } from 'node:module';
11
11
  import { homedir } from 'node:os';
12
12
  import { join, dirname, resolve } from 'node:path';
13
13
  import { fileURLToPath, pathToFileURL } from 'node:url';
14
+ import { getClaudeConfigDir } from './lib/config-dir.mjs';
14
15
 
15
16
  const __filename = fileURLToPath(import.meta.url);
16
17
  const __dirname = dirname(__filename);
17
18
 
18
- const CLAUDE_DIR = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
19
+ const CLAUDE_DIR = getClaudeConfigDir();
19
20
  const HUD_DIR = join(CLAUDE_DIR, 'hud');
21
+ const HUD_LIB_DIR = join(HUD_DIR, 'lib');
20
22
  const SETTINGS_FILE = join(CLAUDE_DIR, 'settings.json');
23
+ // Use the absolute node binary path so nvm/fnm users don't get
24
+ // "node not found" errors in non-interactive shells (issue #892).
25
+ const nodeBin = process.execPath || 'node';
21
26
 
22
27
  console.log('[OMC] Running post-install setup...');
23
28
 
@@ -26,6 +31,11 @@ if (!existsSync(HUD_DIR)) {
26
31
  mkdirSync(HUD_DIR, { recursive: true });
27
32
  }
28
33
 
34
+ if (!existsSync(HUD_LIB_DIR)) {
35
+ mkdirSync(HUD_LIB_DIR, { recursive: true });
36
+ }
37
+ copyFileSync(join(__dirname, 'lib', 'config-dir.mjs'), join(HUD_LIB_DIR, 'config-dir.mjs'));
38
+
29
39
  // 2. Create HUD wrapper script
30
40
  const hudScriptPath = join(HUD_DIR, 'omc-hud.mjs').replace(/\\/g, '/');
31
41
  const hudScript = `#!/usr/bin/env node
@@ -39,7 +49,11 @@ import { existsSync, readdirSync } from "node:fs";
39
49
  import { createRequire } from "node:module";
40
50
  import { homedir } from "node:os";
41
51
  import { dirname, join, resolve } from "node:path";
42
- import { pathToFileURL } from "node:url";
52
+ import { fileURLToPath, pathToFileURL } from "node:url";
53
+
54
+ const __filename = fileURLToPath(import.meta.url);
55
+ const __dirname = dirname(__filename);
56
+ const { getClaudeConfigDir } = await import(pathToFileURL(join(__dirname, "lib", "config-dir.mjs")).href);
43
57
 
44
58
  // Semantic version comparison: returns negative if a < b, positive if a > b, 0 if equal
45
59
  function semverCompare(a, b) {
@@ -133,7 +147,7 @@ async function main() {
133
147
 
134
148
  // 1. Try plugin cache first (marketplace: omc, plugin: oh-my-claudecode)
135
149
  // Respect CLAUDE_CONFIG_DIR so installs under a custom config dir are found
136
- const configDir = process.env.CLAUDE_CONFIG_DIR || join(home, ".claude");
150
+ const configDir = getClaudeConfigDir();
137
151
  const pluginCacheBase = join(configDir, "plugins", "cache", "omc", "oh-my-claudecode");
138
152
  if (existsSync(pluginCacheBase)) {
139
153
  try {
@@ -224,9 +238,6 @@ try {
224
238
  settings = JSON.parse(readFileSync(SETTINGS_FILE, 'utf-8'));
225
239
  }
226
240
 
227
- // Use the absolute node binary path so nvm/fnm users don't get
228
- // "node not found" errors in non-interactive shells (issue #892).
229
- const nodeBin = process.execPath || 'node';
230
241
  settings.statusLine = {
231
242
  type: 'command',
232
243
  command: `"${nodeBin}" "${hudScriptPath.replace(/\\/g, "/")}"`