oh-my-opencode 5.0.0-beta.34 → 5.0.0-beta.36

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 (220) hide show
  1. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  2. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  3. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  4. package/README.ja.md +1 -1
  5. package/README.ko.md +1 -1
  6. package/README.md +1 -1
  7. package/README.ru.md +1 -1
  8. package/README.zh-cn.md +1 -1
  9. package/THIRD-PARTY-NOTICES.md +27 -99
  10. package/dist/cli/index.js +48341 -48541
  11. package/dist/cli-node/index.js +49016 -49216
  12. package/dist/config/index.d.ts +1 -1
  13. package/dist/config/schema/hooks.d.ts +0 -1
  14. package/dist/config/schema/oh-my-opencode-config.d.ts +0 -10
  15. package/dist/config/schema.d.ts +0 -1
  16. package/dist/create-hooks.d.ts +0 -1
  17. package/dist/hooks/index.d.ts +0 -1
  18. package/dist/index.js +11675 -13718
  19. package/dist/mcp/index.d.ts +0 -4
  20. package/dist/mcp/types.d.ts +0 -1
  21. package/dist/oh-my-opencode.schema.json +1 -45
  22. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
  23. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
  24. package/dist/shared/omo-process-sweep.d.ts +2 -4
  25. package/dist/skills/init-deep/SKILL.md +13 -13
  26. package/dist/skills/ulw-execute/SKILL.md +9 -9
  27. package/dist/skills/ulw-plan/SKILL.md +0 -1
  28. package/dist/tui.js +44809 -44883
  29. package/package.json +16 -21
  30. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +0 -17
  31. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -3
  32. package/packages/omo-codex/plugin/.mcp.json +0 -6
  33. package/packages/omo-codex/plugin/AGENTS.md +5 -5
  34. package/packages/omo-codex/plugin/README.md +1 -1
  35. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1 -15
  36. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  37. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  39. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  40. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  41. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  43. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  44. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
  45. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  46. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  47. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  49. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  50. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  51. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  52. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +1 -1
  53. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +2 -2
  56. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  57. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  58. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +0 -1
  59. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  60. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
  61. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  62. package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -1
  63. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +2 -2
  64. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  65. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  66. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +1 -0
  67. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -0
  68. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +10 -3
  69. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +35 -38
  70. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +278 -193
  71. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +5 -0
  72. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +7 -51
  73. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +39 -22
  74. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  75. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +64 -8
  76. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  77. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +37 -18
  78. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  79. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  80. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -1
  81. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  82. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +6 -0
  83. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +10 -3
  84. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +32 -63
  85. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +7 -53
  86. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +50 -31
  87. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +67 -14
  88. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  89. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +36 -17
  90. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +26 -0
  91. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +47 -2
  92. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  93. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  94. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  95. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  96. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  99. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  115. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  116. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  117. package/packages/omo-codex/plugin/package-lock.json +12 -146
  118. package/packages/omo-codex/plugin/package.json +1 -2
  119. package/packages/omo-codex/plugin/scripts/AGENTS.md +0 -1
  120. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +0 -1
  121. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  122. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  123. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  124. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  125. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  126. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
  127. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  128. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +2 -2
  129. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +11 -19
  130. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -1
  131. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +0 -1
  132. package/packages/omo-codex/plugin/test/AGENTS.md +2 -2
  133. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +2 -21
  134. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -2
  135. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  136. package/packages/omo-codex/plugin/test/auto-update.test.mjs +0 -25
  137. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  138. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +0 -50
  139. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +0 -1
  140. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  141. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  142. package/packages/omo-codex/scripts/install-dist/install-local.mjs +227 -435
  143. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  144. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  145. package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
  146. package/packages/shared-skills/skills/ulw-execute/SKILL.md +9 -9
  147. package/packages/shared-skills/skills/ulw-plan/SKILL.md +0 -1
  148. package/dist/config/schema/codegraph.d.ts +0 -12
  149. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  150. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  151. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  152. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  153. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  154. package/dist/mcp/codegraph.d.ts +0 -16
  155. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  156. package/packages/omo-codex/plugin/components/codegraph/LICENSE +0 -21
  157. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  158. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  159. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12326
  160. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9908
  161. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  162. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  163. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  164. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  165. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  166. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  167. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  168. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -310
  169. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -92
  170. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  171. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  172. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  173. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  174. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  175. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -22
  176. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  177. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  178. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  179. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  180. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  181. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  182. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  183. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  184. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  185. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  186. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  187. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  188. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  189. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  190. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  191. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  192. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  193. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  194. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  195. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  196. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  197. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  198. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  199. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +0 -47
  200. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  201. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  202. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  203. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  204. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  205. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  206. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  207. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  208. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  209. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  210. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  211. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  212. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +0 -101
  213. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  214. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  215. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  216. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  217. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  218. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  219. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  220. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
@@ -78,9 +78,9 @@ describe("getCodexOmoConfig", () => {
78
78
  writeOmoConfig(
79
79
  homeDir,
80
80
  JSON.stringify({
81
- codegraph: { enabled: true, install_dir: "/base" },
82
- "[codex]": { codegraph: { enabled: false } },
83
- "[opencode]": { codegraph: { install_dir: "/opencode-only" } },
81
+ telemetry: { enabled: true },
82
+ "[codex]": { telemetry: { enabled: false } },
83
+ "[opencode]": { telemetry: { enabled: true } },
84
84
  }),
85
85
  )
86
86
 
@@ -88,120 +88,36 @@ describe("getCodexOmoConfig", () => {
88
88
  const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
89
89
 
90
90
  // then
91
- expect(result.codegraph).toEqual({
92
- auto_provision: true,
93
- daemon: true,
94
- enabled: false,
95
- install_dir: "/base",
96
- telemetry: false,
97
- })
98
- expect(result.trustedCodegraphInstallDir).toBe("/base")
99
- })
100
-
101
- it("#given project SOT sets install_dir #when loading config #then only the effective value changes while trusted install root stays global", () => {
102
- // given
103
- const homeDir = createTemporaryDirectory("omo-codex-shared-trusted-home-")
104
- const cwd = createTemporaryDirectory("omo-codex-shared-trusted-project-")
105
- writeOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: true, install_dir: "/global-codegraph" } }))
106
- writeOmoConfig(cwd, JSON.stringify({ codegraph: { install_dir: "/project-codegraph" } }))
107
-
108
- // when
109
- const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
110
-
111
- // then
112
- expect(result.codegraph?.install_dir).toBe("/project-codegraph")
113
- expect(result.trustedCodegraphInstallDir).toBe("/global-codegraph")
114
- })
115
-
116
- it("#given codex SOT sets CodeGraph excluded roots #when loading config #then roots are returned to hooks", () => {
117
- // given
118
- const homeDir = createTemporaryDirectory("omo-codex-shared-excluded-home-")
119
- const cwd = createTemporaryDirectory("omo-codex-shared-excluded-project-")
120
- writeOmoConfig(
121
- homeDir,
122
- JSON.stringify({
123
- "[codex]": { codegraph: { excluded_roots: ["/tmp/omo-research", "/private/tmp/omo-research"] } },
124
- }),
125
- )
126
-
127
- // when
128
- const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
129
-
130
- // then
131
- expect(result.codegraph?.excluded_roots).toEqual(["/tmp/omo-research", "/private/tmp/omo-research"])
132
- })
133
-
134
- it("#given codex SOT sets the SessionStart cooldown #when loading config #then the configured base interval is returned", () => {
135
- // given
136
- const homeDir = createTemporaryDirectory("omo-codex-shared-cooldown-home-")
137
- const cwd = createTemporaryDirectory("omo-codex-shared-cooldown-project-")
138
- writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { session_start_cooldown_ms: 900_000 } } }))
139
-
140
- // when
141
- const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
142
-
143
- // then
144
- expect(result.codegraph?.session_start_cooldown_ms).toBe(900_000)
91
+ expect(result.telemetry?.enabled).toBe(false)
145
92
  expect(result.warnings).toEqual([])
