@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
@@ -6,14 +6,23 @@
6
6
  * Cross-platform: Windows, macOS, Linux
7
7
  */
8
8
 
9
+ import { execSync } from 'child_process';
10
+ import { createHash } from 'crypto';
9
11
  import { existsSync, readFileSync, writeFileSync, mkdirSync, appendFileSync, renameSync, unlinkSync } from 'fs';
10
- import { join, dirname } from 'path';
11
- import { homedir } from 'os';
12
+ import { closeSync, openSync, readSync, statSync } from 'fs';
13
+ import { basename, join, dirname, resolve } from 'path';
14
+ import { homedir, tmpdir } from 'os';
12
15
  import { fileURLToPath, pathToFileURL } from 'url';
16
+ import { getClaudeConfigDir } from './lib/config-dir.mjs';
13
17
  import { readStdin } from './lib/stdin.mjs';
14
18
 
15
19
  const AGENT_OUTPUT_ANALYSIS_LIMIT = parseInt(process.env.OMC_AGENT_OUTPUT_ANALYSIS_LIMIT || '12000', 10);
16
20
  const AGENT_OUTPUT_SUMMARY_LIMIT = parseInt(process.env.OMC_AGENT_OUTPUT_SUMMARY_LIMIT || '360', 10);
21
+ const PREEMPTIVE_WARNING_THRESHOLD_PERCENT = parseInt(process.env.OMC_PREEMPTIVE_COMPACTION_WARNING_PERCENT || '70', 10);
22
+ const PREEMPTIVE_CRITICAL_THRESHOLD_PERCENT = parseInt(process.env.OMC_PREEMPTIVE_COMPACTION_CRITICAL_PERCENT || '90', 10);
23
+ const PREEMPTIVE_COOLDOWN_MS = parseInt(process.env.OMC_PREEMPTIVE_COMPACTION_COOLDOWN_MS || '60000', 10);
24
+ const PREEMPTIVE_TRANSCRIPT_TAIL_BYTES = 4096;
25
+ const PREEMPTIVE_LARGE_OUTPUT_TOOLS = new Set(['read', 'grep', 'glob', 'bash', 'webfetch', 'task', 'taskcreate', 'taskupdate', 'taskoutput']);
17
26
  const QUIET_LEVEL = getQuietLevel();
18
27
  const SESSION_ID_ALLOWLIST = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,255}$/;
19
28
 
@@ -23,6 +32,19 @@ function getQuietLevel() {
23
32
  return Math.max(0, parsed);
24
33
  }
25
34
 
35
+ function clampPercent(percent, fallback) {
36
+ if (!Number.isFinite(percent)) return fallback;
37
+ return Math.min(100, Math.max(1, percent));
38
+ }
39
+
40
+ function getPreemptiveWarningThreshold() {
41
+ return clampPercent(PREEMPTIVE_WARNING_THRESHOLD_PERCENT, 70);
42
+ }
43
+
44
+ function getPreemptiveCriticalThreshold() {
45
+ return clampPercent(PREEMPTIVE_CRITICAL_THRESHOLD_PERCENT, 90);
46
+ }
47
+
26
48
  // Get the directory of this script to resolve the dist module
27
49
  const __filename = fileURLToPath(import.meta.url);
28
50
  const __dirname = dirname(__filename);
@@ -45,7 +67,7 @@ const debugLog = (...args) => {
45
67
  };
46
68
 
47
69
  // State file for session tracking
48
- const cfgDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
70
+ const cfgDir = getClaudeConfigDir();
49
71
  const STATE_FILE = join(cfgDir, '.session-stats.json');
50
72
 
51
73
  // Ensure state directory exists
@@ -217,6 +239,170 @@ function detectBackgroundOperation(output) {
217
239
  return bgPatterns.some(pattern => pattern.test(output));
218
240
  }
219
241
 
