@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/bridge/team.js CHANGED
@@ -1649,9 +1649,31 @@ function getDefaultShell() {
1649
1649
  }
1650
1650
  return shell;
1651
1651
  }
1652
+ function pathEntries(envPath) {
1653
+ return (envPath ?? "").split(process.platform === "win32" ? ";" : ":").map((entry) => entry.trim()).filter(Boolean);
1654
+ }
1655
+ function pathCandidateNames(candidatePath) {
1656
+ const base = basename2(candidatePath.replace(/\\/g, "/"));
1657
+ const bare = base.replace(/\.(exe|cmd|bat)$/i, "");
1658
+ if (process.platform === "win32") {
1659
+ return Array.from(/* @__PURE__ */ new Set([`${bare}.exe`, `${bare}.cmd`, `${bare}.bat`, bare]));
1660
+ }
1661
+ return Array.from(/* @__PURE__ */ new Set([base, bare]));
1662
+ }
1663
+ function resolveShellFromPath(candidatePath) {
1664
+ for (const dir of pathEntries(process.env.PATH)) {
1665
+ for (const name of pathCandidateNames(candidatePath)) {
1666
+ const full = join5(dir, name);
1667
+ if (existsSync5(full)) return full;
1668
+ }
1669
+ }
1670
+ return null;
1671
+ }
1652
1672
  function resolveShellFromCandidates(paths, rcFile) {
1653
1673
  for (const p of paths) {
1654
1674
  if (existsSync5(p)) return { shell: p, rcFile };
1675
+ const resolvedFromPath = resolveShellFromPath(p);
1676
+ if (resolvedFromPath) return { shell: resolvedFromPath, rcFile };
1655
1677
  }
1656
1678
  return null;
1657
1679
  }
@@ -2046,7 +2068,7 @@ function paneLooksReady(captured) {
2046
2068
  }