146
93
  })
147
94
 
148
- it("#given no codegraph.daemon key #when loading config #then daemon defaults to on", () => {
95
+ it("#given a project SOT layer #when loading config #then the project value overrides the user layer", () => {
149
96
  // given
150
- const homeDir = createTemporaryDirectory("omo-codex-shared-daemon-default-home-")
151
- const cwd = createTemporaryDirectory("omo-codex-shared-daemon-default-project-")
152
- writeOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: true } }))
97
+ const homeDir = createTemporaryDirectory("omo-codex-shared-project-home-")
98
+ const cwd = createTemporaryDirectory("omo-codex-shared-project-project-")
99
+ writeOmoConfig(homeDir, JSON.stringify({ task: { default_concurrency: 3 } }))
100
+ writeOmoConfig(cwd, JSON.stringify({ task: { default_concurrency: 7 } }))
153
101
 
154
102
  // when
155
103
  const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
156
104
 
157
105
  // then
158
- expect(result.codegraph?.daemon).toBe(true)
159
- expect(result.warnings).toEqual([])
106
+ expect(result.task?.default_concurrency).toBe(7)
160
107
  })
161
108
 
162
- it("#given codex SOT sets codegraph.daemon=false #when loading config #then daemon opt-out is returned", () => {
109
+ it("#given a codex SOT setting with the wrong type #when loading config #then the value is rejected with a warning", () => {
163
110
  // given
164
- const homeDir = createTemporaryDirectory("omo-codex-shared-daemon-off-home-")
165
- const cwd = createTemporaryDirectory("omo-codex-shared-daemon-off-project-")
166
- writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: false } } }))
111
+ const homeDir = createTemporaryDirectory("omo-codex-shared-invalid-home-")
112
+ const cwd = createTemporaryDirectory("omo-codex-shared-invalid-project-")
113
+ writeOmoConfig(homeDir, JSON.stringify({ telemetry: { enabled: true }, "[codex]": { telemetry: { enabled: "yes" } } }))
167
114
 
168
115
  // when
169
116
  const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
170
117
 
171
118
  // then
172
- expect(result.codegraph?.daemon).toBe(false)
173
- expect(result.warnings).toEqual([])
174
- })
175
-
176
- it("#given codex SOT sets codegraph.daemon to a non-boolean #when loading config #then the value is rejected with a warning", () => {
177
- // given
178
- const homeDir = createTemporaryDirectory("omo-codex-shared-daemon-invalid-home-")
179
- const cwd = createTemporaryDirectory("omo-codex-shared-daemon-invalid-project-")
180
- writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: "yes" } } }))
181
-
182
- // when
183
- const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
184
-
185
- // then
186
- expect(result.codegraph?.daemon).toBe(true)
187
- expect(result.warnings).toContain(`Invalid omo config at ${join(homeDir, ".omo", "omo.jsonc")}: [codex].codegraph.daemon`)
188
- })
189
-
190
- it("#given legacy env override and SOT value #when loading config #then env wins over the SOT", () => {
191
- // given
192
- const homeDir = createTemporaryDirectory("omo-codex-shared-env-")
193
- const cwd = createTemporaryDirectory("omo-codex-project-env-")
194
- writeOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: false } }))
195
-
196
- // when
197
- const result = getCodexOmoConfig({
198
- cwd,
199
- homeDir,
200
- env: { CODEX_CODEGRAPH_ENABLED: "1" },
201
- })
202
-
203
- // then
204
- expect(result.codegraph?.enabled).toBe(true)
119
+ expect(result.telemetry).toBeUndefined()
120
+ expect(result.warnings).toContain(`Invalid omo config at ${join(homeDir, ".omo", "omo.jsonc")}: [codex].telemetry.enabled`)
205
121
  })
206
122
 
207
123
  it("#given no SOT files #when loading config #then returns built-in defaults and missing global source", () => {
@@ -213,12 +129,8 @@ describe("getCodexOmoConfig", () => {
213
129
  const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
214
130
 
215
131
  // then
216
- expect(result.codegraph).toEqual({
217
- auto_provision: true,
218
- daemon: true,
219
- enabled: true,
220
- telemetry: false,
221
- })
132
+ expect(result.telemetry).toBeUndefined()
133
+ expect(result.warnings).toEqual([])
222
134
  expect(result.sources).toContainEqual({
223
135
  exists: false,
224
136
  loaded: false,
@@ -227,23 +139,10 @@ describe("getCodexOmoConfig", () => {
227
139
  })
228
140
  })
229
141
 
230
- it("#given codex-unsupported codegraph setting #when loading config #then returns loader warnings", () => {
231
- // given
232
- const homeDir = createTemporaryDirectory("omo-codex-shared-warnings-")
233
- const cwd = createTemporaryDirectory("omo-codex-project-warnings-")
234
- writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { watch_debounce_ms: 42 } } }))
235
-
236
- // when
237
- const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
238
-
239
- // then
240
- expect(result.warnings).toContain("codegraph.watch_debounce_ms is not supported for harness codex")
241
- })
242
-
243
142
  it("#given only legacy config.jsonc #when codex starts #then migrates once with a backup before loading the unified codex view", () => {
244
143
  // given
245
144
  const homeDir = createTemporaryDirectory("omo-codex-legacy-upgrade-")
246
- writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: false } } }))
145
+ writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
247
146
  const legacyPath = join(homeDir, ".omo", "config.jsonc")
