oh-my-copilot 5.5.0 → 5.6.2

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 (444) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +1 -0
  4. package/bridge/__pycache__/gyoshu_bridge.cpython-312.pyc +0 -0
  5. package/bridge/claude-md-coordinator.cjs +2 -2
  6. package/bridge/cli.cjs +6290 -3436
  7. package/bridge/mcp-server.cjs +637 -503
  8. package/bridge/runtime-cli.cjs +516 -213
  9. package/bridge/team-bridge.cjs +141 -135
  10. package/bridge/team-mcp.cjs +201 -129
  11. package/bridge/team.js +473 -237
  12. package/copilot/hooks.json +43 -0
  13. package/dist/__tests__/chain-enqueuer-registration.test.d.ts +11 -0
  14. package/dist/__tests__/chain-enqueuer-registration.test.d.ts.map +1 -0
  15. package/dist/__tests__/chain-enqueuer-registration.test.js +122 -0
  16. package/dist/__tests__/chain-enqueuer-registration.test.js.map +1 -0
  17. package/dist/__tests__/copilot-hooks-manifest.test.js +3 -1
  18. package/dist/__tests__/copilot-hooks-manifest.test.js.map +1 -1
  19. package/dist/__tests__/directory-context-injector.test.js +41 -1
  20. package/dist/__tests__/directory-context-injector.test.js.map +1 -1
  21. package/dist/__tests__/hook-bridge-main-module.test.d.ts +2 -0
  22. package/dist/__tests__/hook-bridge-main-module.test.d.ts.map +1 -0
  23. package/dist/__tests__/hook-bridge-main-module.test.js +48 -0
  24. package/dist/__tests__/hook-bridge-main-module.test.js.map +1 -0
  25. package/dist/__tests__/ralph-prd-stale.test.js +12 -1
  26. package/dist/__tests__/ralph-prd-stale.test.js.map +1 -1
  27. package/dist/__tests__/ralph-prd.test.js +56 -0
  28. package/dist/__tests__/ralph-prd.test.js.map +1 -1
  29. package/dist/__tests__/run-cjs-graceful-fallback.test.js +2 -0
  30. package/dist/__tests__/run-cjs-graceful-fallback.test.js.map +1 -1
  31. package/dist/__tests__/session-end-forwarder-fallback.test.d.ts +2 -0
  32. package/dist/__tests__/session-end-forwarder-fallback.test.d.ts.map +1 -0
  33. package/dist/__tests__/session-end-forwarder-fallback.test.js +138 -0
  34. package/dist/__tests__/session-end-forwarder-fallback.test.js.map +1 -0
  35. package/dist/cli/__tests__/autoresearch-setup-session.test.js +67 -3
  36. package/dist/cli/__tests__/autoresearch-setup-session.test.js.map +1 -1
  37. package/dist/cli/__tests__/launch.test.js +73 -11
  38. package/dist/cli/__tests__/launch.test.js.map +1 -1
  39. package/dist/cli/__tests__/plugin-dir-capture.test.js +45 -0
  40. package/dist/cli/__tests__/plugin-dir-capture.test.js.map +1 -1
  41. package/dist/cli/__tests__/ralph-afk.test.d.ts +2 -0
  42. package/dist/cli/__tests__/ralph-afk.test.d.ts.map +1 -0
  43. package/dist/cli/__tests__/ralph-afk.test.js +312 -0
  44. package/dist/cli/__tests__/ralph-afk.test.js.map +1 -0
  45. package/dist/cli/__tests__/team.test.js +170 -0
  46. package/dist/cli/__tests__/team.test.js.map +1 -1
  47. package/dist/cli/__tests__/tmux-utils.test.js +132 -16
  48. package/dist/cli/__tests__/tmux-utils.test.js.map +1 -1
  49. package/dist/cli/autoresearch-setup-session.d.ts.map +1 -1
  50. package/dist/cli/autoresearch-setup-session.js +29 -9
  51. package/dist/cli/autoresearch-setup-session.js.map +1 -1
  52. package/dist/cli/commands/__tests__/factory-init.test.d.ts +2 -0
  53. package/dist/cli/commands/__tests__/factory-init.test.d.ts.map +1 -0
  54. package/dist/cli/commands/__tests__/factory-init.test.js +90 -0
  55. package/dist/cli/commands/__tests__/factory-init.test.js.map +1 -0
  56. package/dist/cli/commands/__tests__/intake-headless-flag.test.d.ts +2 -0
  57. package/dist/cli/commands/__tests__/intake-headless-flag.test.d.ts.map +1 -0
  58. package/dist/cli/commands/__tests__/intake-headless-flag.test.js +30 -0
  59. package/dist/cli/commands/__tests__/intake-headless-flag.test.js.map +1 -0
  60. package/dist/cli/commands/__tests__/intake.test.d.ts +2 -0
  61. package/dist/cli/commands/__tests__/intake.test.d.ts.map +1 -0
  62. package/dist/cli/commands/__tests__/intake.test.js +257 -0
  63. package/dist/cli/commands/__tests__/intake.test.js.map +1 -0
  64. package/dist/cli/commands/factory.d.ts +61 -0
  65. package/dist/cli/commands/factory.d.ts.map +1 -0
  66. package/dist/cli/commands/factory.js +190 -0
  67. package/dist/cli/commands/factory.js.map +1 -0
  68. package/dist/cli/commands/intake.d.ts +94 -0
  69. package/dist/cli/commands/intake.d.ts.map +1 -0
  70. package/dist/cli/commands/intake.js +311 -0
  71. package/dist/cli/commands/intake.js.map +1 -0
  72. package/dist/cli/commands/ralph.d.ts +88 -0
  73. package/dist/cli/commands/ralph.d.ts.map +1 -0
  74. package/dist/cli/commands/ralph.js +456 -0
  75. package/dist/cli/commands/ralph.js.map +1 -0
  76. package/dist/cli/commands/team.d.ts.map +1 -1
  77. package/dist/cli/commands/team.js +25 -5
  78. package/dist/cli/commands/team.js.map +1 -1
  79. package/dist/cli/index.d.ts.map +1 -1
  80. package/dist/cli/index.js +7 -0
  81. package/dist/cli/index.js.map +1 -1
  82. package/dist/cli/launch.d.ts.map +1 -1
  83. package/dist/cli/launch.js +32 -7
  84. package/dist/cli/launch.js.map +1 -1
  85. package/dist/cli/team.d.ts.map +1 -1
  86. package/dist/cli/team.js +61 -7
  87. package/dist/cli/team.js.map +1 -1
  88. package/dist/cli/tmux-utils.d.ts +26 -0
  89. package/dist/cli/tmux-utils.d.ts.map +1 -1
  90. package/dist/cli/tmux-utils.js +61 -9
  91. package/dist/cli/tmux-utils.js.map +1 -1
  92. package/dist/config/__tests__/loader.test.js +138 -0
  93. package/dist/config/__tests__/loader.test.js.map +1 -1
  94. package/dist/config/loader.d.ts.map +1 -1
  95. package/dist/config/loader.js +17 -0
  96. package/dist/config/loader.js.map +1 -1
  97. package/dist/factory/__tests__/check-run.test.d.ts +2 -0
  98. package/dist/factory/__tests__/check-run.test.d.ts.map +1 -0
  99. package/dist/factory/__tests__/check-run.test.js +213 -0
  100. package/dist/factory/__tests__/check-run.test.js.map +1 -0
  101. package/dist/factory/__tests__/listener.test.d.ts +2 -0
  102. package/dist/factory/__tests__/listener.test.d.ts.map +1 -0
  103. package/dist/factory/__tests__/listener.test.js +312 -0
  104. package/dist/factory/__tests__/listener.test.js.map +1 -0
  105. package/dist/factory/__tests__/map-frontier.test.d.ts +2 -0
  106. package/dist/factory/__tests__/map-frontier.test.d.ts.map +1 -0
  107. package/dist/factory/__tests__/map-frontier.test.js +128 -0
  108. package/dist/factory/__tests__/map-frontier.test.js.map +1 -0
  109. package/dist/factory/__tests__/map-ingest.test.d.ts +2 -0
  110. package/dist/factory/__tests__/map-ingest.test.d.ts.map +1 -0
  111. package/dist/factory/__tests__/map-ingest.test.js +166 -0
  112. package/dist/factory/__tests__/map-ingest.test.js.map +1 -0
  113. package/dist/factory/__tests__/map-run.test.d.ts +2 -0
  114. package/dist/factory/__tests__/map-run.test.d.ts.map +1 -0
  115. package/dist/factory/__tests__/map-run.test.js +148 -0
  116. package/dist/factory/__tests__/map-run.test.js.map +1 -0
  117. package/dist/factory/__tests__/status.test.d.ts +2 -0
  118. package/dist/factory/__tests__/status.test.d.ts.map +1 -0
  119. package/dist/factory/__tests__/status.test.js +77 -0
  120. package/dist/factory/__tests__/status.test.js.map +1 -0
  121. package/dist/factory/listener.d.ts +98 -0
  122. package/dist/factory/listener.d.ts.map +1 -0
  123. package/dist/factory/listener.js +315 -0
  124. package/dist/factory/listener.js.map +1 -0
  125. package/dist/factory/map-frontier.d.ts +73 -0
  126. package/dist/factory/map-frontier.d.ts.map +1 -0
  127. package/dist/factory/map-frontier.js +147 -0
  128. package/dist/factory/map-frontier.js.map +1 -0
  129. package/dist/factory/map-ingest.d.ts +79 -0
  130. package/dist/factory/map-ingest.d.ts.map +1 -0
  131. package/dist/factory/map-ingest.js +232 -0
  132. package/dist/factory/map-ingest.js.map +1 -0
  133. package/dist/factory/map-run.d.ts +74 -0
  134. package/dist/factory/map-run.d.ts.map +1 -0
  135. package/dist/factory/map-run.js +229 -0
  136. package/dist/factory/map-run.js.map +1 -0
  137. package/dist/factory/status.d.ts +33 -0
  138. package/dist/factory/status.d.ts.map +1 -0
  139. package/dist/factory/status.js +93 -0
  140. package/dist/factory/status.js.map +1 -0
  141. package/dist/factory/watchdog.d.ts +46 -0
  142. package/dist/factory/watchdog.d.ts.map +1 -0
  143. package/dist/factory/watchdog.js +130 -0
  144. package/dist/factory/watchdog.js.map +1 -0
  145. package/dist/factory/watchdog.test.d.ts +2 -0
  146. package/dist/factory/watchdog.test.d.ts.map +1 -0
  147. package/dist/factory/watchdog.test.js +111 -0
  148. package/dist/factory/watchdog.test.js.map +1 -0
  149. package/dist/graph/runtime/native-contained-fs.js +1 -1
  150. package/dist/graph/runtime/native-contained-fs.js.map +1 -1
  151. package/dist/hooks/__tests__/compaction-concurrency.test.js +20 -20
  152. package/dist/hooks/__tests__/compaction-concurrency.test.js.map +1 -1
  153. package/dist/hooks/__tests__/workflow-drift-guard-script.test.js +27 -0
  154. package/dist/hooks/__tests__/workflow-drift-guard-script.test.js.map +1 -1
  155. package/dist/hooks/bridge.d.ts +8 -0
  156. package/dist/hooks/bridge.d.ts.map +1 -1
  157. package/dist/hooks/bridge.js +38 -9
  158. package/dist/hooks/bridge.js.map +1 -1
  159. package/dist/hooks/code-simplifier/__tests__/global-config-path.test.d.ts +2 -0
  160. package/dist/hooks/code-simplifier/__tests__/global-config-path.test.d.ts.map +1 -0
  161. package/dist/hooks/code-simplifier/__tests__/global-config-path.test.js +89 -0
  162. package/dist/hooks/code-simplifier/__tests__/global-config-path.test.js.map +1 -0
  163. package/dist/hooks/code-simplifier/index.d.ts +1 -1
  164. package/dist/hooks/code-simplifier/index.js +1 -1
  165. package/dist/hooks/code-simplifier/jev-shadow.d.ts +5 -4
  166. package/dist/hooks/code-simplifier/jev-shadow.d.ts.map +1 -1
  167. package/dist/hooks/code-simplifier/jev-shadow.js +9 -4
  168. package/dist/hooks/code-simplifier/jev-shadow.js.map +1 -1
  169. package/dist/hooks/directory-readme-injector/index.d.ts.map +1 -1
  170. package/dist/hooks/directory-readme-injector/index.js +11 -2
  171. package/dist/hooks/directory-readme-injector/index.js.map +1 -1
  172. package/dist/hooks/jev/__tests__/active-mode.test.d.ts +9 -0
  173. package/dist/hooks/jev/__tests__/active-mode.test.d.ts.map +1 -0
  174. package/dist/hooks/jev/__tests__/active-mode.test.js +252 -0
  175. package/dist/hooks/jev/__tests__/active-mode.test.js.map +1 -0
  176. package/dist/hooks/jev/points.d.ts +3 -1
  177. package/dist/hooks/jev/points.d.ts.map +1 -1
  178. package/dist/hooks/jev/points.js +1 -0
  179. package/dist/hooks/jev/points.js.map +1 -1
  180. package/dist/hooks/jev/resolver.d.ts.map +1 -1
  181. package/dist/hooks/jev/resolver.js +17 -1
  182. package/dist/hooks/jev/resolver.js.map +1 -1
  183. package/dist/hooks/keyword-detector/index.d.ts +2 -0
  184. package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
  185. package/dist/hooks/keyword-detector/index.js +3 -3
  186. package/dist/hooks/keyword-detector/index.js.map +1 -1
  187. package/dist/hooks/keyword-detector/jev-shadow.d.ts +6 -4
  188. package/dist/hooks/keyword-detector/jev-shadow.d.ts.map +1 -1
  189. package/dist/hooks/keyword-detector/jev-shadow.js +18 -4
  190. package/dist/hooks/keyword-detector/jev-shadow.js.map +1 -1
  191. package/dist/hooks/learner/jev-shadow.d.ts +4 -3
  192. package/dist/hooks/learner/jev-shadow.d.ts.map +1 -1
  193. package/dist/hooks/learner/jev-shadow.js +14 -3
  194. package/dist/hooks/learner/jev-shadow.js.map +1 -1
  195. package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
  196. package/dist/hooks/persistent-mode/index.js +22 -6
  197. package/dist/hooks/persistent-mode/index.js.map +1 -1
  198. package/dist/hooks/persistent-mode/jev-shadow.d.ts +7 -5
  199. package/dist/hooks/persistent-mode/jev-shadow.d.ts.map +1 -1
  200. package/dist/hooks/persistent-mode/jev-shadow.js +28 -6
  201. package/dist/hooks/persistent-mode/jev-shadow.js.map +1 -1
  202. package/dist/hooks/preemptive-compaction/__tests__/jev-shadow.test.js +3 -3
  203. package/dist/hooks/preemptive-compaction/__tests__/jev-shadow.test.js.map +1 -1
  204. package/dist/hooks/preemptive-compaction/index.d.ts +5 -1
  205. package/dist/hooks/preemptive-compaction/index.d.ts.map +1 -1
  206. package/dist/hooks/preemptive-compaction/index.js +13 -8
  207. package/dist/hooks/preemptive-compaction/index.js.map +1 -1
  208. package/dist/hooks/preemptive-compaction/jev-shadow.d.ts +6 -5
  209. package/dist/hooks/preemptive-compaction/jev-shadow.d.ts.map +1 -1
  210. package/dist/hooks/preemptive-compaction/jev-shadow.js +18 -5
  211. package/dist/hooks/preemptive-compaction/jev-shadow.js.map +1 -1
  212. package/dist/hooks/ralph/__tests__/feedback-baseline.test.d.ts +2 -0
  213. package/dist/hooks/ralph/__tests__/feedback-baseline.test.d.ts.map +1 -0
  214. package/dist/hooks/ralph/__tests__/feedback-baseline.test.js +250 -0
  215. package/dist/hooks/ralph/__tests__/feedback-baseline.test.js.map +1 -0
  216. package/dist/hooks/ralph/feedback-baseline.d.ts +58 -0
  217. package/dist/hooks/ralph/feedback-baseline.d.ts.map +1 -0
  218. package/dist/hooks/ralph/feedback-baseline.js +141 -0
  219. package/dist/hooks/ralph/feedback-baseline.js.map +1 -0
  220. package/dist/hooks/ralph/index.d.ts +1 -1
  221. package/dist/hooks/ralph/index.d.ts.map +1 -1
  222. package/dist/hooks/ralph/index.js +1 -1
  223. package/dist/hooks/ralph/index.js.map +1 -1
  224. package/dist/hooks/ralph/jev-shadow.d.ts +4 -3
  225. package/dist/hooks/ralph/jev-shadow.d.ts.map +1 -1
  226. package/dist/hooks/ralph/jev-shadow.js +14 -4
  227. package/dist/hooks/ralph/jev-shadow.js.map +1 -1
  228. package/dist/hooks/ralph/loop.d.ts +7 -0
  229. package/dist/hooks/ralph/loop.d.ts.map +1 -1
  230. package/dist/hooks/ralph/loop.js +21 -0
  231. package/dist/hooks/ralph/loop.js.map +1 -1
  232. package/dist/hooks/ralph/prd.d.ts +17 -0
  233. package/dist/hooks/ralph/prd.d.ts.map +1 -1
  234. package/dist/hooks/ralph/prd.js +26 -1
  235. package/dist/hooks/ralph/prd.js.map +1 -1
  236. package/dist/hooks/registry/__tests__/registry.test.js +12 -4
  237. package/dist/hooks/registry/__tests__/registry.test.js.map +1 -1
  238. package/dist/hooks/rules-injector/matcher.d.ts.map +1 -1
  239. package/dist/hooks/rules-injector/matcher.js +35 -7
  240. package/dist/hooks/rules-injector/matcher.js.map +1 -1
  241. package/dist/hooks/rules-injector/matcher.test.d.ts +2 -0
  242. package/dist/hooks/rules-injector/matcher.test.d.ts.map +1 -0
  243. package/dist/hooks/rules-injector/matcher.test.js +58 -0
  244. package/dist/hooks/rules-injector/matcher.test.js.map +1 -0
  245. package/dist/hooks/session-end/__tests__/action-runner.test.js +51 -0
  246. package/dist/hooks/session-end/__tests__/action-runner.test.js.map +1 -1
  247. package/dist/hooks/session-end/__tests__/chain-enqueuer.test.d.ts +2 -0
  248. package/dist/hooks/session-end/__tests__/chain-enqueuer.test.d.ts.map +1 -0
  249. package/dist/hooks/session-end/__tests__/chain-enqueuer.test.js +274 -0
  250. package/dist/hooks/session-end/__tests__/chain-enqueuer.test.js.map +1 -0
  251. package/dist/hooks/session-end/__tests__/check-evidence.test.d.ts +2 -0
  252. package/dist/hooks/session-end/__tests__/check-evidence.test.d.ts.map +1 -0
  253. package/dist/hooks/session-end/__tests__/check-evidence.test.js +171 -0
  254. package/dist/hooks/session-end/__tests__/check-evidence.test.js.map +1 -0
  255. package/dist/hooks/session-end/__tests__/cleanup-manifest.test.js +21 -0
  256. package/dist/hooks/session-end/__tests__/cleanup-manifest.test.js.map +1 -1
  257. package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.d.ts +10 -0
  258. package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.d.ts.map +1 -0
  259. package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.js +123 -0
  260. package/dist/hooks/session-end/__tests__/foreground-bootstrap.test.js.map +1 -0
  261. package/dist/hooks/session-end/__tests__/guardrails.test.d.ts +2 -0
  262. package/dist/hooks/session-end/__tests__/guardrails.test.d.ts.map +1 -0
  263. package/dist/hooks/session-end/__tests__/guardrails.test.js +184 -0
  264. package/dist/hooks/session-end/__tests__/guardrails.test.js.map +1 -0
  265. package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.d.ts +9 -0
  266. package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.d.ts.map +1 -0
  267. package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.js +96 -0
  268. package/dist/hooks/session-end/__tests__/process-session-end-worker-spawn.test.js.map +1 -0
  269. package/dist/hooks/session-end/__tests__/routing.test.d.ts +2 -0
  270. package/dist/hooks/session-end/__tests__/routing.test.d.ts.map +1 -0
  271. package/dist/hooks/session-end/__tests__/routing.test.js +135 -0
  272. package/dist/hooks/session-end/__tests__/routing.test.js.map +1 -0
  273. package/dist/hooks/session-end/__tests__/spawn-next.test.d.ts +2 -0
  274. package/dist/hooks/session-end/__tests__/spawn-next.test.d.ts.map +1 -0
  275. package/dist/hooks/session-end/__tests__/spawn-next.test.js +501 -0
  276. package/dist/hooks/session-end/__tests__/spawn-next.test.js.map +1 -0
  277. package/dist/hooks/session-end/__tests__/worker.test.js +102 -0
  278. package/dist/hooks/session-end/__tests__/worker.test.js.map +1 -1
  279. package/dist/hooks/session-end/action-runner.d.ts.map +1 -1
  280. package/dist/hooks/session-end/action-runner.js +24 -2
  281. package/dist/hooks/session-end/action-runner.js.map +1 -1
  282. package/dist/hooks/session-end/chain-enqueuer.d.ts +45 -0
  283. package/dist/hooks/session-end/chain-enqueuer.d.ts.map +1 -0
  284. package/dist/hooks/session-end/chain-enqueuer.js +191 -0
  285. package/dist/hooks/session-end/chain-enqueuer.js.map +1 -0
  286. package/dist/hooks/session-end/check-evidence.d.ts +29 -0
  287. package/dist/hooks/session-end/check-evidence.d.ts.map +1 -0
  288. package/dist/hooks/session-end/check-evidence.js +52 -0
  289. package/dist/hooks/session-end/check-evidence.js.map +1 -0
  290. package/dist/hooks/session-end/cleanup-manifest.d.ts +1 -1
  291. package/dist/hooks/session-end/cleanup-manifest.d.ts.map +1 -1
  292. package/dist/hooks/session-end/cleanup-manifest.js +22 -2
  293. package/dist/hooks/session-end/cleanup-manifest.js.map +1 -1
  294. package/dist/hooks/session-end/foreground-bootstrap.d.ts.map +1 -1
  295. package/dist/hooks/session-end/foreground-bootstrap.js +30 -4
  296. package/dist/hooks/session-end/foreground-bootstrap.js.map +1 -1
  297. package/dist/hooks/session-end/guardrails.d.ts +67 -0
  298. package/dist/hooks/session-end/guardrails.d.ts.map +1 -0
  299. package/dist/hooks/session-end/guardrails.js +149 -0
  300. package/dist/hooks/session-end/guardrails.js.map +1 -0
  301. package/dist/hooks/session-end/index.d.ts.map +1 -1
  302. package/dist/hooks/session-end/index.js +14 -6
  303. package/dist/hooks/session-end/index.js.map +1 -1
  304. package/dist/hooks/session-end/routing.d.ts +53 -0
  305. package/dist/hooks/session-end/routing.d.ts.map +1 -0
  306. package/dist/hooks/session-end/routing.js +75 -0
  307. package/dist/hooks/session-end/routing.js.map +1 -0
  308. package/dist/hooks/session-end/spawn-next.d.ts +117 -0
  309. package/dist/hooks/session-end/spawn-next.d.ts.map +1 -0
  310. package/dist/hooks/session-end/spawn-next.js +292 -0
  311. package/dist/hooks/session-end/spawn-next.js.map +1 -0
  312. package/dist/hooks/session-end/worker.d.ts.map +1 -1
  313. package/dist/hooks/session-end/worker.js +45 -5
  314. package/dist/hooks/session-end/worker.js.map +1 -1
  315. package/dist/hooks/task-size-detector/jev-shadow.d.ts +2 -1
  316. package/dist/hooks/task-size-detector/jev-shadow.d.ts.map +1 -1
  317. package/dist/hooks/task-size-detector/jev-shadow.js +19 -1
  318. package/dist/hooks/task-size-detector/jev-shadow.js.map +1 -1
  319. package/dist/installer/__tests__/hook-command-portability.test.js +57 -1
  320. package/dist/installer/__tests__/hook-command-portability.test.js.map +1 -1
  321. package/dist/installer/__tests__/mcp-registry.test.js +98 -0
  322. package/dist/installer/__tests__/mcp-registry.test.js.map +1 -1
  323. package/dist/installer/hooks.d.ts +7 -0
  324. package/dist/installer/hooks.d.ts.map +1 -1
  325. package/dist/installer/hooks.js +15 -0
  326. package/dist/installer/hooks.js.map +1 -1
  327. package/dist/installer/index.d.ts +12 -0
  328. package/dist/installer/index.d.ts.map +1 -1
  329. package/dist/installer/index.js +3 -1
  330. package/dist/installer/index.js.map +1 -1
  331. package/dist/installer/mcp-registry.d.ts.map +1 -1
  332. package/dist/installer/mcp-registry.js +56 -6
  333. package/dist/installer/mcp-registry.js.map +1 -1
  334. package/dist/lib/__tests__/host-load-gate.test.d.ts +2 -0
  335. package/dist/lib/__tests__/host-load-gate.test.d.ts.map +1 -0
  336. package/dist/lib/__tests__/host-load-gate.test.js +377 -0
  337. package/dist/lib/__tests__/host-load-gate.test.js.map +1 -0
  338. package/dist/lib/__tests__/runs-ledger.test.d.ts +2 -0
  339. package/dist/lib/__tests__/runs-ledger.test.d.ts.map +1 -0
  340. package/dist/lib/__tests__/runs-ledger.test.js +99 -0
  341. package/dist/lib/__tests__/runs-ledger.test.js.map +1 -0
  342. package/dist/lib/atomic-write.d.ts +16 -0
  343. package/dist/lib/atomic-write.d.ts.map +1 -1
  344. package/dist/lib/atomic-write.js +27 -4
  345. package/dist/lib/atomic-write.js.map +1 -1
  346. package/dist/lib/host-load-gate.d.ts +110 -0
  347. package/dist/lib/host-load-gate.d.ts.map +1 -0
  348. package/dist/lib/host-load-gate.js +228 -0
  349. package/dist/lib/host-load-gate.js.map +1 -0
  350. package/dist/lib/mode-state-io.d.ts.map +1 -1
  351. package/dist/lib/mode-state-io.js +55 -18
  352. package/dist/lib/mode-state-io.js.map +1 -1
  353. package/dist/lib/runs-ledger.d.ts +45 -0
  354. package/dist/lib/runs-ledger.d.ts.map +1 -0
  355. package/dist/lib/runs-ledger.js +141 -0
  356. package/dist/lib/runs-ledger.js.map +1 -0
  357. package/dist/platform/executable-resolution.d.ts +13 -0
  358. package/dist/platform/executable-resolution.d.ts.map +1 -1
  359. package/dist/platform/executable-resolution.js +16 -0
  360. package/dist/platform/executable-resolution.js.map +1 -1
  361. package/dist/shared/types.d.ts +3 -0
  362. package/dist/shared/types.d.ts.map +1 -1
  363. package/dist/team/__tests__/model-contract.test.js +63 -1
  364. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  365. package/dist/team/__tests__/stage-router.test.js +22 -0
  366. package/dist/team/__tests__/stage-router.test.js.map +1 -1
  367. package/dist/team/__tests__/team-owner-epoch.test.js +33 -0
  368. package/dist/team/__tests__/team-owner-epoch.test.js.map +1 -1
  369. package/dist/team/__tests__/tmux-session.create-team.test.js +60 -2
  370. package/dist/team/__tests__/tmux-session.create-team.test.js.map +1 -1
  371. package/dist/team/__tests__/tmux-session.psmux.test.js +12 -0
  372. package/dist/team/__tests__/tmux-session.psmux.test.js.map +1 -1
  373. package/dist/team/__tests__/tmux-session.test.js +230 -7
  374. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  375. package/dist/team/__tests__/worker-launch-ack.test.js +62 -0
  376. package/dist/team/__tests__/worker-launch-ack.test.js.map +1 -1
  377. package/dist/team/model-contract.d.ts +3 -2
  378. package/dist/team/model-contract.d.ts.map +1 -1
  379. package/dist/team/model-contract.js +35 -10
  380. package/dist/team/model-contract.js.map +1 -1
  381. package/dist/team/runtime-v2.d.ts +13 -0
  382. package/dist/team/runtime-v2.d.ts.map +1 -1
  383. package/dist/team/runtime-v2.js +112 -7
  384. package/dist/team/runtime-v2.js.map +1 -1
  385. package/dist/team/scaling.d.ts.map +1 -1
  386. package/dist/team/scaling.js +4 -1
  387. package/dist/team/scaling.js.map +1 -1
  388. package/dist/team/stage-router.d.ts.map +1 -1
  389. package/dist/team/stage-router.js +3 -1
  390. package/dist/team/stage-router.js.map +1 -1
  391. package/dist/team/team-owner-epoch.d.ts.map +1 -1
  392. package/dist/team/team-owner-epoch.js +4 -7
  393. package/dist/team/team-owner-epoch.js.map +1 -1
  394. package/dist/team/tmux-session.d.ts +8 -1
  395. package/dist/team/tmux-session.d.ts.map +1 -1
  396. package/dist/team/tmux-session.js +71 -19
  397. package/dist/team/tmux-session.js.map +1 -1
  398. package/dist/team/worker-launch-ack.d.ts +1 -1
  399. package/dist/team/worker-launch-ack.d.ts.map +1 -1
  400. package/dist/team/worker-launch-ack.js +28 -1
  401. package/dist/team/worker-launch-ack.js.map +1 -1
  402. package/dist/tools/lsp/__tests__/client-handle-data.test.js +83 -0
  403. package/dist/tools/lsp/__tests__/client-handle-data.test.js.map +1 -1
  404. package/dist/tools/lsp/client.d.ts.map +1 -1
  405. package/dist/tools/lsp/client.js +41 -11
  406. package/dist/tools/lsp/client.js.map +1 -1
  407. package/docs/CLAUDE.md +1 -1
  408. package/docs/HOOKS.md +235 -0
  409. package/docs/MIGRATION.md +132 -0
  410. package/docs/REFERENCE.md +26 -1
  411. package/docs/adr/03672-env-activated-active-mode.md +18 -1
  412. package/docs/design/FACTORY-FINAL-DESIGN.md +114 -0
  413. package/docs/design/P2-RUN-LEDGER-AND-INTAKE-PLAN.md +83 -0
  414. package/docs/factory/t6-acceptance/acceptance-comment.md +36 -0
  415. package/hooks/hooks.json +22 -1
  416. package/package.json +6 -2
  417. package/plugin.json +1 -1
  418. package/scripts/build-contained-fs.mjs +24 -2
  419. package/scripts/ci/check-multirepo-paths.mjs +3 -0
  420. package/scripts/code-simplifier.mjs +24 -2
  421. package/scripts/dev/repro-state-lock.mjs +67 -0
  422. package/scripts/git-guardrails.mjs +581 -0
  423. package/scripts/keyword-detector.mjs +21 -4
  424. package/scripts/lib/atomic-write.mjs +31 -8
  425. package/scripts/lib/jev-shadow.mjs +68 -29
  426. package/scripts/lib/run-reaper.mjs +114 -0
  427. package/scripts/lib/state-lock.mjs +22 -13
  428. package/scripts/post-tool-verifier.mjs +8 -2
  429. package/scripts/postinstall-contained-fs.mjs +56 -0
  430. package/scripts/pre-tool-enforcer.mjs +25 -8
  431. package/scripts/run.cjs +18 -0
  432. package/scripts/runs-reconciler.mjs +103 -0
  433. package/scripts/stale-run-reporter.mjs +73 -0
  434. package/scripts/workflow-drift-guard.mjs +6 -1
  435. package/skills/autopilot/SKILL.md +10 -2
  436. package/skills/harbor/SKILL.md +8 -0
  437. package/skills/omc-setup/phases/04-welcome.md +1 -1
  438. package/skills/ralph/SKILL.md +32 -15
  439. package/skills/refit/SKILL.md +8 -0
  440. package/skills/team/SKILL.md +2 -0
  441. package/templates/hooks/code-simplifier.mjs +24 -2
  442. package/templates/hooks/lib/atomic-write.mjs +31 -8
  443. package/templates/hooks/session-end.mjs +99 -0
  444. package/templates/hooks/workflow-drift-guard.mjs +6 -1