2047
2069
  async function waitForPaneReady(paneId, opts = {}) {
2048
2070
  const envTimeout = Number.parseInt(process.env.OMC_SHELL_READY_TIMEOUT_MS ?? "", 10);
2049
- const timeoutMs = Number.isFinite(opts.timeoutMs) && (opts.timeoutMs ?? 0) > 0 ? Number(opts.timeoutMs) : Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout : 1e4;
2071
+ const timeoutMs = Number.isFinite(opts.timeoutMs) && (opts.timeoutMs ?? 0) > 0 ? Number(opts.timeoutMs) : Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout : 3e4;
2050
2072
  const pollIntervalMs = Number.isFinite(opts.pollIntervalMs) && (opts.pollIntervalMs ?? 0) > 0 ? Number(opts.pollIntervalMs) : 250;
2051
2073
  const deadline = Date.now() + timeoutMs;
2052
2074
  while (Date.now() < deadline) {
@@ -2163,7 +2185,12 @@ async function sendToWorker(_sessionName, paneId, message) {
2163
2185
  await sendKey("C-m");
2164
2186
  await sleep3(120);
2165
2187
  await sendKey("C-m");
2166
- return true;
2188
+ await sleep3(140);
2189
+ const finalCheckCapture = await capturePaneAsync(paneId, execFileAsync2);
2190
+ if (!finalCheckCapture || finalCheckCapture.trim() === "") {
2191
+ return false;
2192
+ }
2193
+ return !paneTailContainsLiteralLine(finalCheckCapture, message);
2167
2194
  } catch {
2168
2195
  return false;
2169
2196
  }
@@ -2495,6 +2522,8 @@ var init_omc_cli_rendering = __esm({
2495
2522
  });
2496
2523
 
2497
2524
  // src/utils/config-dir.ts
2525
+ import { join as join8, normalize, parse, sep } from "path";
2526
+ import { homedir } from "os";
2498
2527
  var init_config_dir = __esm({
2499
2528
  "src/utils/config-dir.ts"() {
2500
2529
  "use strict";
@@ -2502,45 +2531,45 @@ var init_config_dir = __esm({
2502
2531
  });
2503
2532
 
2504
2533
  // src/utils/paths.ts
2505
- import { join as join8 } from "path";
2534
+ import { join as join9 } from "path";
2506
2535
  import { existsSync as existsSync6, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync, unlinkSync, rmSync } from "fs";
2507
- import { homedir } from "os";
2508
- function getConfigDir2() {
2536
+ import { homedir as homedir2 } from "os";
2537
+ function getConfigDir() {
2509
2538
  if (process.platform === "win32") {
2510
- return process.env.APPDATA || join8(homedir(), "AppData", "Roaming");
2539
+ return process.env.APPDATA || join9(homedir2(), "AppData", "Roaming");
2511
2540
  }
2512
- return process.env.XDG_CONFIG_HOME || join8(homedir(), ".config");
2541
+ return process.env.XDG_CONFIG_HOME || join9(homedir2(), ".config");
2513
2542
  }
2514
2543
  function getStateDir() {
2515
2544
  if (process.platform === "win32") {
2516
- return process.env.LOCALAPPDATA || join8(homedir(), "AppData", "Local");
2545
+ return process.env.LOCALAPPDATA || join9(homedir2(), "AppData", "Local");
2517
2546
  }
2518
- return process.env.XDG_STATE_HOME || join8(homedir(), ".local", "state");
2547
+ return process.env.XDG_STATE_HOME || join9(homedir2(), ".local", "state");
2519
2548
  }
2520
2549
  function prefersXdgOmcDirs() {
2521
2550
  return process.platform !== "win32" && process.platform !== "darwin";
2522
2551
  }
2523
2552
  function getUserHomeDir() {
2524
2553
  if (process.platform === "win32") {
2525
- return process.env.USERPROFILE || process.env.HOME || homedir();
2554
+ return process.env.USERPROFILE || process.env.HOME || homedir2();
2526
2555
  }
2527
- return process.env.HOME || homedir();
2556
+ return process.env.HOME || homedir2();
2528
2557
  }
2529
2558
  function getLegacyOmcDir() {
2530
- return join8(getUserHomeDir(), ".omc");
2559
+ return join9(getUserHomeDir(), ".omc");
2531
2560
  }
2532
2561
  function getGlobalOmcStateRoot() {
2533
2562
  const explicitRoot = process.env.OMC_HOME?.trim();
2534
2563
  if (explicitRoot) {
2535
- return join8(explicitRoot, "state");
2564
+ return join9(explicitRoot, "state");
2536
2565
  }
2537
2566
  if (prefersXdgOmcDirs()) {
2538
- return join8(getStateDir(), "omc");
2567
+ return join9(getStateDir(), "omc");
2539
2568
  }
2540
- return join8(getLegacyOmcDir(), "state");
2569
+ return join9(getLegacyOmcDir(), "state");
2541
2570
  }
2542
2571
  function getGlobalOmcStatePath(...segments) {
2543
- return join8(getGlobalOmcStateRoot(), ...segments);
2572
+ return join9(getGlobalOmcStateRoot(), ...segments);
2544
2573
  }
2545
2574
  var STALE_THRESHOLD_MS;
2546
2575
  var init_paths = __esm({
@@ -2729,7 +2758,7 @@ var init_models = __esm({
2729
2758
 
2730
2759
  // src/config/loader.ts
2731
2760
  import { readFileSync as readFileSync3, existsSync as existsSync7 } from "fs";
2732
- import { join as join9, dirname as dirname6 } from "path";
2761
+ import { join as join10, dirname as dirname6 } from "path";
2733
2762
  function buildDefaultConfig() {
2734
2763
  const defaultTierModels = getDefaultTierModels();
2735
2764
  return {
@@ -3519,11 +3548,11 @@ var init_delegation_enforcer = __esm({
3519
3548
 
3520
3549
  // src/lib/security-config.ts
3521
3550
  import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
3522
- import { join as join10 } from "path";
3551
+ import { join as join11 } from "path";
3523
3552
  function loadSecurityFromConfigFiles() {
3524
3553
  const paths = [
3525
- join10(process.cwd(), ".claude", "omc.jsonc"),
3526
- join10(getConfigDir2(), "claude-omc", "config.jsonc")
3554
+ join11(process.cwd(), ".claude", "omc.jsonc"),
3555
+ join11(getConfigDir(), "claude-omc", "config.jsonc")
3527
3556
  ];
3528
3557
  for (const configPath of paths) {
3529
3558
  if (!existsSync8(configPath)) continue;
@@ -3599,7 +3628,7 @@ var init_security_config = __esm({
3599
3628
 
3600
3629
  // src/team/model-contract.ts
3601
3630
  import { spawnSync as spawnSync2 } from "child_process";
3602
- import { isAbsolute as isAbsolute4, normalize, win32 as win32Path } from "path";
3631
+ import { isAbsolute as isAbsolute4, normalize as normalize2, win32 as win32Path } from "path";
3603
3632
  function getTrustedPrefixes() {
3604
3633
  const trusted = [
3605
3634
  "/usr/local/bin",
@@ -3617,8 +3646,8 @@ function getTrustedPrefixes() {
3617
3646
  return trusted;
3618
3647
  }
3619
3648
  function isTrustedPrefix(resolvedPath) {
3620
- const normalized = normalize(resolvedPath);
3621
- return getTrustedPrefixes().some((prefix) => normalized.startsWith(normalize(prefix)));
3649
+ const normalized = normalize2(resolvedPath);
3650
+ return getTrustedPrefixes().some((prefix) => normalized.startsWith(normalize2(prefix)));
3622
3651
  }
3623
3652
  function assertBinaryName(binary) {
3624
3653
  if (!/^[A-Za-z0-9._-]+$/.test(binary)) {
@@ -3642,7 +3671,7 @@ function resolveCliBinaryPath(binary) {
3642
3671
  if (!firstLine) {
3643
3672
  throw new Error(`CLI binary '${binary}' not found in PATH`);
3644
3673
  }
3645
- const resolvedPath = normalize(firstLine);
3674
+ const resolvedPath = normalize2(firstLine);
3646
3675
  if (!isAbsolute4(resolvedPath)) {
3647
3676
  throw new Error(`Resolved CLI binary '${binary}' to relative path`);
3648
3677
  }
@@ -3852,9 +3881,9 @@ var init_model_contract = __esm({
3852
3881
 
3853
3882
  // src/team/worker-bootstrap.ts
3854
3883
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile as appendFile2 } from "fs/promises";
3855
- import { join as join11, dirname as dirname7 } from "path";
3884
+ import { join as join12, dirname as dirname7 } from "path";
3856
3885
  function buildInstructionPath(...parts) {
3857
- return join11(...parts).replaceAll("\\", "/");
3886
+ return join12(...parts).replaceAll("\\", "/");
3858
3887
  }
3859
3888
  function generateTriggerMessage(teamName, workerName, teamStateRoot3 = ".omc/state") {
3860
3889
  const inboxPath = buildInstructionPath(teamStateRoot3, "team", teamName, "workers", workerName, "inbox.md");
@@ -4017,22 +4046,22 @@ ${bootstrapInstructions}
4017
4046
  ` : ""}`;
4018
4047
  }
4019
4048
  async function composeInitialInbox(teamName, workerName, content, cwd) {
4020
- const inboxPath = join11(cwd, `.omc/state/team/${teamName}/workers/${workerName}/inbox.md`);
4049
+ const inboxPath = join12(cwd, `.omc/state/team/${teamName}/workers/${workerName}/inbox.md`);
4021
4050
  await mkdir3(dirname7(inboxPath), { recursive: true });
4022
4051
  await writeFile3(inboxPath, content, "utf-8");
4023
4052
  }
4024
4053
  async function ensureWorkerStateDir(teamName, workerName, cwd) {
4025
- const workerDir = join11(cwd, `.omc/state/team/${teamName}/workers/${workerName}`);
4054
+ const workerDir = join12(cwd, `.omc/state/team/${teamName}/workers/${workerName}`);
4026
4055
  await mkdir3(workerDir, { recursive: true });
4027
- const mailboxDir = join11(cwd, `.omc/state/team/${teamName}/mailbox`);
4056
+ const mailboxDir = join12(cwd, `.omc/state/team/${teamName}/mailbox`);
4028
4057
  await mkdir3(mailboxDir, { recursive: true });
4029
- const tasksDir = join11(cwd, `.omc/state/team/${teamName}/tasks`);
4058
+ const tasksDir = join12(cwd, `.omc/state/team/${teamName}/tasks`);
4030
4059
  await mkdir3(tasksDir, { recursive: true });
4031
4060
  }
4032
4061
  async function writeWorkerOverlay(params) {
4033
4062
  const { teamName, workerName, cwd } = params;
4034
4063
  const overlay = generateWorkerOverlay(params);
4035
- const overlayPath = join11(cwd, `.omc/state/team/${teamName}/workers/${workerName}/AGENTS.md`);
4064
+ const overlayPath = join12(cwd, `.omc/state/team/${teamName}/workers/${workerName}/AGENTS.md`);
4036
4065
  await mkdir3(dirname7(overlayPath), { recursive: true });
4037
4066
  await writeFile3(overlayPath, overlay, "utf-8");
4038
4067
  return overlayPath;
@@ -4276,16 +4305,16 @@ var init_file_lock = __esm({
4276
4305
 
4277
4306
  // src/team/git-worktree.ts
4278
4307
  import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
4279
- import { join as join13 } from "node:path";
4308
+ import { join as join14 } from "node:path";
4280
4309
  import { execFileSync as execFileSync3 } from "node:child_process";
4281
4310
  function getWorktreePath(repoRoot, teamName, workerName) {
4282
- return join13(repoRoot, ".omc", "worktrees", sanitizeName(teamName), sanitizeName(workerName));
4311
+ return join14(repoRoot, ".omc", "worktrees", sanitizeName(teamName), sanitizeName(workerName));
4283
4312
  }
4284
4313
  function getBranchName(teamName, workerName) {
4285
4314
  return `omc-team/${sanitizeName(teamName)}/${sanitizeName(workerName)}`;
4286
4315
  }
4287
4316
  function getMetadataPath(repoRoot, teamName) {
4288
- return join13(repoRoot, ".omc", "state", "team-bridge", sanitizeName(teamName), "worktrees.json");
4317
+ return join14(repoRoot, ".omc", "state", "team-bridge", sanitizeName(teamName), "worktrees.json");
4289
4318
  }
4290
4319
  function readMetadata(repoRoot, teamName) {
4291
4320
  const metaPath = getMetadataPath(repoRoot, teamName);
@@ -4302,7 +4331,7 @@ function readMetadata(repoRoot, teamName) {
4302
4331
  function writeMetadata(repoRoot, teamName, entries) {
4303
4332
  const metaPath = getMetadataPath(repoRoot, teamName);
4304
4333
  validateResolvedPath(metaPath, repoRoot);
4305
- const dir = join13(repoRoot, ".omc", "state", "team-bridge", sanitizeName(teamName));
4334
+ const dir = join14(repoRoot, ".omc", "state", "team-bridge", sanitizeName(teamName));
4306
4335
  ensureDirWithMode(dir);
4307
4336
  atomicWriteJson(metaPath, entries);
4308
4337
  }
@@ -4719,7 +4748,7 @@ __export(runtime_v2_exports, {
4719
4748
  writeWatchdogFailedMarker: () => writeWatchdogFailedMarker
4720
4749
  });
4721
4750
  import { execFile as execFile3 } from "child_process";
4722
- import { join as join16, resolve as resolve3 } from "path";
4751
+ import { join as join17, resolve as resolve3 } from "path";
4723
4752
  import { existsSync as existsSync15 } from "fs";
4724
4753
  import { mkdir as mkdir7, readdir as readdir2, readFile as readFile9, writeFile as writeFile5 } from "fs/promises";
4725
4754
  import { performance } from "perf_hooks";
@@ -4969,30 +4998,15 @@ async function spawnV2Worker(opts) {
4969
4998
  opts.teamName,
4970
4999
  opts.workerName,
4971
5000
  opts.taskId,
4972
- opts.cwd
5001
+ opts.cwd,
5002
+ 6
4973
5003
  );
4974
5004
  if (!settled) {
4975
- const renotified = await notifyStartupInbox(opts.sessionName, paneId, inboxTriggerMessage);
4976
- if (!renotified.ok) {
4977
- return {
4978
- paneId,
4979
- startupAssigned: false,
4980
- startupFailureReason: `${renotified.reason}:startup_evidence_missing`
4981
- };
4982
- }
4983
- const settledAfterRetry = await waitForWorkerStartupEvidence(
4984
- opts.teamName,
4985
- opts.workerName,
4986
- opts.taskId,
4987
- opts.cwd
4988
- );
4989
- if (!settledAfterRetry) {
4990
- return {
4991
- paneId,
4992
- startupAssigned: false,
4993
- startupFailureReason: "claude_startup_evidence_missing"
4994
- };
4995
- }
5005
+ return {
5006
+ paneId,
5007
+ startupAssigned: false,
5008
+ startupFailureReason: "claude_startup_evidence_missing"
5009
+ };
4996
5010
  }
4997
5011
  }
4998
5012
  if (usePromptMode) {
@@ -5026,11 +5040,11 @@ async function startTeamV2(config) {
5026
5040
  }
5027
5041
  await mkdir7(absPath(leaderCwd, TeamPaths.tasks(sanitized)), { recursive: true });
5028
5042
  await mkdir7(absPath(leaderCwd, TeamPaths.workers(sanitized)), { recursive: true });
5029
- await mkdir7(join16(leaderCwd, ".omc", "state", "team", sanitized, "mailbox"), { recursive: true });
5043
+ await mkdir7(join17(leaderCwd, ".omc", "state", "team", sanitized, "mailbox"), { recursive: true });
5030
5044
  for (let i = 0; i < config.tasks.length; i++) {
5031
5045
  const taskId = String(i + 1);
5032
5046
  const taskFilePath = absPath(leaderCwd, TeamPaths.taskFile(sanitized, taskId));
5033
- await mkdir7(join16(taskFilePath, ".."), { recursive: true });
5047
+ await mkdir7(join17(taskFilePath, ".."), { recursive: true });
5034
5048
  await writeFile5(taskFilePath, JSON.stringify({
5035
5049
  id: taskId,
5036
5050
  subject: config.tasks[i].subject,
@@ -5221,7 +5235,7 @@ async function writeWatchdogFailedMarker(teamName, cwd, reason) {
5221
5235
  writtenBy: "runtime-v2"
5222
5236
  };
5223
5237
  const root = absPath(cwd, TeamPaths.root(sanitizeTeamName(teamName)));
5224
- const markerPath = join16(root, "watchdog-failed.json");
5238
+ const markerPath = join17(root, "watchdog-failed.json");
5225
5239
  await mkdir7(root, { recursive: true });
5226
5240
  await writeFile6(markerPath, JSON.stringify(marker, null, 2), "utf-8");
5227
5241
  }
@@ -5587,7 +5601,7 @@ async function resumeTeamV2(teamName, cwd) {
5587
5601
  }
5588
5602
  }
5589
5603
  async function findActiveTeamsV2(cwd) {
5590
- const root = join16(cwd, ".omc", "state", "team");
5604
+ const root = join17(cwd, ".omc", "state", "team");
5591
5605
  if (!existsSync15(root)) return [];
5592
5606
  const entries = await readdir2(root, { withFileTypes: true });
5593
5607
  const active = [];
@@ -5653,7 +5667,7 @@ import { randomUUID as randomUUID6 } from "crypto";
5653
5667
  import { spawn } from "child_process";
5654
5668
  import { existsSync as existsSync17, mkdirSync as mkdirSync3, readFileSync as readFileSync10, writeFileSync as writeFileSync2 } from "fs";
5655
5669
  import { readFile as readFile10, rm as rm4 } from "fs/promises";
5656
- import { dirname as dirname13, join as join18 } from "path";
5670
+ import { dirname as dirname13, join as join19 } from "path";
5657
5671
  import { fileURLToPath as fileURLToPath3 } from "url";
5658
5672
 
5659
5673
  // src/team/api-interop.ts
@@ -5664,7 +5678,7 @@ init_tmux_session();
5664
5678
  init_dispatch_queue();
5665
5679
  init_worker_bootstrap();
5666
5680
  import { existsSync as existsSync16, readFileSync as readFileSync9 } from "node:fs";
5667
- import { dirname as dirname12, join as join17, resolve as resolvePath } from "node:path";
5681
+ import { dirname as dirname12, join as join18, resolve as resolvePath } from "node:path";
5668
5682
 
5669
5683
  // src/team/runtime.ts
5670
5684
  init_model_contract();
@@ -5673,25 +5687,25 @@ init_tmux_session();
5673
5687
  init_worker_bootstrap();
5674
5688
  init_git_worktree();
5675
5689
  import { mkdir as mkdir4, writeFile as writeFile4, readFile as readFile6, rm as rm3, rename as rename2 } from "fs/promises";
5676
- import { join as join15 } from "path";
5690
+ import { join as join16 } from "path";
5677
5691
  import { existsSync as existsSync12 } from "fs";
5678
5692
 
5679
5693
  // src/team/task-file-ops.ts
5680
- init_paths();
5694
+ init_config_dir();
5681
5695
  init_tmux_session();
5682
5696
  init_fs_utils();
5683
5697
  init_platform();
5684
5698
  init_state_paths();
5685
5699
  import { readFileSync as readFileSync8, readdirSync as readdirSync3, existsSync as existsSync11, openSync as openSync4, closeSync as closeSync4, unlinkSync as unlinkSync4, writeSync as writeSync4, statSync as statSync3, constants as fsConstants2 } from "fs";
5686
- import { join as join14 } from "path";
5700
+ import { join as join15 } from "path";
5687
5701
 
5688
5702
  // src/team/runtime.ts
5689
5703
  function stateRoot(cwd, teamName) {
5690
5704
  validateTeamName(teamName);
5691
- return join15(cwd, `.omc/state/team/${teamName}`);
5705
+ return join16(cwd, `.omc/state/team/${teamName}`);
5692
5706
  }
5693
5707
  async function writeJson(filePath, data) {
5694
- await mkdir4(join15(filePath, ".."), { recursive: true });
5708
+ await mkdir4(join16(filePath, ".."), { recursive: true });
5695
5709
  await writeFile4(filePath, JSON.stringify(data, null, 2), "utf-8");
5696
5710
  }
5697
5711
  async function readJsonSafe2(filePath) {
@@ -5721,7 +5735,7 @@ async function readJsonSafe2(filePath) {
5721
5735
  return null;
5722
5736
  }
5723
5737
  function taskPath(root, taskId) {
5724
- return join15(root, "tasks", `${taskId}.json`);
5738
+ return join16(root, "tasks", `${taskId}.json`);
5725
5739
  }
5726
5740
  async function readTask(root, taskId) {
5727
5741
  return readJsonSafe2(taskPath(root, taskId));
@@ -5734,9 +5748,9 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
5734
5748
  const taskCounts = { pending: 0, inProgress: 0, completed: 0, failed: 0 };
5735
5749
  try {
5736
5750
  const { readdir: readdir3 } = await import("fs/promises");
5737
- const taskFiles = await readdir3(join15(root, "tasks"));
5751
+ const taskFiles = await readdir3(join16(root, "tasks"));
5738
5752
  for (const f of taskFiles.filter((f2) => f2.endsWith(".json"))) {
5739
- const task = await readJsonSafe2(join15(root, "tasks", f));
5753
+ const task = await readJsonSafe2(join16(root, "tasks", f));
5740
5754
  if (task?.status === "pending") taskCounts.pending++;
5741
5755
  else if (task?.status === "in_progress") taskCounts.inProgress++;
5742
5756
  else if (task?.status === "completed") taskCounts.completed++;
@@ -5752,7 +5766,7 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
5752
5766
  const wName = `worker-${i + 1}`;
5753
5767
  const paneId = workerPaneIds[i];
5754
5768
  const alive = await isWorkerAlive(paneId);
5755
- const heartbeatPath = join15(root, "workers", wName, "heartbeat.json");
5769
+ const heartbeatPath = join16(root, "workers", wName, "heartbeat.json");
5756
5770
  const heartbeat = await readJsonSafe2(heartbeatPath);
5757
5771
  let stalled = false;
5758
5772
  if (heartbeat?.updatedAt) {
@@ -5794,11 +5808,11 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
5794
5808
  }
5795
5809
  async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, workerPaneIds, leaderPaneId, ownsWindow) {
5796
5810
  const root = stateRoot(cwd, teamName);
5797
- await writeJson(join15(root, "shutdown.json"), {
5811
+ await writeJson(join16(root, "shutdown.json"), {
5798
5812
  requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
5799
5813
  teamName
5800
5814
  });
5801
- const configData = await readJsonSafe2(join15(root, "config.json"));
5815
+ const configData = await readJsonSafe2(join16(root, "config.json"));
5802
5816
  const CLI_AGENT_TYPES = /* @__PURE__ */ new Set(["claude", "codex", "gemini"]);
5803
5817
  const agentTypes = configData?.agentTypes ?? [];
5804
5818
  const isCliWorkerTeam = agentTypes.length > 0 && agentTypes.every((t) => CLI_AGENT_TYPES.has(t));
@@ -5808,7 +5822,7 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
5808
5822
  const expectedAcks = Array.from({ length: workerCount }, (_, i) => `worker-${i + 1}`);
5809
5823
  while (Date.now() < deadline && expectedAcks.length > 0) {
5810
5824
  for (const wName of [...expectedAcks]) {
5811
- const ackPath = join15(root, "workers", wName, "shutdown-ack.json");
5825
+ const ackPath = join16(root, "workers", wName, "shutdown-ack.json");
5812
5826
  if (existsSync12(ackPath)) {
5813
5827
  expectedAcks.splice(expectedAcks.indexOf(wName), 1);
5814
5828
  }
@@ -5832,7 +5846,7 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
5832
5846
  }
5833
5847
  async function resumeTeam(teamName, cwd) {
5834
5848
  const root = stateRoot(cwd, teamName);
5835
- const configData = await readJsonSafe2(join15(root, "config.json"));
5849
+ const configData = await readJsonSafe2(join16(root, "config.json"));
5836
5850
  if (!configData) return null;
5837
5851
  const { execFile: execFile4 } = await import("child_process");
5838
5852
  const { promisify: promisify3 } = await import("util");
@@ -5941,8 +5955,8 @@ function parseValidatedTaskIdArray(value, fieldName) {
5941
5955
  }
5942
5956
  function teamStateExists(teamName, candidateCwd) {
5943
5957
  if (!TEAM_NAME_SAFE_PATTERN.test(teamName)) return false;
5944
- const teamRoot = join17(candidateCwd, ".omc", "state", "team", teamName);
5945
- return existsSync16(join17(teamRoot, "config.json")) || existsSync16(join17(teamRoot, "tasks")) || existsSync16(teamRoot);
5958
+ const teamRoot = join18(candidateCwd, ".omc", "state", "team", teamName);
5959
+ return existsSync16(join18(teamRoot, "config.json")) || existsSync16(join18(teamRoot, "tasks")) || existsSync16(teamRoot);
5946
5960
  }
5947
5961
  function parseTeamWorkerEnv(raw) {
5948
5962
  if (typeof raw !== "string" || raw.trim() === "") return null;
@@ -6013,16 +6027,16 @@ function stateRootToWorkingDirectory(stateRoot2) {
6013
6027
  return dirname12(dirname12(absolute));
6014
6028
  }
6015
6029
  function resolveTeamWorkingDirectoryFromMetadata(teamName, candidateCwd, workerContext) {
6016
- const teamRoot = join17(candidateCwd, ".omc", "state", "team", teamName);
6030
+ const teamRoot = join18(candidateCwd, ".omc", "state", "team", teamName);
6017
6031
  if (!existsSync16(teamRoot)) return null;
6018
6032
  if (workerContext?.teamName === teamName) {
6019
- const workerRoot = readTeamStateRootFromFile(join17(teamRoot, "workers", workerContext.workerName, "identity.json"));
6033
+ const workerRoot = readTeamStateRootFromFile(join18(teamRoot, "workers", workerContext.workerName, "identity.json"));
6020
6034
  if (workerRoot) return stateRootToWorkingDirectory(workerRoot);
6021
6035
  }
6022
- const fromConfig = readTeamStateRootFromFile(join17(teamRoot, "config.json"));
6036
+ const fromConfig = readTeamStateRootFromFile(join18(teamRoot, "config.json"));
6023
6037
  if (fromConfig) return stateRootToWorkingDirectory(fromConfig);
6024
6038
  for (const manifestName of ["manifest.json", "manifest.v2.json"]) {
6025
- const fromManifest = readTeamStateRootFromFile(join17(teamRoot, manifestName));
6039
+ const fromManifest = readTeamStateRootFromFile(join18(teamRoot, manifestName));
6026
6040
  if (fromManifest) return stateRootToWorkingDirectory(fromManifest);
6027
6041
  }
6028
6042
  return null;
@@ -6671,7 +6685,7 @@ function resolveRuntimeCliPath(env = process.env) {
6671
6685
  return env.OMC_RUNTIME_CLI_PATH;
6672
6686
  }
6673
6687
  const moduleDir = dirname13(fileURLToPath3(import.meta.url));
6674
- return join18(moduleDir, "../../bridge/runtime-cli.cjs");
6688
+ return join19(moduleDir, "../../bridge/runtime-cli.cjs");
6675
6689
  }
6676
6690
  function ensureJobsDir(jobsDir) {
6677
6691
  if (!existsSync17(jobsDir)) {
@@ -6679,16 +6693,16 @@ function ensureJobsDir(jobsDir) {
6679
6693
  }
6680
6694
  }
6681
6695
  function jobPath(jobsDir, jobId) {
6682
- return join18(jobsDir, `${jobId}.json`);
6696
+ return join19(jobsDir, `${jobId}.json`);
6683
6697
  }
6684
6698
  function resultArtifactPath(jobsDir, jobId) {
6685
- return join18(jobsDir, `${jobId}-result.json`);
6699
+ return join19(jobsDir, `${jobId}-result.json`);
6686
6700
  }
6687
6701
  function panesArtifactPath(jobsDir, jobId) {
6688
- return join18(jobsDir, `${jobId}-panes.json`);
6702
+ return join19(jobsDir, `${jobId}-panes.json`);
6689
6703
  }
6690
6704
  function teamStateRoot2(cwd, teamName) {
6691
- return join18(cwd, ".omc", "state", "team", teamName);
6705
+ return join19(cwd, ".omc", "state", "team", teamName);
6692
6706
  }
6693
6707
  function validateJobId(jobId) {
6694
6708
  if (!JOB_ID_PATTERN.test(jobId)) {
@@ -26,9 +26,8 @@ vi.mock('fs', async () => {
26
26
  });
27
27
  import { execSync, execFileSync } from 'child_process';
28
28
  import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
29
- import { homedir } from 'os';
30
29
  import { join } from 'path';
31
- import { install, isProjectScopedPlugin, checkNodeVersion } from '../installer/index.js';
30
+ import { install, isProjectScopedPlugin, checkNodeVersion, CLAUDE_CONFIG_DIR } from '../installer/index.js';
32
31
  import * as hooksModule from '../installer/hooks.js';
33
32
  import { reconcileUpdateRuntime, performUpdate, shouldBlockStandaloneUpdateInCurrentSession, syncPluginCache, } from '../features/auto-update.js';
34
33
  const mockedExecSync = vi.mocked(execSync);
@@ -190,7 +189,7 @@ describe('auto-update reconciliation', () => {
190
189
  });
191
190
  it('syncs the plugin cache directory when cache root exists', () => {
192
191
  const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
193
- const cacheRoot = join(homedir(), '.claude', 'plugins', 'cache', 'omc', 'oh-my-claudecode');
192
+ const cacheRoot = join(CLAUDE_CONFIG_DIR, 'plugins', 'cache', 'omc', 'oh-my-claudecode');
194
193
  const versionedCacheRoot = `${cacheRoot}/4.9.0`;
195
194
  mockedExecSync.mockImplementation((command) => {
196
195
  if (command === 'npm root -g') {
@@ -235,7 +234,7 @@ describe('auto-update reconciliation', () => {
235
234
  expect(consoleLogSpy).toHaveBeenCalledWith('[omc update] Plugin cache synced');
236
235
  });
237
236
  it('skips plugin cache sync gracefully when cache dir does not exist', () => {
238
- const cacheRoot = join(homedir(), '.claude', 'plugins', 'cache', 'omc', 'oh-my-claudecode');
237
+ const cacheRoot = join(CLAUDE_CONFIG_DIR, 'plugins', 'cache', 'omc', 'oh-my-claudecode');
239
238
  mockedExistsSync.mockImplementation((path) => {
240
239
  const normalized = String(path).replace(/\\/g, '/');
241
240
  if (normalized === cacheRoot) {
@@ -250,7 +249,7 @@ describe('auto-update reconciliation', () => {
250
249
  });
251
250
  it('handles plugin cache sync errors non-fatally', () => {
252
251
  const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
253
- const cacheRoot = join(homedir(), '.claude', 'plugins', 'cache', 'omc', 'oh-my-claudecode');
252
+ const cacheRoot = join(CLAUDE_CONFIG_DIR, 'plugins', 'cache', 'omc', 'oh-my-claudecode');
254
253
  const versionedCacheRoot = `${cacheRoot}/4.9.0`;
255
254
  mockedExecSync.mockImplementation((command) => {
256
255
  if (command === 'npm root -g') {
@@ -355,8 +354,8 @@ describe('auto-update reconciliation', () => {
355
354
  expect(consoleLogSpy).toHaveBeenCalledWith('[omc update] Synced plugin cache');
356
355
  });
357
356
  it('allows standalone update when CLAUDE_PLUGIN_ROOT is inherited without an active Claude session', async () => {
358
- const pluginRoot = join(homedir(), '.claude', 'plugins', 'cache', 'omc', 'oh-my-claudecode', '4.1.5');
359
- const cacheRoot = join(homedir(), '.claude', 'plugins', 'cache', 'omc', 'oh-my-claudecode');
357
+ const pluginRoot = join(CLAUDE_CONFIG_DIR, 'plugins', 'cache', 'omc', 'oh-my-claudecode', '4.1.5');
358
+ const cacheRoot = join(CLAUDE_CONFIG_DIR, 'plugins', 'cache', 'omc', 'oh-my-claudecode');
360
359
  process.env.OMC_UPDATE_RECONCILE = '1';
361
360
  process.env.CLAUDE_PLUGIN_ROOT = pluginRoot;
362
361
  delete process.env.CLAUDE_CODE_ENTRYPOINT;
@@ -709,7 +708,7 @@ describe('auto-update reconciliation', () => {
709
708
  ],
710
709
  },
711
710
  };
712
- const settingsPath = join(homedir(), '.claude', 'settings.json');
711
+ const settingsPath = join(CLAUDE_CONFIG_DIR, 'settings.json');
713
712
  const baseHooks = hooksModule.getHooksSettingsConfig();
714
713
  const freshHooks = {
715
714
  ...baseHooks,
@@ -752,7 +751,7 @@ describe('auto-update reconciliation', () => {
752
751
  });
753
752
  vi.spyOn(hooksModule, 'getHooksSettingsConfig').mockReturnValue(freshHooks);
754
753
  const originalPluginRoot = process.env.CLAUDE_PLUGIN_ROOT;
755
- process.env.CLAUDE_PLUGIN_ROOT = join(homedir(), '.claude', 'plugins', 'cache', 'omc', 'oh-my-claudecode', '4.1.5');
754
+ process.env.CLAUDE_PLUGIN_ROOT = join(CLAUDE_CONFIG_DIR, 'plugins', 'cache', 'omc', 'oh-my-claudecode', '4.1.5');
756
755
  const result = install({
757
756
  force: true,
758
757
  skipClaudeCheck: true,