248
147
 
249
148
  // when
@@ -252,7 +151,7 @@ describe("getCodexOmoConfig", () => {
252
151
  const second = getCodexOmoConfig({ cwd: homeDir, homeDir, env: {} })
253
152
 
254
153
  // then
255
- expect(first.codegraph?.daemon).toBe(false)
154
+ expect(first.telemetry?.enabled).toBe(false)
256
155
  expect(first.warnings.some((warning) => warning.startsWith("omo-codex: migrated legacy configuration from ")
257
156
  && warning.endsWith("/.omo/config.jsonc"))).toBe(true)
258
157
  expect(readOmoJson(homeDir)["_migrations"]).toEqual(["2026-07-codex-config-jsonc"])
@@ -266,8 +165,8 @@ describe("getCodexOmoConfig", () => {
266
165
  it("#given a legacy migration conflict #when codex starts #then exposes the migration summary and conflict through loader warnings", () => {
267
166
  // given
268
167
  const homeDir = createTemporaryDirectory("omo-codex-legacy-conflict-")
269
- writeOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: true } }))
270
- writeLegacyOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: false } }))
168
+ writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: true } } }))
169
+ writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
271
170
 
272
171
  // when
273
172
  const result = getCodexOmoConfig({ cwd: homeDir, homeDir, env: {} })
@@ -275,7 +174,7 @@ describe("getCodexOmoConfig", () => {
275
174
  // then
276
175
  expect(result.warnings.some((warning) => warning.startsWith("omo-codex: migrated legacy configuration from ")
277
176
  && warning.endsWith("/.omo/config.jsonc"))).toBe(true)
278
- expect(result.warnings).toContain("omo-codex: configuration migration: skipped: codegraph.enabled legacy=false kept=true")
177
+ expect(result.warnings).toContain("omo-codex: configuration migration: skipped: [codex].telemetry.enabled legacy=false kept=true")
279
178
  })
280
179
 
281
180
  it("#given overlapping [omo] and [senpi] blocks in legacy config #when Codex migrates #then the transform conflict is reported", () => {
@@ -310,7 +209,7 @@ describe("getCodexOmoConfig", () => {
310
209
  it("#given codex starts before opencode #when both legacy source groups exist #then each distinct migration id is applied once", () => {
311
210
  // given
312
211
  const homeDir = createTemporaryDirectory("omo-codex-order-codex-first-")
313
- writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: false } } }))
212
+ writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
314
213
  writeOpenCodeConfig(homeDir)
315
214
  const openCodeSource = join(homeDir, ".config", "opencode", "oh-my-openagent.jsonc")
316
215
 
@@ -322,13 +221,17 @@ describe("getCodexOmoConfig", () => {
322
221
  // then
323
222
  expect(remainsAfterCodexStartup).toBe(true)
324
223
  expect(existsSync(openCodeSource)).toBe(false)
325
- expect(migrationIds(homeDir)).toEqual(["2026-07-codex-config-jsonc", "2026-07-opencode-config-unification"])
224
+ expect(migrationIds(homeDir)).toEqual([
225
+ "2026-07-codex-config-jsonc",
226
+ "2026-07-opencode-config-unification",
227
+ "2026-08-reasoning-unification",
228
+ ])
326
229
  })
327
230
 
328
231
  it("#given opencode starts before codex #when both legacy source groups exist #then each distinct migration id is applied once", () => {
329
232
  // given
330
233
  const homeDir = createTemporaryDirectory("omo-codex-order-opencode-first-")
331
- writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: false } } }))
234
+ writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
332
235
  writeOpenCodeConfig(homeDir)
333
236
 
334
237
  // when
@@ -336,13 +239,17 @@ describe("getCodexOmoConfig", () => {
336
239
  getCodexOmoConfig({ cwd: homeDir, homeDir, env: {} })
337
240
 
338
241
  // then
339
- expect(migrationIds(homeDir)).toEqual(["2026-07-opencode-config-unification", "2026-07-codex-config-jsonc"])
242
+ expect(migrationIds(homeDir)).toEqual([
243
+ "2026-07-opencode-config-unification",
244
+ "2026-07-codex-config-jsonc",
245
+ "2026-08-reasoning-unification",
246
+ ])
340
247
  })
341
248
 
342
249
  it("#given concurrent codex and opencode starts #when opencode owns the shared lock #then both migration ids are applied exactly once", () => {
343
250
  // given
344
251
  const homeDir = createTemporaryDirectory("omo-codex-order-concurrent-")
345
- writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: false } } }))
252
+ writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
346
253
  writeOpenCodeConfig(homeDir)
347
254
  let codexResult: ReturnType<typeof runCodexStartupMigration> | undefined
348
255
 
@@ -355,6 +262,10 @@ describe("getCodexOmoConfig", () => {
355
262
  // then
356
263
  if (codexResult === undefined) throw new Error("Expected concurrent Codex migration attempt")
357
264
  expect(codexResult.error).toBe("Configuration migration is already running")
358
- expect(migrationIds(homeDir)).toEqual(["2026-07-opencode-config-unification", "2026-07-codex-config-jsonc"])
265
+ expect(migrationIds(homeDir)).toEqual([
266
+ "2026-07-opencode-config-unification",
267
+ "2026-07-codex-config-jsonc",
268
+ "2026-08-reasoning-unification",
269
+ ])
359
270
  })
360
271
  })
@@ -42,7 +42,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
42
42
 
43
43
  1. **Discovery + Analysis** (concurrent)
44
44
  - Fire background explore agents immediately
45
- - Main session: bash structure + LSP/codegraph code map + read existing AGENTS.md
45
+ - Main session: bash structure + LSP/ast-grep code map + read existing AGENTS.md
46
46
  2. **Score & Decide** - Determine AGENTS.md locations from merged findings
47
47
  3. **Generate** - Root first, then subdirs in parallel
48
48
  4. **Review** - Deduplicate, trim, validate
@@ -51,7 +51,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
51
51
  **TodoWrite ALL phases. Mark in_progress → completed in real-time.**