@@ -0,0 +1,83 @@
1
+ # P2: Run ledger and intake CLI — the runtime contract for closeout enforcement and scheduled intake
2
+
3
+ **Status:** planning-only architecture contract; no runtime behavior changes in this PR
4
+ **Origin:** the doctrine trial run and PR #4113/#4117 review cycle; the enforcement-layer design (E0–E3) with E0/E2 already shipped (#4117)
5
+ **Owner:** Yeachan-Heo (final decisions marked **[OWNER]**)
6
+ **Base:** `origin/dev` at the head of the #4113 review cycle
7
+
8
+ ## 1. Scope and non-goals
9
+
10
+ This document is the planning contract for the P2 wave: the runtime pieces of the enforcement layer that cannot live at the hook layer. It defines (A) a durable **run ledger** that makes closeout enforcement possible at all, and (B) an **intake CLI** that gives the harbor headless sweep its missing power switch. It intentionally does **not** change what skills instruct, auto-merge anything, auto-resume any run, infer any approval, or introduce a daemon — every scheduled surface is host-native (cron / Task Scheduler / launchd), never an OMC process.
11
+
12
+ Non-goals inherited from the #4113 review: nothing posts to a tracker or opens a PR without explicit authorization; the guardrail default remains whatever the owner decides on #4113 (this contract is agnostic to that flip).
13
+
14
+ ## 2. Why a contract is needed (the design correction this document records)
15
+
16
+ The enforcement-layer design (E1) originally placed closeout enforcement in a Stop hook. Walking the real sequence invalidates that placement:
17
+
18
+ 1. ralph Step 10 writes the run closeout to the notepad;
19
+ 2. Step 8 runs `/oh-my-copilot:cancel`, which **deletes the mode state file**;
20
+ 3. the session stops; the Stop hook fires with **no state left to read**.
21
+
22
+ A Stop-hook closeout check can therefore never observe a legitimately finished run — it would only ever fire on the mid-run stops that persistent-mode already blocks. The companion idea ("have the stale-run watchdog notice missing closeouts") is equally void: the watchdog only sees **crashed** runs (state still `active`), and a crashed run legitimately has no closeout. Hard closeout enforcement needs a durable trace that survives cancel. That trace is the run ledger.
23
+
24
+ ## 3. Part A — the run ledger
25
+
26
+ ### 3.1 Shape
27
+
28
+ Append-only JSONL at `.omg/state/runs/ledger.jsonl` (respects `OMC_STATE_DIR` via the canonical state-root resolver). One line per lifecycle edge:
29
+
30
+ ```json
31
+ { "ts": "...", "run": "ralph", "sessionId": "...", "event": "start"|"end", "outcome": "running"|"completed"|"failed"|"cancelled", "closeoutWritten": true }
32
+ ```
33
+
34
+ - **start** written when a mode state file transitions to `active: true` (single choke point: `state_write` in `src/lib/mode-state-io.ts` for the four watched modes).
35
+ - **end** written by the cancel/session-end/state-clear path (`state_clear` and the cleanup branches) **before** the mode state file is removed, carrying the outcome and a `closeoutWritten` flag computed by checking the mode's notepad for a write after `startedAt` (mtime comparison — cheap, no content parsing).
36
+ - The ledger is **not** wiped by cancel. It is the durable trace; mode state remains the ephemeral control plane. Rotation: lines beyond a bounded tail (e.g. 1,000) roll to `ledger.jsonl.1` — same pattern as other local logs.
37
+
38
+ ### 3.2 Consumers
39
+
40
+ - **SessionStart reconciliation** (extends the stale-run reporter): for each `end` entry whose `closeoutWritten: false`, report one advisory line — "previous ralph run completed without a closeout; the run's friction was not captured." Advisory only; never mutates.
41
+ - **Promotion evidence**: the enforcement shadow log (`.omg/state/enforcement/shadow.jsonl`, shipped in #4117) gains closeout-rule samples only once the ledger exists — the ledger is the prerequisite for any closeout enforcement, hard or advisory.
42
+
43
+ ### 3.3 Risks
44
+
45
+ - **Concurrency**: two sessions writing the ledger — append-only single-line writes with the existing state-lock helper; worst case an interleaved line, which the JSONL readers already tolerate.
46
+ - **Privacy**: the ledger carries only mode names, timestamps, and booleans — no prompts, no paths beyond the state root.
47
+ - **Compatibility**: `state_clear` callers today expect nothing in return; the write is additive and failure-swallowed (evidence by contract, mirroring `enforcement-log.mjs`).
48
+
49
+ ## 4. Part B — the intake CLI
50
+
51
+ ### 4.1 Surface
52
+
53
+ - `omg intake run --headless` — validates harbor preconditions (tracker reachable, the eight `harbor:*` labels, single-writer attestable), spawns one headless agent session running the harbor `sweep` argument with guardrails enabled, captures the docket link, posts it through `configure-notifications` when configured. Single process; exits when the sweep exits.
54
+ - `omg intake schedule --cron "<expr>"` / `omg intake schedule --off` — registers/removes a **host-native** scheduled entry (cron on Linux/macOS, Task Scheduler on Windows) pointing at `omg intake run --headless`. The timer belongs to the OS; OMC still runs no daemon (harbor's own non-goal is preserved verbatim).
55
+
56
+ ### 4.2 Preconditions and refusals
57
+
58
+ Schedule installation refuses (loudly, no silent install) when: the tracker is unreachable; labels are missing and cannot be created; single-writer cannot be attested; or no notification channel exists **and** the user has not confirmed the docket-only fallback. A headless sweep never widens communication scope and never creates standing rules — those wait for a signed session (harbor's own contract, unchanged).
59
+
60
+ ### 4.3 Risks
61
+
62
+ - **Credentials**: headless gh needs a token; the CLI surfaces exactly which credential is missing rather than degrading to a half-run.
63
+ - **Surface area**: this is the first `src/cli` change in the enforcement family — the bridge build chain must be exercised (`npm run build:cli`), and the CLI help snapshot tests updated.
64
+
65
+ ## 5. Sequencing
66
+
67
+ 1. **A** (run ledger) — one slice: ledger writes + SessionStart reconciliation + tests. No skill text changes.
68
+ 2. **B** (intake CLI) — one slice: CLI + schedule contract + tests. Depends on nothing from A.
69
+ 3. **E1 promotion** — after A ships and the reconciliation advisory accumulates samples, the closeout rule can move from advisory to enforced **[OWNER]**.
70
+
71
+ ## 6. Open questions for the owner
72
+
73
+ 1. **[OWNER]** Ledger location: `.omg/state/runs/ledger.jsonl` vs `.omg/logs/` — state (control-plane adjacent) or logs (audit-like)?
74
+ 2. **[OWNER]** Retention bound for the ledger tail (proposed 1,000 lines, rotate on overflow)?
75
+ 3. **[OWNER]** Should `omg intake schedule` be allowed to install without a notification channel (docket-only fallback), or is a channel mandatory?
76
+
77
+ ## 7. Verification checklist for changes in this contract
78
+
79
+ 1. Ledger write on activation, on cancel, on session-end crash path (simulate kill: no `end` entry — the gap is itself the signal the reconciliation reports).
80
+ 2. Reconciliation advisory appears for `closeoutWritten: false` and stays silent for true closeouts.
81
+ 3. Intake schedule install refusals covered (tracker down, labels missing, single-writer unattestable).
82
+ 4. Hook latency budgets unchanged (Stop hooks remain ≤ their declared timeouts; ledger writes are on the cancel path, not the Stop path).
83
+ 5. `dist/`/`bridge/` artifacts never committed; `npm run build`, `plugin:shipping:verify`, `prompt-ssot:check`, `lint` green.
@@ -0,0 +1,36 @@
1
+ # T6 验收报告:软件工厂闭环正式实现(对正式实现重跑演练)
2
+
3
+ - 日期:2026-09-28;演练场:`pangpang778/factory-demo` issue #1(退货退款用例)
4
+ - 被验代码:分支 `factory-t6-acceptance`(spec #9 正式实现),编译产物 `dist/hooks/session-end/*`、`dist/factory/listener.js`
5
+ - 方法:三项演练(金路径 / 失败注入 / 护栏触发),全程真实 HMAC 签名 webhook、真实标签、真实 gh 回写、真实 detached claude 会话
6
+ - 证据包:分支 `factory-t6-acceptance` `docs/factory/t6-acceptance/evidence/`(审计 jsonl、decision ledger、handoff ×2、护栏 stop marker + usage、intent 草稿、金路径 timeline、演练驱动脚本)
7
+
8
+ ## 判据逐条结论
9
+
10
+ **判据 1(intake 标签 → intake 会话自动起):绿。** 签名 POST → 202 `spawned intent session (intent)`,审计记 `routed`(`evidence/factory-listener-audit.jsonl`),真实 claude 会话以 `/intent 处理 tracker 进货:…` 提示词自动启动、intent 技能装载(transcripts d6989e55 / ba18aaef / d314390f)。非绿段:首次尝试(listener 以 worktree 为 cwd 启动)spawn 的会话 f2f76121 首次 API 调用即死(模型 claude-sonnet-4-6 被代理拒)。根因:listener.ts:114 spawn 无 `cwd` 选项,子进程继承 listener 进程 cwd,`--cwd` 仅喂审计路径;以「从演练目录启动 listener」为文档化姿势重跑后稳定。归属 listener 跟进。
11
+
12
+ **判据 2(草稿按契约回写):绿。** 多轮追问(issue 评论)后自动回写 `docs/intents/return-refund-flow/intent.md`(五段 + 3 条非阻塞未决,`evidence/intent-draft-return-refund-flow.md`)、指针评论、标签 `intake → needs-review`(评论 5866170890 / 5866239914 / 5866302124)。诚实备注:轮间续接靠重新 POST webhook —— 正式实现应由 SessionEnd→链推进 enqueuer 完成,而 enqueuer 未实现(见红项 1)。
13
+
14
+ **判据 3(人接受 → launch 会话自动起 + handoff 正确):绿(含备注)。** 人闸记录评论 5866386028(signer: PangHong)、标签 `needs-review → accepted`;真实 `executeSpawnNext` + defaultSpawnFn:`acquireChainSlot('return-refund-flow')` allowed linkIndex=1,handoff `evidence/return-refund-flow-launch.json`(success:intent-accepted → launch,context 指向已接受 intent),tracker 评论「链已推进到 launch」,launch 会话 a2524410 于 08:34:38 自动起并定位到 handoff。备注:launch 技能 yard gate 需要目标仓 `scripts/shipyard-audit.mjs`,演练仓未铺设(T5 缺口),会话按技能定义 BLOCKED 收场;`launch` 标签未预置,detached shell 里 `gh --add-label` 静默失败,操作员补建补挂 —— tracker 命令失败可观测性是跟进项。
15
+
16
+ **判据 4(机械对照自动过闸,signer = 判据事实):绿。** `gradeGate('spec-approve', 全绿)` → auto-pass,signerFact「分级判据均未触发,机械验证项全部通过,自动过」(`evidence/t6-decision-ledger.json`)。
17
+
18
+ **判据 5(先例性取舍升人闸,留痕):绿。** 判据一/二/机械未过三类 facts 全部升 human 且留触发判据文案;intent-accept、review-approve 固定人闸(ledger 共 6 条:5 human + 1 auto)。
19
+
20
+ **判据 6(失败注入 → failed + 告警 + 链停住):绿(注入点诚实标注)。** 6a:生产路由表 + `failed:budget-exhausted` → plan null:0 spawn、链静默停住(`evidence/t6-exercise-evidence.json` 2A)。6b:spawnFn 注入抛错 → 真实告警评论「链已停住:… v1 无自动重试」+ 真实 failed 标签落 issue #1(`evidence/t6-exercise-2b.txt` + issue 评论/标签可查)。诚实边界:告警路径仅在 spawn 同步抛错时可达,defaultSpawnFn(shell:true)不同步抛 → 生产可达性≈0,子进程生死无观测(与判据 1 首败静默一致)。归属 listener/T2 跟进。
21
+
22
+ **判据 7(每日 N=10 护栏):绿。** 同 intent 当日 ×10 acquire 全过,第 11 次 `daily-cap` 拒绝、中文 detail、真实 stop marker `evidence/chain-t6-demo-refund.stopped.json` 落盘,`evidence/chain-usage.json` 计数 10。LOW 缺陷:guardrails.ts:131 拒绝 detail 引用 stopMarkerPath 漏传 stateRoot,提示路径与实际落盘根不一致(marker 本体正确)。
23
+
24
+ **判据 8(全程可审计 / 黑灯度量):绿。** 每环有记录:listener 审计 jsonl、handoff ×2、usage + stop marker、gate ledger ×6、issue 全程评论链。黑灯度量:gate 判定合计 7(ledger 6 + 实链 intent-accept 1),人签 6 → **6/7 ≈ 86%**;唯一非人签为 spec-approve 全绿 auto-pass,signer = 判据事实(设计如此)。
25
+
26
+ ## 红项归属(无未归属红项)
27
+ 1. **SessionEnd→链推进 enqueuer 未实现**:src 内无构造/入队 spawn-next action 的生产调用方(类型在 cleanup-manifest.ts:7、dispatch 在 worker.ts:47-53)。无闭环工票覆盖,建议开跟进票。
28
+ 2. **listener spawn 三缺口**:无 cwd 选项(子进程 cwd 继承 listener 进程);子进程生死/退出无观测;tracker 命令 detached shell 失败静默。归属 listener(T2/T4 跟进)。
29
+ 3. **guardrails.ts:131 detail 路径 LOW**(见判据 7)。
30
+ 4. **T5 铺设缺口**:演练仓缺 shipyard 审计机械与 launch 标签预置。
31
+
32
+ ## 操作员侧修复披露(非实现改动)
33
+ listener 以演练目录为 cwd 重启一次;演练目录 trust 与 allow-list 预置;轮间回答与人闸接受由操作员以 pangpang778 身份在 issue 留痕(人机协作「人」的一侧)。
34
+
35
+ ## 结论
36
+ **8/8 判据全绿**(判据 3 含 T5 铺设备注、判据 6 注入点诚实标注)。红项均为实现跟进而非验收阻塞,按归属开跟进票即可。
package/hooks/hooks.json CHANGED
@@ -36,6 +36,16 @@
36
36
  "type": "command",
37
37
  "command": "node \"${CLAUDE_PLUGIN_ROOT}\"/scripts/run.cjs \"${CLAUDE_PLUGIN_ROOT}\"/scripts/wiki-session-start.mjs",
38
38
  "timeout": 5
39
+ },
40
+ {
41
+ "type": "command",
42
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}\"/scripts/run.cjs \"${CLAUDE_PLUGIN_ROOT}\"/scripts/stale-run-reporter.mjs",
43
+ "timeout": 5
44
+ },
45
+ {
46
+ "type": "command",
47
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}\"/scripts/run.cjs \"${CLAUDE_PLUGIN_ROOT}\"/scripts/runs-reconciler.mjs",
48
+ "timeout": 5
39
49
  }
40
50
  ]