242
+ function resolveTranscriptPath(transcriptPath, cwd) {
243
+ if (!transcriptPath) return undefined;
244
+
245
+ try {
246
+ if (existsSync(transcriptPath)) return transcriptPath;
247
+ } catch {}
248
+
249
+ const worktreePattern = /--claude-worktrees-[^/\\]+/;
250
+ if (worktreePattern.test(transcriptPath)) {
251
+ const resolvedPath = transcriptPath.replace(worktreePattern, '');
252
+ try {
253
+ if (existsSync(resolvedPath)) return resolvedPath;
254
+ } catch {}
255
+ }
256
+
257
+ const effectiveCwd = cwd || process.cwd();
258
+ try {
259
+ const gitCommonDir = execSync('git rev-parse --git-common-dir', {
260
+ cwd: effectiveCwd,
261
+ encoding: 'utf-8',
262
+ stdio: ['pipe', 'pipe', 'pipe'],
263
+ }).trim();
264
+
265
+ const mainRepoRoot = dirname(resolve(effectiveCwd, gitCommonDir));
266
+ const worktreeTop = execSync('git rev-parse --show-toplevel', {
267
+ cwd: effectiveCwd,
268
+ encoding: 'utf-8',
269
+ stdio: ['pipe', 'pipe', 'pipe'],
270
+ }).trim();
271
+
272
+ if (mainRepoRoot !== worktreeTop) {
273
+ const sessionFile = basename(transcriptPath);
274
+ if (sessionFile) {
275
+ const projectsDir = join(getClaudeConfigDir(), 'projects');
276
+ if (existsSync(projectsDir)) {
277
+ const encodedMain = mainRepoRoot.replace(/[/\\]/g, '-');
278
+ const resolvedPath = join(projectsDir, encodedMain, sessionFile);
279
+ if (existsSync(resolvedPath)) return resolvedPath;
280
+ }
281
+ }
282
+ }
283
+ } catch {}
284
+
285
+ return transcriptPath;
286
+ }
287
+
288
+ function readTranscriptUsage(transcriptPath) {
289
+ if (!transcriptPath) return null;
290
+
291
+ let fd = -1;
292
+ try {
293
+ const stat = statSync(transcriptPath);
294
+ if (stat.size === 0) return null;
295
+
296
+ fd = openSync(transcriptPath, 'r');
297
+ const readSize = Math.min(PREEMPTIVE_TRANSCRIPT_TAIL_BYTES, stat.size);
298
+ const buffer = Buffer.alloc(readSize);
299
+ readSync(fd, buffer, 0, readSize, stat.size - readSize);
300
+ closeSync(fd);
301
+ fd = -1;
302
+
303
+ const tail = buffer.toString('utf-8');
304
+ const windowMatches = tail.match(/"context_window"\s{0,5}:\s{0,5}(\d+)/g);
305
+ const inputMatches = tail.match(/"input_tokens"\s{0,5}:\s{0,5}(\d+)/g);
306
+ if (!windowMatches || !inputMatches) return null;
307
+
308
+ const lastWindow = Number.parseInt(
309
+ windowMatches[windowMatches.length - 1].match(/(\d+)/)?.[1] || '0',
310
+ 10,
311
+ );
312
+ const lastInput = Number.parseInt(
313
+ inputMatches[inputMatches.length - 1].match(/(\d+)/)?.[1] || '0',
314
+ 10,
315
+ );
316
+ if (!Number.isFinite(lastWindow) || lastWindow <= 0) return null;
317
+ if (!Number.isFinite(lastInput) || lastInput < 0) return null;
318
+
319
+ return Math.round((lastInput / lastWindow) * 100);
320
+ } catch {
321
+ return null;
322
+ } finally {
323
+ if (fd !== -1) {
324
+ try { closeSync(fd); } catch {}
325
+ }
326
+ }
327
+ }
328
+
329
+ function getPreemptiveCooldownFilePath(directory, sessionId) {
330
+ const cooldownScope =
331
+ sessionId && sessionId !== 'unknown'
332
+ ? `${directory || process.cwd()}::${sessionId}`
333
+ : directory || process.cwd();
334
+ const hash = createHash('sha1').update(cooldownScope).digest('hex');
335
+ const cooldownDir = join(tmpdir(), 'omc-preemptive-compaction');
336
+ mkdirSync(cooldownDir, { recursive: true });
337
+ return join(cooldownDir, `${hash}.json`);
338
+ }
339
+
340
+ function readPreemptiveCooldownState(directory, sessionId) {
341
+ try {
342
+ const filePath = getPreemptiveCooldownFilePath(directory, sessionId);
343
+ if (!existsSync(filePath)) return null;
344
+ const data = JSON.parse(readFileSync(filePath, 'utf-8'));
345
+ if (!data || typeof data !== 'object') return null;
346
+ return {
347
+ lastWarningTime:
348
+ typeof data.lastWarningTime === 'number' ? data.lastWarningTime : 0,
349
+ severity: data.severity === 'critical' ? 'critical' : 'warning',
350
+ };
351
+ } catch {
352
+ return null;
353
+ }
354
+ }
355
+
356
+ function writePreemptiveCooldownState(directory, sessionId, severity, now) {
357
+ writeFileSync(
358
+ getPreemptiveCooldownFilePath(directory, sessionId),
359
+ JSON.stringify({ lastWarningTime: now, severity }),
360
+ { mode: 0o600 },
361
+ );
362
+ }
363
+
364
+ function shouldSuppressPreemptiveWarning(directory, sessionId, severity, now) {
365
+ const cooldownState = readPreemptiveCooldownState(directory, sessionId);
366
+ if (!cooldownState) return false;
367
+ if (now - cooldownState.lastWarningTime >= PREEMPTIVE_COOLDOWN_MS) return false;
368
+ return !(cooldownState.severity === 'warning' && severity === 'critical');
369
+ }
370
+
371
+ function buildPreemptiveContextMessage(percentUsed, severity) {
372
+ if (severity === 'critical') {
373
+ return `[OMC CRITICAL] Context at ${percentUsed}% (critical threshold: ${getPreemptiveCriticalThreshold()}%). Run /compact now before continuing with more tools or agent fan-out.`;
374
+ }
375
+
376
+ return `[OMC WARNING] Context at ${percentUsed}% (warning threshold: ${getPreemptiveWarningThreshold()}%). Plan a /compact soon to preserve room for the next large tool output.`;
377
+ }
378
+
379
+ function maybeBuildPreemptiveCompactionMessage(toolName, data, directory) {
380
+ if (!PREEMPTIVE_LARGE_OUTPUT_TOOLS.has(String(toolName || '').toLowerCase())) {
381
+ return '';
382
+ }
383
+
384
+ const percentUsed = readTranscriptUsage(
385
+ resolveTranscriptPath(data.transcript_path || data.transcriptPath, directory),
386
+ );
387
+ const warningThreshold = getPreemptiveWarningThreshold();
388
+ const criticalThreshold = getPreemptiveCriticalThreshold();
389
+
390
+ if (percentUsed === null || percentUsed < warningThreshold) {
391
+ return '';
392
+ }
393
+
394
+ const severity = percentUsed >= criticalThreshold ? 'critical' : 'warning';
395
+ const now = Date.now();
396
+ const sessionId = data.session_id || data.sessionId || 'unknown';
397
+
398
+ if (shouldSuppressPreemptiveWarning(directory, sessionId, severity, now)) {
399
+ return '';
400
+ }
401
+
402
+ writePreemptiveCooldownState(directory, sessionId, severity, now);
403
+ return buildPreemptiveContextMessage(percentUsed, severity);
404
+ }
405
+
220
406
  function getInvokedSkillName(toolInput) {
221
407
  if (!toolInput || typeof toolInput !== 'object') return null;
222
408
  const rawSkill =
@@ -477,6 +663,10 @@ function generateMessage(toolName, toolOutput, sessionId, toolCount, directory,
477
663
  return message;
478
664
  }
479
665
 
666
+ function combineMessages(...messages) {
667
+ return messages.filter(Boolean).join(' | ');
668
+ }
669
+
480
670
  async function main() {
481
671
  // Skip guard: check OMC_SKIP_HOOKS env var (see issue #838)
482
672
  const _skipHooks = (process.env.OMC_SKIP_HOOKS || '').split(',').map(s => s.trim());
@@ -528,10 +718,13 @@ async function main() {
528
718
  }
529
719
 
530
720
  // Generate contextual message
531
- const message = generateMessage(toolName, clippedToolOutput, sessionId, toolCount, directory, {
532
- wasTruncated,
533
- rawLength: toolOutput.length,
534
- });
721
+ const message = combineMessages(
722
+ generateMessage(toolName, clippedToolOutput, sessionId, toolCount, directory, {
723
+ wasTruncated,
724
+ rawLength: toolOutput.length,
725
+ }),
726
+ maybeBuildPreemptiveCompactionMessage(toolName, data, directory),
727
+ );
535
728
 
536
729
  // Build response - use hookSpecificOutput.additionalContext for PostToolUse
537
730
  const response = { continue: true };
@@ -6,11 +6,12 @@
6
6
  * Cross-platform: Windows, macOS, Linux
7
7
  */
8
8
 
9
- import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, renameSync, statSync, writeFileSync } from 'fs';
9
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
10
10
  import { dirname, join, resolve } from 'path';
11
11
  import { execSync } from 'child_process';
12
- import { homedir } from 'os';
13
12
  import { fileURLToPath, pathToFileURL } from 'url';
13
+ import { getClaudeConfigDir } from './lib/config-dir.mjs';
14
+ import { evaluateAgentHeavyPreflight } from './lib/pre-tool-enforcer-preflight.mjs';
14
15
  import { readStdin } from './lib/stdin.mjs';
15
16
 
16
17
  // Inlined from src/config/models.ts — avoids a dist/ import so the hook works
@@ -90,8 +91,6 @@ const MODE_STATE_FILES = [
90
91
  'team-state.json',
91
92
  'omc-teams-state.json',
92
93
  ];
93
- const AGENT_HEAVY_TOOLS = new Set(['Task', 'TaskCreate', 'TaskUpdate']);
94
- const PREFLIGHT_CONTEXT_THRESHOLD = parseInt(process.env.OMC_AGENT_PREFLIGHT_CONTEXT_THRESHOLD || '72', 10);
95
94
  const QUIET_LEVEL = getQuietLevel();
96
95
 
97
96
  function getQuietLevel() {
@@ -139,7 +138,7 @@ function resolveTranscriptPath(transcriptPath, cwd) {
139
138
  const lastSep = transcriptPath.lastIndexOf('/');
140
139
  const sessionFile = lastSep !== -1 ? transcriptPath.substring(lastSep + 1) : '';
141
140
  if (sessionFile) {
142
- const configDir = process.env.CLAUDE_CONFIG_DIR || join(homedir(), '.claude');
141
+ const configDir = getClaudeConfigDir();
143
142
  const projectsDir = join(configDir, 'projects');
144
143
  if (existsSync(projectsDir)) {
145
144
  const encodedMain = mainRepoRoot.replace(/[/\\]/g, '-');
@@ -155,46 +154,6 @@ function resolveTranscriptPath(transcriptPath, cwd) {
155
154
  return transcriptPath;
156
155
  }
157
156
 
158
- function estimateContextPercent(transcriptPath) {
159
- if (!transcriptPath) return 0;
160
-
161
- let fd = -1;
162
- try {
163
- const stat = statSync(transcriptPath);
164
- if (stat.size === 0) return 0;
165
-
166
- fd = openSync(transcriptPath, 'r');
167
- const readSize = Math.min(4096, stat.size);
168
- const buf = Buffer.alloc(readSize);
169
- readSync(fd, buf, 0, readSize, stat.size - readSize);
170
- closeSync(fd);
171
- fd = -1;
172
-
173
- const tail = buf.toString('utf-8');
174
- const windowMatch = tail.match(/"context_window"\s{0,5}:\s{0,5}(\d+)/g);
175
- const inputMatch = tail.match(/"input_tokens"\s{0,5}:\s{0,5}(\d+)/g);
176
-
177
- if (!windowMatch || !inputMatch) return 0;
178
-
179
- const lastWindow = parseInt(windowMatch[windowMatch.length - 1].match(/(\d+)/)[1], 10);
180
- const lastInput = parseInt(inputMatch[inputMatch.length - 1].match(/(\d+)/)[1], 10);
181
-
182
- if (lastWindow === 0) return 0;
183
- return Math.round((lastInput / lastWindow) * 100);
184
- } catch {
185
- return 0;
186
- } finally {
187
- if (fd !== -1) try { closeSync(fd); } catch { /* ignore */ }
188
- }
189
- }
190
-
191
- function buildPreflightRecoveryAdvice(contextPercent) {
192
- return `[OMC] Preflight context guard: ${contextPercent}% used ` +
193
- `(threshold: ${PREFLIGHT_CONTEXT_THRESHOLD}%). Avoid spawning additional agent-heavy tasks ` +
194
- `until context is reduced. Safe recovery: (1) pause new Task fan-out, (2) run /compact now, ` +
195
- `(3) if compact fails, open a fresh session and continue from .omc/state + .omc/notepad.md.`;
196
- }
197
-
198
157
  // Simple JSON field extraction
199
158
  function extractJsonField(input, field, defaultValue = '') {
200
159
  try {
@@ -247,7 +206,8 @@ function getTodoStatus(directory) {
247
206
  }
248
207
  }
249
208
 
250
- // NOTE: We intentionally do NOT scan the global ~/.claude/todos/ directory.
209
+ // NOTE: We intentionally do NOT scan the global
210
+ // [$CLAUDE_CONFIG_DIR|~/.claude]/todos/ directory.
251
211
  // That directory accumulates todo files from ALL past sessions across all
252
212
  // projects, causing phantom task counts in fresh sessions (see issue #354).
253
213
 
@@ -362,7 +322,7 @@ function generateAgentSpawnMessage(toolInput, directory, todoStatus, sessionId)
362
322
  `Task(team_name="${teamName}", name="worker-N", subagent_type="${agentType}"). ` +
363
323
  `Do NOT use Task without team_name during an active team session. ` +
364
324
  `If TeamCreate is not available in your tools, tell the user to verify ` +
365
- `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set in ~/.claude/settings.json and restart Claude Code.`;
325
+ 'CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set in [$CLAUDE_CONFIG_DIR|~/.claude]/settings.json. Restart Claude Code.';
366
326
  }
367
327
 
368
328
  if (QUIET_LEVEL >= 2) return '';
@@ -455,7 +415,7 @@ function getSkillProtectionLevel(skillName, rawSkillName) {
455
415
  // Load OMC config to check forceInherit setting (issues #1135, #1201)
456
416
  function loadOmcConfig() {
457
417
  const configPaths = [
458
- join(homedir(), '.claude', '.omc-config.json'),
418
+ join(getClaudeConfigDir(), '.omc-config.json'),
459
419
  join(process.cwd(), '.omc', 'config.json'),
460
420
  ];
461
421
  for (const configPath of configPaths) {
@@ -784,16 +744,15 @@ async function main() {
784
744
 
785
745
  const todoStatus = getTodoStatus(directory);
786
746
 
787
- if (AGENT_HEAVY_TOOLS.has(toolName)) {
747
+ if (toolName === 'Task' || toolName === 'TaskCreate' || toolName === 'TaskUpdate') {
788
748
  const rawTranscriptPath = data.transcript_path || data.transcriptPath || '';
789
749
  const transcriptPath = resolveTranscriptPath(rawTranscriptPath, directory);
790
- const contextPercent = estimateContextPercent(transcriptPath);
791
-
792
- if (contextPercent >= PREFLIGHT_CONTEXT_THRESHOLD) {
793
- console.log(JSON.stringify({
794
- decision: 'block',
795
- reason: buildPreflightRecoveryAdvice(contextPercent),
796
- }));
750
+ const preflightBlock = evaluateAgentHeavyPreflight({
751
+ toolName,
752
+ transcriptPath,
753
+ });
754
+ if (preflightBlock) {
755
+ console.log(JSON.stringify(preflightBlock));
797
756
  return;
798
757
  }
799
758
  }