52
52
  ```
53
53
  TodoWrite([
54
- { id: "discovery", content: "Fire explore agents + LSP/codegraph map + read existing", status: "pending", priority: "high" },
54
+ { id: "discovery", content: "Fire explore agents + LSP/ast-grep map + read existing", status: "pending", priority: "high" },
55
55
  { id: "scoring", content: "Score directories, determine locations", status: "pending", priority: "high" },
56
56
  { id: "generate", content: "Generate AGENTS.md files (root + subdirs)", status: "pending", priority: "high" },
57
57
  { id: "review", content: "Deduplicate, validate, trim", status: "pending", priority: "medium" }
@@ -67,16 +67,16 @@ TodoWrite([
67
67
 
68
68
  ### Fire Background Explore Agents IMMEDIATELY
69
69
 
70
- Don't wait-these run async while main session works. **Equip every agent with the code graph**: any task touching structure, entry points, dependencies, or hotspots MUST query `codegraph_*` (explore/search/callers/callees/impact) and `lsp_symbols` when present, and ground its claims in that data instead of guessing from conventions. Richer real-graph context per agent = a more accurate project map.
70
+ Don't wait-these run async while main session works. **Ground every agent in real symbol data**: any task touching structure, entry points, dependencies, or hotspots MUST query `lsp_symbols`/`lsp_find_references` and the ast-grep skill (`sg`) when present, and ground its claims in that data instead of guessing from conventions. Richer real context per agent = a more accurate project map.
71
71
 
72
72
  ```
73
73
  // Fire all at once, collect results later