41
51
  },
@@ -70,6 +80,16 @@
70
80
  "timeout": 5
71
81
  }
72
82
  ]
83
+ },
84
+ {
85
+ "matcher": "Bash",
86
+ "hooks": [
87
+ {
88
+ "type": "command",
89
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}\"/scripts/run.cjs \"${CLAUDE_PLUGIN_ROOT}\"/scripts/git-guardrails.mjs",
90
+ "timeout": 5
91
+ }
92
+ ]
73
93
  }
74
94
  ],
75
95
  "PermissionRequest": [
@@ -96,7 +116,8 @@
96
116
  {
97
117
  "type": "command",
98
118
  "command": "node \"${CLAUDE_PLUGIN_ROOT}\"/scripts/run.cjs \"${CLAUDE_PLUGIN_ROOT}\"/scripts/project-memory-posttool.mjs",
99
- "timeout": 3
119
+ "timeout": 3,
120
+ "async": true
100
121
  },
101
122
  {
102
123
  "type": "command",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-copilot",
3
- "version": "5.5.0",
3
+ "version": "5.6.2",
4
4
  "description": "Multi-agent orchestration system for Copilot CLI - Inspired by oh-my-opencode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -34,6 +34,9 @@
34
34
  "bridge/runtime-cli.cjs",
35
35
  "commands",
36
36
  "hooks",
37
+ "scripts/build-contained-fs.mjs",
38
+ "scripts/postinstall-contained-fs.mjs",
39
+ "scripts/verify-graph-contained-fs.mjs",
37
40
  "scripts",
38
41
  "skills",
39
42
  "templates",
@@ -92,6 +95,7 @@
92
95
  "generate:prompt-projections": "node scripts/generate-prompt-projections.mjs",
93
96
  "verify:prompt-projections": "node scripts/generate-prompt-projections.mjs --verify",
94
97
  "build:contained-fs": "node scripts/build-contained-fs.mjs",
98
+ "postinstall": "node scripts/postinstall-contained-fs.mjs",
95
99
  "build:copilot-hooks": "node scripts/copilot/build-hooks.mjs --write",
96
100
  "verify:copilot-hooks": "node scripts/copilot/build-hooks.mjs --verify",
97
101
  "build:copilot-agents": "node scripts/copilot/build-agents.mjs --write",
@@ -155,5 +159,5 @@
155
159
  "publishConfig": {
156
160
  "access": "public"
157
161
  },
158
- "gitHead": "f9bc06177e37904aa42cabce644b56340e8c44b0"
162
+ "gitHead": "dff284086ef69f7bd488ba13346e66a90180d671"
159
163
  }
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-copilot",
3
- "version": "5.5.0",
3
+ "version": "5.6.2",
4
4
  "description": "Multi-agent orchestration system for GitHub Copilot CLI",
5
5
  "author": {
6
6
  "name": "oh-my-copilot contributors"
@@ -6,8 +6,24 @@ import { spawnSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  // Build-time only. Runtime never invokes a compiler or downloads a binary.
9
- if (process.platform !== 'darwin' && !process.argv.includes('--force')) process.exit(0);
10
- if (!['darwin', 'linux'].includes(process.platform)) throw new Error('Unsupported native build platform');
9
+
10
+ // Original behavior: darwin only, unless --optional or --force is passed
11
+ const isOptional = process.argv.includes('--optional');
12
+ const isForceBuild = process.argv.includes('--force');
13
+
14
+ // Skip on non-darwin platforms unless explicitly forced or optional
15
+ if (process.platform !== 'darwin' && !isForceBuild && !isOptional) {
16
+ process.exit(0);
17
+ }
18
+
19
+ // Fail loudly if platform is unsupported AND not optional
20
+ if (!['darwin', 'linux'].includes(process.platform)) {
21
+ if (isOptional) {
22
+ process.exit(0);
23
+ }
24
+ throw new Error('Unsupported native build platform');
25
+ }
26
+
11
27
  const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
12
28
  const explicit = process.argv.find(arg => arg.startsWith('--headers='))?.slice('--headers='.length);
13
29
  const version = process.versions.node;
@@ -20,10 +36,16 @@ const candidates = [
20
36
  '/usr/local/include/node',
21
37
  '/usr/include/node',
22
38
  ].filter(Boolean);
39
+
23
40
  const headers = candidates.find(path => existsSync(join(path, 'node_api.h')));
24
41
  if (!headers) {
42
+ if (isOptional) {
43
+ // Graceful skip for optional builds
44
+ process.exit(0);
45
+ }
25
46
  throw new Error('Node development headers are required. Supply --headers=/absolute/path/to/include/node (node_api.h), or populate the node-gyp cache before building. No headers are downloaded by this script.');
26
47
  }
48
+
27
49
  for (const arch of process.platform === 'darwin' ? ['arm64', 'x64'] : [process.arch]) {
28
50
  const output = join(root, 'native', `contained-fs-${process.platform}-${arch}.node`);
29
51
  mkdirSync(dirname(output), { recursive: true });
@@ -36,6 +36,9 @@ const WHITELIST_FILES = new Set([
36
36
  'scripts/pre-tool-enforcer.mjs',
37
37
  'scripts/skill-injector.mjs',
38
38
  'scripts/session-start.mjs',
39
+ 'scripts/code-simplifier.mjs',
40
+ // Hook templates (shipped in distribution, own resolver pre-dist)
41
+ 'templates/hooks/code-simplifier.mjs',
39
42
  // Multi-repo test fixtures and audits (construct fake .omc trees)
40
43
  'scripts/smoke-multirepo.mjs',
41
44
  'scripts/audit-multirepo-e2e.mjs',
@@ -6,7 +6,9 @@
6
6
  * Intercepts Stop events to automatically delegate recently modified source files
7
7
  * to the code-simplifier agent for cleanup and simplification.
8
8
  *
9
- * Opt-in via ~/.omg/config.json: { "codeSimplifier": { "enabled": true } }
9
+ * Opt-in via the global OMC config.json: { "codeSimplifier": { "enabled": true } }
10
+ * ($OMC_HOME/config.json, else ${XDG_CONFIG_HOME:-~/.config}/omc/config.json on
11
+ * Linux/Unix, with legacy ~/.omg/config.json as the fallback)
10
12
  * Default: disabled (must explicitly opt in)
11
13
  */
12
14
 
@@ -48,8 +50,28 @@ function readJsonFile(filePath) {
48
50
  }
49
51
  }
50
52
 
53
+ // Mirrors src/utils/paths.ts:getGlobalOmcConfigCandidates('config.json'):
54
+ // OMC_HOME alone when set; otherwise the XDG config root on Linux/Unix, then
55
+ // the legacy ~/.omg fallback. The first file that exists wins.
56
+ function getGlobalOmcConfigCandidates() {
57
+ const explicitRoot = process.env.OMC_HOME?.trim();
58
+ if (explicitRoot) return [join(explicitRoot, 'config.json')];
59
+
60
+ const home = process.platform === 'win32'
61
+ ? process.env.USERPROFILE || process.env.HOME || homedir()
62
+ : process.env.HOME || homedir();
63
+ const legacy = join(home, '.omg', 'config.json');
64
+ if (process.platform === 'win32' || process.platform === 'darwin') return [legacy];
65
+
66
+ const configHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
67
+ return [...new Set([join(configHome, 'omc', 'config.json'), legacy])];
68
+ }
69
+
51
70
  function readOmcConfig() {
52
- return readJsonFile(join(homedir(), '.omg', 'config.json'));
71
+ for (const configPath of getGlobalOmcConfigCandidates()) {
72
+ if (existsSync(configPath)) return readJsonFile(configPath);
73
+ }
74
+ return null;
53
75
  }
54
76
 
55
77
  function isEnabled(config) {
@@ -0,0 +1,67 @@
1
+ // Repro for upstream issue #4146: mutual exclusion of the owner-file fallback in
2
+ // scripts/lib/state-lock.mjs (owner releases/exits during a reclaimer's liveness
3
+ // probe; the reclaimer must not quarantine a live replacement owner).
4
+ //
5
+ // Usage (from any cwd): node scripts/dev/repro-state-lock.mjs [procs=8] [iterations=15]
6
+ //
7
+ // Spawns `procs` worker processes that each acquire/increment/release a shared
8
+ // counter `iterations` times. Children run with NODE_ENV=test
9
+ // OMC_TEST_FLOCK_AVAILABLE=0 to force the owner-file fallback (the same path
10
+ // taken when better-sqlite3 cannot load). Prints acquisitions vs. counter,
11
+ // overlaps, release/acquire failures, and a final RESULT line
12
+ // (OK | MUTUAL EXCLUSION VIOLATED | LOCK STRANDED).
13
+ //
14
+ // Worker mode (used internally and by tests/integration/state-lock-owner-reclaim.test.ts):
15
+ // node scripts/dev/repro-state-lock.mjs worker <target> <iterations> <log>
16
+ import { spawn } from 'node:child_process';
17
+ import { appendFileSync, closeSync, existsSync, mkdirSync, mkdtempSync, openSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
18
+ import { tmpdir } from 'node:os';
19
+ import { join } from 'node:path';
20
+ import { fileURLToPath } from 'node:url';
21
+
22
+ const [, , role, ...args] = process.argv;
23
+
24
+ if (role === 'worker') {
25
+ const lib = await import('../lib/state-lock.mjs');
26
+ const [target, iterations, log] = args;
27
+ const inside = `${target}.inside`; // created O_EXCL inside the critical section
28
+ const deadline = Date.now() + 60_000; // keep the run bounded if a lock gets stranded
29
+ for (let i = 0; i < Number(iterations) && Date.now() < deadline; i++) {
30
+ const lock = lib.acquireStateFileLockSync(target, 50);
31
+ if (!lock) {
32
+ const message = lib.getStateFileLockFailureMessage();
33
+ appendFileSync(log, `${process.pid} acquire-failed: ${/contention/.test(message) ? 'contention' : /could not be verified/.test(message) ? 'unverifiable' : message}\n`);
34
+ continue;
35
+ }
36
+ let marker = true;
37
+ try { closeSync(openSync(inside, 'wx')); } catch { marker = false; appendFileSync(log, `${process.pid} OVERLAP: another process is inside the critical section\n`); }
38
+ const n = Number(readFileSync(target, 'utf8'));
39
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5); // hold the lock ~5 ms
40
+ writeFileSync(target, String(n + 1));
41
+ if (marker) unlinkSync(inside);
42
+ appendFileSync(log, `${process.pid} acquired\n`);
43
+ if (!lib.releaseStateFileLockSync(lock)) appendFileSync(log, `${process.pid} release-failed: ${lib.getStateFileLockFailureMessage()}\n`);
44
+ }
45
+ } else {
46
+ const procs = Number(role || 8), iterations = Number(args[0] || 15);
47
+ const dir = mkdtempSync(join(tmpdir(), 'omc-lock-repro-'));
48
+ mkdirSync(join(dir, 'state'));
49
+ const target = join(dir, 'state', 'counter.json');
50
+ const log = join(dir, 'log.txt');
51
+ writeFileSync(target, '0'); writeFileSync(log, '');
52
+ // Force the owner-file fallback (same path taken when better-sqlite3 cannot load).
53
+ const env = { ...process.env, NODE_ENV: 'test', OMC_TEST_FLOCK_AVAILABLE: '0' };
54
+ const t0 = Date.now();
55
+ await Promise.all(Array.from({ length: procs }, () => new Promise(resolve =>
56
+ spawn(process.execPath, [fileURLToPath(import.meta.url), 'worker', target, String(iterations), log], { env, stdio: 'inherit' }).on('exit', resolve))));
57
+ const lines = readFileSync(log, 'utf8').split('\n').filter(Boolean);
58
+ const count = re => lines.filter(l => re.test(l)).length;
59
+ const acquired = count(/ acquired$/), counter = Number(readFileSync(target, 'utf8'));
60
+ console.log(`platform=${process.platform} node=${process.version} procs=${procs} iterations=${iterations} elapsed=${Date.now() - t0}ms`);
61
+ console.log(`acquisitions=${acquired} counter=${counter} lostUpdates=${acquired - counter} overlaps=${count(/OVERLAP/)} releaseFailures=${count(/release-failed/)} acquireFailures=${count(/acquire-failed/)}`);
62
+ const stranded = existsSync(`${target}.mutation.lock`);
63
+ if (stranded) console.log(`lock file still present after all workers exited:${readFileSync(`${target}.mutation.lock`, 'utf8')}`);
64
+ for (const l of [...new Set(lines.filter(l => !/ acquired$/.test(l)).map(l => l.replace(/^\d+ /, '')))].slice(0, 6)) console.log(` ${l}`);
65
+ const violated = acquired !== counter || count(/OVERLAP/) > 0;
66
+ console.log(`RESULT: ${violated ? 'MUTUAL EXCLUSION VIOLATED' : stranded ? 'LOCK STRANDED' : 'OK'}`);
67
+ }