74
- task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure: map real layout via codegraph_explore/codegraph_files → REPORT deviations from standard patterns")
75
- task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files, trace reach via codegraph_callees + lsp_symbols → REPORT non-standard organization")
74
+ task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure: map real layout via glob + lsp_symbols scope=workspace → REPORT deviations from standard patterns")
75
+ task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files, trace reach via lsp_symbols + lsp_find_references → REPORT non-standard organization")
76
76
  task(subagent_type="explore", load_skills=[], description="Find conventions", run_in_background=true, prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules")
77
77
  task(subagent_type="explore", load_skills=[], description="Find anti-patterns", run_in_background=true, prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns")
78
78
  task(subagent_type="explore", load_skills=[], description="Explore build/CI", run_in_background=true, prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns")
79
- task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs/structure; codegraph_callers on core modules to see what is covered → REPORT unique conventions")
79
+ task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs/structure; lsp_find_references on core modules to see what is covered → REPORT unique conventions")
80
80
  ```
81
81
 
82
82
  <dynamic-agents>
@@ -138,7 +138,7 @@ For each existing file found:
138
138
 
139
139
  If `--create-new`: Read all existing first (preserve context) → then delete all → regenerate.
140
140
 
141
- #### 3. Code Map - drive LSP AND codegraph (do NOT skip)
141
+ #### 3. Code Map - drive LSP AND ast-grep (do NOT skip)
142
142
 
143
143
  Highest-signal source for the CODE MAP and the Symbol/Export/Reference scoring rows. Complementary, not alternatives - run BOTH when present, alongside the explore agents.
144
144
 
@@ -147,10 +147,10 @@ Highest-signal source for the CODE MAP and the Symbol/Export/Reference scoring r
147
147
  - `lsp_symbols` scope="workspace", query by kind (class/interface/function) -> symbol inventory.
148
148
  - `lsp_find_references` on top exports (line/character from the symbols result) -> reference centrality.
149
149
 
150
- **codegraph** - when `codegraph_*` tools exist (check `codegraph_status`); a first-class peer to LSP, NOT a last resort:
151
- - `codegraph_explore` -> overview; `codegraph_callers`/`codegraph_callees`/`codegraph_impact` -> centrality + blast radius for the scoring matrix; `codegraph_search`/`codegraph_files` -> symbol/file inventory.
150
+ **ast-grep** - load the ast-grep skill; a first-class peer to LSP, NOT a last resort:
151
+ - `sg --pattern 'export $$$' --lang <lang>` -> export inventory; `sg --pattern 'import $$$ from "$MOD"'` -> dependency edges between modules for the scoring matrix.
152
152
 
153
- Only if NEITHER exists: explore agents + the ast-grep skill (`sg`), and mark centrality unmeasured in the CODE MAP.
153
+ Only if LSP is unavailable: explore agents + ast-grep alone, and mark reference centrality unmeasured in the CODE MAP.
154
154
 
155
155
  ### Collect Background Results
156
156
 
@@ -159,7 +159,7 @@ Only if NEITHER exists: explore agents + the ast-grep skill (`sg`), and mark cen
159
159
  for each background task ID (`bg_...`): background_output(task_id="bg_...")
160
160
  ```
161
161
 
162
- **Merge: bash + LSP/codegraph + existing + explore findings. Mark "discovery" as completed.**
162
+ **Merge: bash + LSP/ast-grep + existing + explore findings. Mark "discovery" as completed.**
163
163
 
164
164
  ---
165
165
 
@@ -235,7 +235,7 @@ NEVER use Write to overwrite an existing file. ALWAYS check existence first via
235
235
  |------|----------|-------|
236
236
 
237
237
  ## CODE MAP
238
- {From LSP/codegraph - skip only if neither exists or project <10 files}
238
+ {From LSP/ast-grep - skip only if neither exists or project <10 files}
239
239
 
240
240
  | Symbol | Type | Location | Refs | Role |
241
241
  |--------|------|----------|------|------|
@@ -318,7 +318,7 @@ Hierarchy:
318
318
  ## Anti-Patterns
319
319
 
320
320
  - **Static agent count**: MUST vary agents based on project size/depth
321
- - **Sequential execution**: MUST parallel (explore + LSP + codegraph concurrent)
321
+ - **Sequential execution**: MUST parallel (explore + LSP + ast-grep concurrent)
322
322
  - **Ignoring existing**: ALWAYS read existing first, even with --create-new
323
323
  - **Over-documenting**: Not every dir needs AGENTS.md
324
324
  - **Redundancy**: Child never repeats parent
@@ -70,7 +70,7 @@ sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/openai-codex-source"
70
70
  - `$CODEX_HOME/config.toml` exists and parses; LazyCodex-managed entries match what the latest installer would write.
71
71
  - Plugin payload present and non-empty: read `.codex-plugin/plugin.json`; when that manifest declares a `hooks` array, validate every direct hook path declared by the manifest; require `hooks/hooks.json` only when the manifest declares it; do not require retired paths such as `components/workflow-selector` or `hooks/user-prompt-submit-selecting-lazycodex-workflow.json` unless the current manifest declares them.
72
72
  - Verify the manifest-declared runtime payload, not a remembered source tree. Current payload includes `skills/`, `.mcp.json`, root CLI runtimes such as `dist/cli/index.js` and `dist/cli-node/index.js`, and every hook/MCP `components/*/dist/*.js` target referenced by installed manifests.
73
- - Treat install-time materialization rewrites as expected when the rewritten target exists and is non-empty. For example, `.mcp.json` may use plugin-local or absolute installed paths for CodeGraph/MCP runtimes; that is PASS/WARN context, not payload drift. Missing or zero-byte rewritten targets are FAIL.
73
+ - Treat install-time materialization rewrites as expected when the rewritten target exists and is non-empty. For example, `.mcp.json` may use plugin-local or absolute installed paths for MCP runtimes; that is PASS/WARN context, not payload drift. Missing or zero-byte rewritten targets are FAIL.
74
74
  - Stale project-local leftovers the installer now removes (e.g. `.codex/hooks.json`, `.codex/skills` in the project) are flagged, not deleted.
75
75
  4. Probe the real surface. Do not invoke `lazycodex doctor`; this skill is already running inside that doctor workflow, so calling it would recurse. Instead run non-recursive probes directly: `codex --version`, `command -v codex`, the bin-link checks above, config/plugin payload inspections, and a trivial non-interactive Codex invocation that loads the plugin. Use the configured Codex default model for the runtime probe unless the user explicitly passed a model override to the doctor surface; never force a guessed/rejected model such as `gpt-5.5-codex-mini`. Capture stderr verbatim; a clean exit with warnings is WARN, not PASS.
76
76
  5. Compare for drift. Where installed manifest-declared bundled files differ from the same files at the installed version, or the latest source removed or renamed something the local config still references, record it with both paths. Do not report expected materialization differences, such as absolute `.mcp.json` runtime paths, as drift when their targets exist and are non-empty.
@@ -236,8 +236,8 @@ and utility functions to batch commands and reduce output. Keep direct calls
236
236
  when one result chooses the next action, outputs are already small, semantic
237
237
  judgment is required between calls, approval or side effects are involved,
238
238
  or native artifacts / citations must be preserved.
239
- - Architecture / flow / blast radius → `codegraph_explore` first when
240
- `codegraph_*` exists; if unavailable, continue with repo tools and LSP.
239
+ - Architecture / flow / blast radius → explore agents plus LSP references
240
+ and impact; do not guess from conventions.
241
241
  - **SYMBOLS REQUIRE LSP** — definitions, references, rename impact,
242
242
  workspace symbols, and diagnostics use the available `lsp_*` tools, not
243
243
  text search. Run diagnostics after edits and treat errors as blocking.
@@ -49,17 +49,17 @@ $ulw-execute [plan-name] [--worktree <absolute-path>] [--make-pr] [--ship]
49
49
  ```
50
50
 
51
51
  - `plan-name` (optional): a full or partial file stem under `.omo/plans/`.
52
- - `--worktree` (required for PR/branch work; otherwise optional): the task-owned git worktree path.
53
- - `--make-pr` (optional): deliver the work as a pull request. IMPLIES worktree mode: when `--worktree` is absent, create a task-owned worktree (`git worktree add <absolute-path> <base-branch>`) before implementation and record it as `worktree_path`. On completion, push the branch and open a reviewer-readable PR, then hand off with the PR URL - merge only if the user asks.
52
+ - `--worktree` (optional): reuse an existing task-owned worktree for the first phase instead of creating one; every phase runs in a task-owned worktree regardless.
53
+ - `--make-pr` (optional): deliver each phase's worktree as a pull request — push the branch, open a reviewer-readable PR, hand off with the URL, and merge only if the user asks.
54
54
  - `--ship` (optional): full delivery lifecycle; implies `--make-pr`. After the PR opens, stay on the job until it is MERGED: watch CI and review gates, fix failures and address feedback from the worktree (fresh QA evidence for behavior changes), merge per the repository's merge policy, then remove the worktree and sync `.omo/` state back.
55
55
 
56
56
  ## Goal and todo discipline (MANDATORY)
57
57
 
58
58
  Do ALL of this immediately after the plan is selected, BEFORE the first implementation dispatch. Skipping any step is a defect.
59
59
 
60
- 1. **Set the goal, in detail.** When a goal tool is available (`create_goal`), call it with a DETAILED objective: the plan name and path, the concrete end state, the phase and task counts, the delivery mode (direct, `--make-pr`, or `--ship`), and how completion will be verified. One work session = one goal. No goal tool -> record the same objective as the first ledger entry.
60
+ 1. **Set the goal, in detail.** When a goal tool is available (`create_goal`), call it with a DETAILED objective: the plan name and path, the concrete end state, the phase and task counts, the delivery mode (direct, `--make-pr`, or `--ship`), and how completion will be verified. One work session = one registered goal (the goal tool holds one active goal); each phase then carries its own concrete goal — the ledger entry Phase 2 records before the wave's first dispatch, defined from the previous phase's landed and verified evidence. No goal tool -> record the same objective as the first ledger entry.
61
61
  2. **Register every phase and task as todos.** Mirror the plan into the todo/plan tool of your harness: one phase per plan wave, one todo per column-zero checkbox (including the final verification wave). Register ALL of them up front - never keep tasks in memory only.
62
- 3. **Keep them current at every moment.** Mark a todo in_progress when its work dispatches and done immediately after its verification passes. Never batch-complete at the end, never execute work that is not a registered todo; discovered work is appended as a todo before it runs. The todo list, Boulder state, and plan checkboxes must always tell the same story.
62
+ 3. **Keep them current at every moment.** Mark a todo in_progress when its work dispatches and done immediately after its verification passes. Never batch-complete at the end, never execute work that is not a registered todo; discovered work — a pre-existing bug, failing test, stale doc, or wrong guidance — is appended to the plan as a checkbox, mirrored as a todo before it runs, and fixed to the ideal state, never deferred as a follow-up. A worker that meets a defect outside its assigned files reports it instead of fixing it; only the orchestrator appends the checkbox and dispatches it to a correctly scoped unit. The todo list, Boulder state, and plan checkboxes must always tell the same story.
63
63
 
64
64
  ## Phase 1: Select the plan
65
65
 
@@ -102,14 +102,14 @@ Write `.omo/boulder.json` before implementation starts. Prefix session ids with
102
102
  }
103
103
  ```
104
104
 
105
- For PR/branch work, a task-owned worktree is mandatory before implementation starts: pass `--worktree`, or use `--make-pr`/`--ship`, which auto-create one. Verify the path with `git worktree list --porcelain` or create it with `git worktree add <path> <branch-or-HEAD>`, then store the absolute path as `worktree_path`. All edits, commands, tests, and evidence capture must run inside that worktree.
105
+ Every phase (plan wave) runs in its own task-owned worktree with its own goal: before the wave's first dispatch, record the wave's goal — its checkboxes and their acceptance criteria — as a ledger entry, then `git worktree add <repo>-wt/<plan>-<wave> <branch off the integration base>` (or verify a `--worktree` path with `git worktree list --porcelain`), store the absolute path as `worktree_path`, run every edit, command, test, and evidence capture inside it; the wave lands on the integration base once its checkboxes are verified (direct merge, or the PR under `--make-pr`/`--ship`), and the next wave branches from that landed base.
106
106
 
107
107
  ## Parallel delivery lanes (teams and worktrees)
108
108
 
109
109
  Solo orchestration with parallel background workers is the default topology. Decide once, when the wave's lanes are known, and record the verdict in the ledger:
110
110
 
111
111
  - **Independent lanes -> parallel workers.** Separate files, no shared contract: one parallel spawn burst; no team.
112
- - **Dependency-ordered lanes -> a dag run.** Sub-tasks with real ordering between them (C needs A and B finished first) and a harness with a native `dag` tool: dispatch the wave as ONE dag run — one producer node per lane plus a verification node — instead of a spawn burst, and watch the run's lifecycle instead of arming per-lane watchers. Read the `mass-ulw` skill's `SKILL.md` and `references/planning.md` IN FULL before defining any graph.
112
+ - **Dependency-ordered lanes -> one `workflow` run per wave.** Sub-tasks with real ordering between them (C needs A and B finished first) and a harness with a native `workflow` tool: dispatch the wave as ONE run (one producer node per lane plus a verification node); recover inside it with `retry`/`amend`/`send`; let node completions wake you instead of arming per-lane watchers; the next wave is a NEW run (or `amend` when only the definition changed) — never one graph for the whole plan. Read the `mass-ulw` skill's `SKILL.md` and `references/planning.md` IN FULL before defining any graph.
113
113
  - **Overlapping lanes -> a team.** The lanes touch the same module or contract AND running them concurrently actually finishes sooner: stand up a team (where the harness has one) so one lane's discoveries relay through you mid-flight.
114
114
  - **PR-mode independent lanes -> a worktree per lane.** Under `--make-pr`/`--ship`, when a wave holds independent checkboxes, give each lane its own branch and task-owned worktree, delivered as its own PR.
115
115
 
@@ -169,7 +169,7 @@ Each sub-task message must include:
169
169
  - Terminal / TUI: drive a real pty; `tmux send-keys` is fine for a boot/behavior smoke, but color/layout/CJK evidence goes through the xterm.js web terminal below, NEVER `tmux capture-pane`.
170
170
  - Browser use: prefer the harness's in-app browser control when available and the scenario does not need an authenticated or persistent user browser profile; otherwise drive the real page with Chrome, or agent-browser (https://github.com/vercel-labs/agent-browser) when Chrome is unavailable.
171
171
  - Computer use: OS-level GUI automation against the running desktop app when the surface is not a page.
172
- - TUI visual evidence: when a TUI claim needs visual QA or PR proof, run `node script/qa/web-terminal-visual-qa.mjs --command "<cmd>" --input "{Enter}" --evidence-dir <dir>` (real pty rendered through xterm.js in Chrome) and attach `terminal.png` plus `metadata.json`.
172
+ - TUI visual evidence: when a TUI claim needs visual QA or PR proof, run `bun script/qa/web-terminal-visual-qa.mjs --command "<cmd>" --input "{Enter}" --evidence-dir <dir>` (real pty rendered through xterm.js in Chrome) and attach `terminal.png` plus `metadata.json`.
173
173
  6. The adversarial classes that apply to this sub-task (from the 9 ultraqa classes) and how each is probed.
174
174
  7. Required artifact path and cleanup receipt.
175
175
  8. Tool-use expectations: batch independent tool calls in parallel; when the harness exposes a code-execution surface (eval), use it for multi-call steps instead of one-by-one calls.
@@ -232,16 +232,9 @@ Only after verification passes:
232
232
  When all top-level checkboxes in `## TODOs` and `## Final Verification Wave` are complete:
233
233
 
234
234
  1. Run the plan's final verification commands.
235
- 2. Complete the **Global Review and Debugging Gate** before any completion claim, PR creation, PR handoff, branch handoff, or merge:
236
- - Invoke the `review-work` skill with the final diff, changed files, user goal, constraints, run command, and verification evidence. All five review lanes must return PASS. A timeout, missing deliverable, ack-only child, `BLOCKED:`, or inconclusive lane is a gate failure, not approval.
237
- - Each passing review lane binds to the exact full commit SHA it reviewed. Immediately append a durable record to `.omo/ulw-execute/ledger.jsonl` with the lane name, full SHA, PASS verdict, and report artifact/source. Before same-SHA reuse after any continuation or compaction, re-read the ledger record and require the exact lane/SHA pair; memory, chat history, or an unstamped report is not coverage. New commits require fresh applicable lane coverage.
238
- - Run a debugging-oriented runtime audit even when the review passes: name at least three plausible failure hypotheses for the changed surface, run the distinguishing checks against the actual artifact, and append a separate durable record with the audit name, exact full SHA, verdict, and evidence artifact/source to `.omo/ulw-execute/ledger.jsonl`. Reuse it only after re-reading an exact audit/SHA match.
239
- - If any review lane or debugging hypothesis fails, invoke the `debugging` skill, confirm root cause with runtime evidence, add the minimal failing test or reproduction, fix it, rerun the affected verification, then rerun the Global Review and Debugging Gate.
240
- - Evidence hygiene is mandatory: redact or mask secrets and sensitive user data before writing `.omo/ulw-execute/ledger.jsonl`, a PR body, or a handoff. Never include raw tokens, credentials, auth headers, cookies, API keys, env dumps, private logs, or PII; use concise summaries, lengths, hashes, or short non-sensitive prefixes instead.
241
- - If the work includes creating, updating, or handing off a PR, refresh `git status` and the PR/branch state from the task-owned worktree after the gate, and include only redacted review/debugging evidence in the PR body or handoff.
242
- 3. Finish the PR/branch lifecycle from its task-owned worktree: sync `.omo/` state back to the main repo, create or update the PR when requested, wait for CI/review/Cubic gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
243
- 4. Remove or mark the Boulder work as completed.
244
- 5. Print an `ORCHESTRATION COMPLETE` block with the plan path, verification commands, Global Review and Debugging Gate verdict, artifacts, and cleanup receipts.
235
+ 2. For PR/branch work, finish the lifecycle from the last phase's worktree: sync `.omo/` state back to the main repo, create or update the PR, wait for review/verification gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
236
+ 3. Remove or mark the Boulder work as completed.
237
+ 4. Print an `ORCHESTRATION COMPLETE` block with the plan path, verification commands, artifacts, and cleanup receipts.
245
238
 
246
239
  ## Hard rules
247
240
 
@@ -250,7 +243,6 @@ When all top-level checkboxes in `## TODOs` and `## Final Verification Wave` are
250
243
  - No tests-only completion claim. A Manual-QA artifact is required.
251
244
  - **NO DIRECT IMPLEMENTATION BY THE ORCHESTRATOR.** Root NEVER edits product files, writes tests, or runs QA itself — a spawned worker does.
252
245
  - No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.
253
- - No `ORCHESTRATION COMPLETE`, final response, PR creation, PR handoff, or merge before the Global Review and Debugging Gate passes with recorded evidence.
254
- - No PR/branch implementation or review in the main worktree; create or use a task-owned git worktree first.
246
+ - No implementation, review, or merge in the main checkout; every phase works in its task-owned worktree.
255
247
  - No unprefixed session ids in Boulder state. Sessions are always recorded as `codex:<session_id>`.
256
248
  - No stale-memory execution. The plan and ledger are the durable source of truth.
@@ -190,6 +190,7 @@ omo-agent-toolkit ulw-loop record-evidence --goal-id <g> --criterion-id <c> --st
190
190
  # Then use the harness update_goal tool with status complete.
191
191
  omo-agent-toolkit ulw-loop checkpoint --goal-id <g> --print-template --json
192
192
  # Fill the printed template: replace every placeholder and use real artifact paths under currentAttemptDir.
193
+ # codex-goal-json.goal.objective must equal the plan's codexObjective verbatim.
193
194
  omo-agent-toolkit ulw-loop checkpoint --goal-id <g> --status complete --evidence "..." --codex-goal-json <path> --quality-gate-json <path>
194
195
  omo-agent-toolkit ulw-loop complete-goals
195
196
  ```
@@ -214,7 +215,7 @@ omo-agent-toolkit ulw-loop checkpoint --goal-id <id> --status complete --evidenc
214
215
  {
215
216
  "codeReview":{"by":"lazycodex-code-reviewer","recommendation":"APPROVE","codeQualityStatus":"CLEAR","reportPath":"test/fixtures/artifacts/code-review.md","evidence":"Diff review passed.","blockers":[]},
216
217
  "manualQa":{"by":"lazycodex-qa-executor","status":"passed","evidence":"CLI and data surfaces passed.","surfaceEvidence":[{"id":"surface-cli-pass","criterionRef":"C1","surface":"cli","invocation":"omo-agent-toolkit ulw-loop checkpoint --quality-gate-json sample-quality-gate.json --json","verdict":"passed","artifactRefs":["artifact-cli-pass"]},{"id":"surface-data-pass","criterionRef":"C2","surface":"data","invocation":"diff -u before-ledger.json after-ledger.json","verdict":"passed","artifactRefs":["artifact-data-diff"]}],"adversarialCases":[{"id":"adv-malformed-input","criterionRef":"C3","scenario":"malformed gate input omits manual QA evidence","expectedBehavior":"validator rejects ULW_LOOP_QUALITY_GATE_INVALID","verdict":"passed","artifactRefs":["artifact-cli-reject"]}],"artifactRefs":[{"id":"artifact-cli-pass","kind":"cli-transcript","description":"CLI pass artifact.","path":"test/fixtures/artifacts/cli-pass.txt"},{"id":"artifact-cli-reject","kind":"log","description":"Reject log artifact.","path":"test/fixtures/artifacts/rejection.txt"},{"id":"artifact-data-diff","kind":"data-diff","description":"Data diff artifact.","path":"test/fixtures/artifacts/data-diff.txt"}]},
217
- "gateReview":{"by":"lazycodex-gate-reviewer","recommendation":"APPROVE","reportPath":"test/fixtures/artifacts/gate-review.md","evidence":"Gate review passed.","blockers":[]},
218
+ "gateReview":{"by":"lazycodex-gate-reviewer","recommendation":"APPROVE","reportPath":"test/fixtures/artifacts/gate-review.md","evidence":"Gate review passed.","blockers":[],"notes":[]},
218
219
  "iteration":{"fullRerun":true,"status":"passed","rerunCommands":["bunx vitest run packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-doc.test.ts"],"evidence":"Focused rerun passed."},
219
220
  "criteriaCoverage":{"totalCriteria":3,"passCount":3,"originalIntent":"User wanted artifact-backed completion.","desiredOutcome":"Behavior ships with review and QA evidence.","userOutcomeReview":"Result matches brief and goals.","adversarialClassesCovered":["malformed_input","stale_state"]}
220
221
  }
@@ -71,7 +71,6 @@ When producing the plan, encode every executable item as a column-zero Markdown
71
71
  - **Decision-complete is the north star.** The executor has NO interview context - spell out exact paths, "every X in Y", and an explicit Must-NOT-Have. Leave the implementer ZERO judgment calls.
72
72
  - **Full scope is the default.** Plan the ENTIRE request; "MVP", "v1", "phase 1", or any reduced subset is never an option you invent or ask about - it exists only if the user introduces it. Scope OUT / Must-NOT-Have entries are guardrails against unrequested additions, never reductions of the request.
73
73
  - **Explore before asking.** Discoverable facts (repo/system/docs truth) -> research and cite, never ask. Preferences/tradeoffs -> the only things you bring to the user. When unsure which, treat it as a user-decision.
74
- - **CodeGraph first when present.** Use `codegraph_explore` for repo how/where/what/flow questions before wider reads; if codegraph_* tools are absent, inactive/uninitialized, or cold-start unavailable, continue with Read/Grep/Glob/LSP and the ast-grep skill.
75
74
  - **Two filters** on every candidate question, in order: (1) Could collected evidence answer it? -> explore instead. (2) Could the user's stated intent plus a defensible default answer it? -> adopt the default, record it, do not ask - UNLESS it is an owner-decision, which always survives as a question even when a default exists: anything irreversible / destructive / safety-critical, or a cross-cutting product choice the user lives with (public config surface, distribution / packaging, external dependency or pinned SHA, data / schema shape, real budget / paid-service spend, expected scale or capacity target, target-audience / compliance limits). Extrinsic constraints (budget, mandated stack, scale, audience) leave no repo evidence, so exploration can never surface them - sweep those axes explicitly once per plan and classify each as explored, defaulted (ledger), or asked. Default the reversible internals; surface the owner-decisions.
76
75
  - **Explore to sufficiency, then STOP.** One research wave per open question; stop when the clearance check is answerable; never re-explore to double-check.
77
76
  - **Parallel-dispatch** independent research in ONE turn and keep working while it runs. Subagent outputs are CLAIMS until you independently verify them.
@@ -23,10 +23,10 @@
23
23
  | Aggregate wiring | `aggregate-{manifest,hooks,build,mcp,agents,model-catalog}.test.mjs` |
24
24
  | Bootstrap | `bootstrap-{hooks,setup,binlinks,orchestration,ps-guard}.test.mjs` |
25
25
  | Update flow | `auto-update{,-state-persistence,-restart-notice,-release-notes}.test.mjs` |
26
- | Migration | `migrate-codex-config.test.mjs` (1,242 LOC — densest), `migrate-omo-sot`, `multi-agent-v2-regression`, `subagent-limit-migration` |
26
+ | Migration | `migrate-codex-config.test.mjs` (1,242 LOC — densest), `multi-agent-v2-regression`, `subagent-limit-migration` |
27
27
  | Skills sync | `sync-skills{,-codex-compatibility}.test.mjs`, `ulw-plan`/`ulw-research`/`ulw-loop` skill contracts |
28
28
  | Teammode | `teammode-{transport,communication,worktree,safety,thread-links,thread-title,archive-ambiguity}.test.mjs` |
29
- | Component CLIs | `component-{bundled-cli,bin-names,codegraph-mcp-smoke}.test.mjs`, `lsp-prebuild-layouts` |
29
+ | Component CLIs | `component-{bundled-cli,bin-names}.test.mjs`, `lsp-prebuild-layouts` |
30
30
 
31
31
  ## CONVENTIONS
32
32
 
@@ -30,7 +30,6 @@ test("#given isolated components #when hooks are inspected #then commands stay i
30
30
  const componentMarkers = [
31
31
  "components/comment-checker/dist/cli.js",
32
32
  "components/lsp/dist/cli.js",
33
- "components/codegraph/dist/cli.js",
34
33
  "components/rules/dist/cli.js",
35
34
  "components/ulw-execute-continuation/dist/cli.js",
36
35
  "components/telemetry/dist/cli.js",
@@ -220,34 +219,16 @@ test("#given aggregate SessionStart hooks #when inspected #then cold-start-prone
220
219
  const coldStartHooks = sessionStartHooks.filter(
221
220
  ({ command }) =>
222
221
  command.includes("components/telemetry/dist/cli.js") ||
223
- command.includes("scripts/auto-update.mjs") ||
224
- command.includes("components/codegraph/dist/cli.js"),
222
+ command.includes("scripts/auto-update.mjs"),
225
223
  );
226
224
 
227
225
  // then
228
- assert.equal(coldStartHooks.length, 3);
226
+ assert.equal(coldStartHooks.length, 2);
229
227
  for (const hook of coldStartHooks) {
230
228
  assert.equal(hook.timeout, 15, `${hook.source} must carry timeout 15 for cold-start headroom`);
231
229
  }
232
230
  });
233
231
 
234
- test("#given aggregate PostToolUse hooks #when inspected #then CodeGraph init guidance is registered for CodeGraph tools", async () => {
235
- // given
236
- const commandHooks = await readAggregateCommandHooks();
237
-
238
- // when
239
- const codegraphPostToolUseHooks = commandHooks.filter(
240
- (hook) =>
241
- hook.eventName === "PostToolUse" &&
242
- hook.handler.command === 'node "${PLUGIN_ROOT}/components/codegraph/dist/cli.js" hook post-tool-use',
243
- );
244
-
245
- // then
246
- assert.equal(codegraphPostToolUseHooks.length, 1);
247
- assert.equal(codegraphPostToolUseHooks[0]?.matcher, "^(codegraph[._].*|mcp__codegraph__.*)$");
248
- assert.match(codegraphPostToolUseHooks[0]?.handler.statusMessage ?? "", /\S/);
249
- });
250
-
251
232
  test("#given aggregate PostToolUse hooks #when inspected #then thread title hygiene is registered for created Codex threads", async () => {
252
233
  // given
253
234
  const commandHooks = await readAggregateCommandHooks();
@@ -17,7 +17,7 @@ test("#given aggregate plugin manifest #when inspected #then it owns the omo nam
17
17
  // then
18
18
  assert.equal(manifest.name, "omo");
19
19
  assert(Array.isArray(hookPaths));
20
- assert.equal(hookPaths.length, 23);
20
+ assert.equal(hookPaths.length, 21);
21
21
  assert(hookPaths.every((hookPath) => typeof hookPath === "string" && hookPath.startsWith("./hooks/")));
22
22
  assert(!hookPaths.includes("./hooks/hooks.json"));
23
23
  assert(!hookPaths.includes("./hooks/user-prompt-submit-selecting-lazycodex-workflow.json"));
@@ -54,7 +54,6 @@ test("#given component directories #when scanned #then only intentional resource
54
54
  // then
55
55
  assert.deepEqual(componentNames, [
56
56
  "bootstrap",
57
- "codegraph",
58
57
  "comment-checker",
59
58
  "git-bash",
60
59
  "lazycodex-executor-verify",
@@ -18,14 +18,13 @@ test("#given aggregate MCP config #when inspected #then code MCPs reference pack
18
18
  // when
19
19
  const lspServer = mcp.mcpServers.lsp;
20
20
  const gitBashServer = mcp.mcpServers.git_bash;
21
- const codegraphServer = mcp.mcpServers.codegraph;
22
21
  const codeMcpNames = Object.keys(mcp.mcpServers)
23
- .filter((name) => name === "lsp" || name === "git_bash" || name === "codegraph")
22
+ .filter((name) => name === "lsp" || name === "git_bash")
24
23
  .sort();
25
24
  const componentLocalMcpSources = lspSources.filter((name) => name.startsWith("lazy-mcp") || name === "lazy-lsp-mcp.ts");
26
25
 
27
26
  // then
28
- assert.deepEqual(codeMcpNames, ["codegraph", "git_bash", "lsp"]);
27
+ assert.deepEqual(codeMcpNames, ["git_bash", "lsp"]);
29
28
  assert.equal(packageJson.workspaces.includes("components/lsp/packages/lsp-tools-mcp"), false);
30
29
  assert.deepEqual(packageJson.dependencies, { "@oh-my-opencode/shared-skills": "file:../../shared-skills" });
31
30
  assert.doesNotMatch(bundledMcpBuildScript, new RegExp(["ast", "grep", "mcp"].join("-")));
@@ -38,10 +37,6 @@ test("#given aggregate MCP config #when inspected #then code MCPs reference pack
38
37
  assert.equal(gitBashServer.command, "node");
39
38
  assert.deepEqual(gitBashServer.args, ["../../git-bash-mcp/dist/cli.js", "mcp"]);
40
39
  assert.equal(gitBashServer.cwd, ".");
41
- assert.equal(codegraphServer.command, "node");
42
- assert.deepEqual(codegraphServer.args, ["components/codegraph/dist/serve.js"]);
43
- assert.equal(codegraphServer.cwd, ".");
44
- assert.equal(codegraphServer.required, false);
45
40
  assert.deepEqual(componentLocalMcpSources, []);
46
41
  });
47
42