oh-my-opencode 4.15.1 → 4.16.1

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 (234) hide show
  1. package/.agents/skills/codex-qa/SKILL.md +9 -7
  2. package/.agents/skills/codex-qa/references/logging-debug.md +6 -4
  3. package/.agents/skills/opencode-qa/SKILL.md +9 -9
  4. package/.agents/skills/opencode-qa/references/tui-tmux.md +10 -8
  5. package/dist/cli/codex-ulw-loop.d.ts +8 -0
  6. package/dist/cli/doctor/checks/tui-plugin-config.d.ts +4 -4
  7. package/dist/cli/get-local-version/types.d.ts +1 -1
  8. package/dist/cli/index.js +792 -744
  9. package/dist/cli/install-senpi/index.d.ts +1 -0
  10. package/dist/cli/run/poll-for-completion.d.ts +4 -0
  11. package/dist/cli/run/session-resolver.d.ts +1 -0
  12. package/dist/cli/senpi-platform-flag.d.ts +4 -0
  13. package/dist/cli/types.d.ts +2 -1
  14. package/dist/cli-node/index.js +792 -744
  15. package/dist/features/background-agent/manager.d.ts +16 -0
  16. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  17. package/dist/features/monitor/process.d.ts +17 -1
  18. package/dist/hooks/anthropic-context-window-limit-recovery/aggressive-truncation-strategy.d.ts +1 -0
  19. package/dist/index.js +2206 -1971
  20. package/dist/skills/debugging/references/methodology/06-fix.md +6 -0
  21. package/dist/skills/frontend/ATTRIBUTION.md +10 -1
  22. package/dist/skills/frontend/SKILL.md +12 -7
  23. package/dist/skills/frontend/references/design/README.md +8 -4
  24. package/dist/skills/frontend/references/design/_INDEX.md +2 -2
  25. package/dist/skills/frontend/references/design/design-system-architecture.md +24 -2
  26. package/dist/skills/frontend/references/design/lazyweb.md +77 -0
  27. package/dist/skills/frontend/references/design/stitch-design-example.md +121 -0
  28. package/dist/skills/frontend/references/designpowers/README.md +2 -2
  29. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
  30. package/dist/skills/programming/SKILL.md +10 -1
  31. package/dist/skills/programming/references/logging.md +91 -0
  32. package/dist/skills/start-work/SKILL.md +2 -2
  33. package/dist/skills/ulw-plan/SKILL.md +5 -5
  34. package/dist/skills/ulw-plan/references/full-workflow.md +7 -7
  35. package/dist/skills/ulw-plan/references/intent-unclear.md +3 -3
  36. package/dist/skills/ulw-research/ATTRIBUTION.md +2 -2
  37. package/dist/skills/ulw-research/SKILL.md +28 -7
  38. package/dist/skills/visual-qa/SKILL.md +13 -17
  39. package/dist/tools/skill/description-formatter.d.ts +1 -0
  40. package/dist/tools/skill/description-formatter.test-support.d.ts +9 -0
  41. package/dist/tools/skill/zauc-mocks-skill-tools/test-support.d.ts +25 -0
  42. package/dist/tui.js +121 -419
  43. package/docs/reference/web-terminal-visual-qa.md +39 -45
  44. package/package.json +48 -25
  45. package/packages/git-bash-mcp/dist/cli.js +2 -2
  46. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  47. package/packages/omo-codex/plugin/components/bootstrap/AGENTS.md +55 -0
  48. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +19 -16
  49. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  50. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +51 -0
  52. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +936 -248
  53. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +233 -135
  54. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +29 -0
  56. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +13 -0
  57. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +25 -0
  58. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  59. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +30 -1
  60. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +16 -2
  61. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +80 -0
  62. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +34 -0
  63. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +107 -0
  64. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +26 -0
  65. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +29 -0
  66. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +8 -21
  67. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +108 -0
  68. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +76 -0
  69. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +17 -111
  70. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +1 -1
  71. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +45 -67
  72. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +56 -0
  73. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  74. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  75. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +31 -0
  76. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  77. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  78. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +45 -0
  79. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  80. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  81. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  82. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  83. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +37 -102
  84. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  85. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +2 -2
  87. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  88. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  89. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +46 -0
  90. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  91. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  92. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +6 -0
  93. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +6 -0
  94. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  95. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  96. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -2
  97. package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +2 -0
  98. package/packages/omo-codex/plugin/components/ultrawork/README.md +3 -3
  99. package/packages/omo-codex/plugin/components/ultrawork/directive.md +18 -10
  100. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +51 -2
  101. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  102. package/packages/omo-codex/plugin/components/ultrawork/package.json +2 -1
  103. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +14 -1
  104. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +388 -0
  105. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +16 -2
  106. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +4 -4
  107. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
  108. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +5 -3
  109. package/packages/omo-codex/plugin/components/ultrawork/src/skill-pointer.ts +56 -0
  110. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +26 -5
  111. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +12 -0
  112. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +1 -0
  113. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +82 -0
  114. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +5 -0
  115. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +18 -10
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +15 -2
  117. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +2 -1
  118. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +145 -32
  119. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +1 -0
  120. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +5 -1
  121. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +6 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +55 -9
  123. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-snapshot.d.ts +15 -0
  124. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-snapshot.js +33 -0
  125. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +10 -3
  126. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +15 -11
  127. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +2 -1
  128. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +5 -3
  129. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.d.ts +7 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.js +46 -0
  131. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  132. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  133. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
  134. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +7 -7
  135. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -2
  136. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +2 -1
  137. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +5 -1
  138. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +59 -11
  139. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-snapshot.ts +38 -0
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +11 -3
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +15 -7
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +9 -3
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-skill-pointer.ts +55 -0
  144. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +16 -0
  145. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +260 -2
  146. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-snapshot.test.ts +124 -0
  147. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +101 -2
  148. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +49 -0
  149. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  151. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  157. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  158. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  159. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  160. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  161. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  164. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  165. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  170. package/packages/omo-codex/plugin/package-lock.json +13 -13
  171. package/packages/omo-codex/plugin/package.json +1 -1
  172. package/packages/omo-codex/plugin/scripts/build-components.mjs +63 -17
  173. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +10 -6
  174. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +10 -3
  175. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +1 -0
  176. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +18 -0
  177. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +6 -0
  178. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -1
  179. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +12 -7
  180. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +8 -4
  181. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -2
  182. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +24 -2
  183. package/packages/omo-codex/plugin/skills/frontend/references/design/lazyweb.md +77 -0
  184. package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-design-example.md +121 -0
  185. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +2 -2
  186. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
  187. package/packages/omo-codex/plugin/skills/programming/SKILL.md +10 -1
  188. package/packages/omo-codex/plugin/skills/programming/references/logging.md +91 -0
  189. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +2 -2
  190. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +388 -0
  191. package/packages/omo-codex/plugin/skills/ultrawork/agents/openai.yaml +2 -0
  192. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
  193. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +7 -7
  194. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +16 -2
  195. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +4 -4
  196. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
  197. package/packages/omo-codex/plugin/skills/ulw-research/ATTRIBUTION.md +2 -2
  198. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +28 -7
  199. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +13 -17
  200. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +4 -4
  201. package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +1 -1
  202. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +22 -9
  203. package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +1 -1
  204. package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
  205. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -0
  206. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +56 -0
  207. package/packages/omo-codex/plugin/test/ulw-plan-skill-contract.test.mjs +52 -0
  208. package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +98 -0
  209. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +6 -6
  210. package/packages/omo-codex/scripts/install-dist/install-local.mjs +310 -3979
  211. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
  212. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +6 -0
  213. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -1
  214. package/packages/shared-skills/skills/frontend/SKILL.md +12 -7
  215. package/packages/shared-skills/skills/frontend/references/design/README.md +8 -4
  216. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -2
  217. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +24 -2
  218. package/packages/shared-skills/skills/frontend/references/design/lazyweb.md +77 -0
  219. package/packages/shared-skills/skills/frontend/references/design/stitch-design-example.md +121 -0
  220. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +2 -2
  221. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
  222. package/packages/shared-skills/skills/programming/SKILL.md +10 -1
  223. package/packages/shared-skills/skills/programming/references/logging.md +91 -0
  224. package/packages/shared-skills/skills/start-work/SKILL.md +2 -2
  225. package/packages/shared-skills/skills/ulw-plan/SKILL.md +5 -5
  226. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +7 -7
  227. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +3 -3
  228. package/packages/shared-skills/skills/ulw-research/ATTRIBUTION.md +2 -2
  229. package/packages/shared-skills/skills/ulw-research/SKILL.md +28 -7
  230. package/packages/shared-skills/skills/visual-qa/SKILL.md +13 -17
  231. package/script/qa/strip-ansi.mjs +10 -0
  232. package/script/qa/web-terminal-visual-qa.mjs +112 -195
  233. package/script/qa/xterm-live-terminal.mjs +180 -0
  234. package/script/qa/web-terminal-renderer.mjs +0 -218
@@ -1,8 +1,8 @@
1
- import { mkdtemp, readFile } from "node:fs/promises";
1
+ import { appendFile, mkdtemp, readFile } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { describe, expect, it } from "vitest";
5
- import { ulwLoopGoalsPath } from "../src/paths.js";
5
+ import { ulwLoopGoalsPath, ulwLoopLedgerPath } from "../src/paths.js";
6
6
  import { readSteeringLedgerEntries, readUlwLoopPlan, writePlan } from "../src/plan-io.js";
7
7
  import {
8
8
  applySteeringMutation,
@@ -12,6 +12,7 @@ import {
12
12
  } from "../src/steering.js";
13
13
  import type {
14
14
  UlwLoopItem,
15
+ UlwLoopLedgerEntry,
15
16
  UlwLoopPlan,
16
17
  UlwLoopSteeringProposal,
17
18
  UlwLoopSuccessCriterion,
@@ -320,6 +321,104 @@ describe("steerUlwLoop", () => {
320
321
  expect(second.deduped).toBe(true);
321
322
  expect((await readUlwLoopPlan(repoRoot)).goals).toHaveLength(4);
322
323
  });
324
+
325
+ describe("compact steering ledger entries", () => {
326
+ const DETAIL = "evidence detail ".repeat(200);
327
+
328
+ function fatGoal(id: string): UlwLoopItem {
329
+ return goal({
330
+ id,
331
+ title: `Fat goal ${id}`,
332
+ objective: `Objective ${id}: ${DETAIL}`,
333
+ evidence: DETAIL,
334
+ successCriteria: [
335
+ criterion({ id: "C001", scenario: DETAIL, expectedEvidence: DETAIL }),
336
+ criterion({ id: "C002", scenario: DETAIL, expectedEvidence: DETAIL }),
337
+ ],
338
+ });
339
+ }
340
+
341
+ function fatPlan(): UlwLoopPlan {
342
+ return plan({
343
+ goals: Array.from({ length: 20 }, (_, index) => fatGoal(`G${String(index + 1).padStart(3, "0")}`)),
344
+ });
345
+ }
346
+
347
+ it("writes an O(changed goals) ledger entry instead of embedding the full plan", async () => {
348
+ // given
349
+ const seed = fatPlan();
350
+ const planBytes = JSON.stringify(seed).length;
351
+ const repoRoot = await repoWithPlan(seed);
352
+
353
+ // when
354
+ await steerUlwLoop(
355
+ repoRoot,
356
+ steering({ kind: "revise_pending_wording", targetGoalId: "G010", revisedTitle: "Sharper goal ten" }),
357
+ );
358
+
359
+ // then
360
+ const lines = (await readFile(ulwLoopLedgerPath(repoRoot), "utf8")).split("\n").filter(Boolean);
361
+ expect(lines).toHaveLength(1);
362
+ const line = lines[0] ?? "";
363
+ expect(line.length).toBeLessThan(planBytes / 4);
364
+ const entry: UlwLoopLedgerEntry = JSON.parse(line);
365
+ expect("before" in entry).toBe(false);
366
+ expect("after" in entry).toBe(false);
367
+ expect(entry.steering?.before?.goals.map((item) => item.id)).toEqual(["G010"]);
368
+ expect(entry.steering?.after?.goals.map((item) => item.id)).toEqual(["G010"]);
369
+ expect(entry.steering?.after?.goals[0]?.title).toBe("Sharper goal ten");
370
+ expect(entry.steering?.before?.goalCount).toBe(20);
371
+ expect(entry.steering?.before?.goalIds).toEqual(seed.goals.map((item) => item.id));
372
+ });
373
+ });
374
+
375
+ it("dedup against a legacy full-plan entry strips before/after from the returned audit", async () => {
376
+ // given
377
+ const seed = plan();
378
+ const repoRoot = await repoWithPlan(seed);
379
+ const legacyLine = JSON.stringify({
380
+ at: NOW,
381
+ kind: "steering_accepted",
382
+ goalId: "G001",
383
+ idempotencyKey: "legacy-key",
384
+ evidence: "observable blocker evidence",
385
+ message: "the plan must change to stay safe",
386
+ mutationKind: "revise_pending_wording",
387
+ steering: {
388
+ kind: "revise_pending_wording",
389
+ source: "cli",
390
+ targetGoalIds: ["G001"],
391
+ evidence: "observable blocker evidence",
392
+ rationale: "the plan must change to stay safe",
393
+ idempotencyKey: "legacy-key",
394
+ invariant: {
395
+ accepted: true,
396
+ structuralInvariantAccepted: true,
397
+ evidenceBackedNecessity: true,
398
+ noEasierCompletion: true,
399
+ rejectedReasons: [],
400
+ },
401
+ before: seed,
402
+ after: seed,
403
+ },
404
+ });
405
+ await appendFile(ulwLoopLedgerPath(repoRoot), `${legacyLine}\n`, "utf8");
406
+
407
+ // when
408
+ const result = await steerUlwLoop(repoRoot, steering({ idempotencyKey: "legacy-key" }));
409
+
410
+ // then
411
+ expect(result.deduped).toBe(true);
412
+ expect(result.accepted).toBe(true);
413
+ expect("before" in result.audit).toBe(false);
414
+ expect("after" in result.audit).toBe(false);
415
+ expect(result.audit).toMatchObject({
416
+ kind: "revise_pending_wording",
417
+ idempotencyKey: "legacy-key",
418
+ deduped: true,
419
+ });
420
+ expect((await readUlwLoopPlan(repoRoot)).goals).toEqual(seed.goals);
421
+ });
323
422
  });
324
423
 
325
424
  describe("parseUlwLoopSteeringDirective", () => {
@@ -61,4 +61,53 @@ describe("standalone ultrawork directive injection", () => {
61
61
 
62
62
  expect(ulwLoopDirective).toBe(ultraworkDirective);
63
63
  });
64
+
65
+ it("#given an existing ultrawork skill file #when standalone injection runs #then emits the compact skill pointer", async () => {
66
+ const skillFilePath = join(await mkdtemp(join(tmpdir(), "ug-skill-")), "SKILL.md");
67
+ await writeFile(
68
+ skillFilePath,
69
+ "---\nname: ultrawork\n---\n\n<ultrawork-mode>\ndirective body\n</ultrawork-mode>\n",
70
+ );
71
+
72
+ const output = await applyUserPromptUlwLoopSteering(payload("ulw this change", "/tmp"), {
73
+ includeUltraworkDirective: true,
74
+ ultraworkSkillFilePath: skillFilePath,
75
+ });
76
+ const parsed = JSON.parse(output);
77
+ const context = parsed.hookSpecificOutput.additionalContext;
78
+
79
+ expect(context).toMatch(/^<ultrawork-mode>/);
80
+ expect(context).toContain(skillFilePath);
81
+ expect(context).toContain("create_goal");
82
+ expect(context).not.toContain("Tier triage");
83
+ });
84
+
85
+ it("#given a missing ultrawork skill file #when standalone injection runs #then falls back to the full directive", async () => {
86
+ const missingSkillFilePath = join(await mkdtemp(join(tmpdir(), "ug-skill-")), "SKILL.md");
87
+
88
+ const output = await applyUserPromptUlwLoopSteering(payload("ulw this change", "/tmp"), {
89
+ includeUltraworkDirective: true,
90
+ ultraworkSkillFilePath: missingSkillFilePath,
91
+ });
92
+ const parsed = JSON.parse(output);
93
+
94
+ expect(parsed.hookSpecificOutput.additionalContext).toContain("Tier triage");
95
+ });
96
+
97
+ it("#given the ulw-loop pointer template #when compared to ultrawork #then the copy stays byte-identical", async () => {
98
+ const ulwLoopPointerSource = await readFile(
99
+ new URL("../src/ultrawork-skill-pointer.ts", import.meta.url),
100
+ "utf8",
101
+ );
102
+ const ultraworkPointerSource = await readFile(
103
+ new URL("../../ultrawork/src/skill-pointer.ts", import.meta.url),
104
+ "utf8",
105
+ );
106
+ const templatePattern = /export const ULTRAWORK_SKILL_POINTER_TEMPLATE = `[\s\S]*?`;\n/;
107
+ const ulwLoopTemplate = ulwLoopPointerSource.match(templatePattern)?.[0];
108
+ const ultraworkTemplate = ultraworkPointerSource.match(templatePattern)?.[0];
109
+
110
+ expect(ulwLoopTemplate).toBeDefined();
111
+ expect(ulwLoopTemplate).toBe(ultraworkTemplate);
112
+ });
64
113
  });
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook post-compact",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Resetting Git Bash MCP Reminder",
10
+ "statusMessage": "(OmO 4.16.1) Resetting Git Bash MCP Reminder",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-compact",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Resetting LSP Diagnostics Cache",
10
+ "statusMessage": "(OmO 4.16.1) Resetting LSP Diagnostics Cache",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-compact",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Resetting Project Rule Cache",
10
+ "statusMessage": "(OmO 4.16.1) Resetting Project Rule Cache",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/codegraph/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Checking CodeGraph Init Guidance",
10
+ "statusMessage": "(OmO 4.16.1) Checking CodeGraph Init Guidance",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\codegraph\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/comment-checker/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 30,
10
- "statusMessage": "(OmO) Checking Comments",
10
+ "statusMessage": "(OmO 4.16.1) Checking Comments",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\comment-checker\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 60,
10
- "statusMessage": "(OmO) Checking LSP Diagnostics",
10
+ "statusMessage": "(OmO 4.16.1) Checking LSP Diagnostics",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/teammode/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO) Checking Thread Title Hygiene",
11
+ "statusMessage": "(OmO 4.16.1) Checking Thread Title Hygiene",
12
12
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\teammode\\dist\\cli.js\" hook post-tool-use"
13
13
  }
14
14
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Matching Project Rules",
10
+ "statusMessage": "(OmO 4.16.1) Matching Project Rules",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Enforcing Unlimited Goal Budget",
10
+ "statusMessage": "(OmO 4.16.1) Enforcing Unlimited Goal Budget",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook pre-tool-use",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Recommending Git Bash MCP",
10
+ "statusMessage": "(OmO 4.16.1) Recommending Git Bash MCP",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook pre-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/scripts/auto-update.mjs\" hook session-start",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Checking Auto Update",
10
+ "statusMessage": "(OmO 4.16.1) Checking Auto Update",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\scripts\\auto-update.mjs\" hook session-start"
12
12
  }
13
13
  ],
@@ -8,7 +8,7 @@
8
8
  "command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
9
9
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO) Checking Bootstrap Provisioning"
11
+ "statusMessage": "(OmO 4.16.1) Checking Bootstrap Provisioning"
12
12
  }
13
13
  ]
14
14
  }
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/codegraph/dist/cli.js\" hook session-start",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Checking CodeGraph Bootstrap",
10
+ "statusMessage": "(OmO 4.16.1) Checking CodeGraph Bootstrap",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\codegraph\\dist\\cli.js\" hook session-start"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook session-start",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Loading Project Rules",
10
+ "statusMessage": "(OmO 4.16.1) Loading Project Rules",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook session-start"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/telemetry/dist/cli.js\" hook session-start",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Recording Session Telemetry",
10
+ "statusMessage": "(OmO 4.16.1) Recording Session Telemetry",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\telemetry\\dist\\cli.js\" hook session-start"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Checking Start-Work Continuation",
10
+ "statusMessage": "(OmO 4.16.1) Checking Start-Work Continuation",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\start-work-continuation\\dist\\cli.js\" hook stop"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook subagent-stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Checking Start-Work Continuation",
10
+ "statusMessage": "(OmO 4.16.1) Checking Start-Work Continuation",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\start-work-continuation\\dist\\cli.js\" hook subagent-stop"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Verifying LazyCodex Executor Evidence",
10
+ "statusMessage": "(OmO 4.16.1) Verifying LazyCodex Executor Evidence",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lazycodex-executor-verify\\dist\\cli.js\" hook subagent-stop"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ultrawork/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO) Checking Ultrawork Trigger",
10
+ "statusMessage": "(OmO 4.16.1) Checking Ultrawork Trigger",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ultrawork\\dist\\cli.js\" hook user-prompt-submit"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Checking Ulw-Loop Steering",
10
+ "statusMessage": "(OmO 4.16.1) Checking Ulw-Loop Steering",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook user-prompt-submit"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO) Loading Project Rules",
10
+ "statusMessage": "(OmO 4.16.1) Loading Project Rules",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook user-prompt-submit"
12
12
  }
13
13
  ]
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/omo-codex-plugin",
3
- "version": "4.15.1",
3
+ "version": "4.16.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@sisyphuslabs/omo-codex-plugin",
9
- "version": "4.15.1",
9
+ "version": "4.16.1",
10
10
  "workspaces": [
11
11
  "components/codegraph",
12
12
  "components/comment-checker",
@@ -93,7 +93,7 @@
93
93
  },
94
94
  "components/codegraph": {
95
95
  "name": "@sisyphuslabs/codex-codegraph",
96
- "version": "4.15.1",
96
+ "version": "4.16.1",
97
97
  "bin": {
98
98
  "omo-codegraph": "dist/cli.js"
99
99
  },
@@ -112,7 +112,7 @@
112
112
  },
113
113
  "components/comment-checker": {
114
114
  "name": "@code-yeongyu/codex-comment-checker",
115
- "version": "4.15.1",
115
+ "version": "4.16.1",
116
116
  "license": "MIT",
117
117
  "bin": {
118
118
  "omo-comment-checker": "dist/cli.js"
@@ -133,7 +133,7 @@
133
133
  },
134
134
  "components/git-bash": {
135
135
  "name": "@sisyphuslabs/codex-git-bash-hook",
136
- "version": "4.15.1",
136
+ "version": "4.16.1",
137
137
  "bin": {
138
138
  "omo-git-bash-hook": "dist/cli.js"
139
139
  },
@@ -148,7 +148,7 @@
148
148
  },
149
149
  "components/lazycodex-executor-verify": {
150
150
  "name": "@code-yeongyu/codex-lazycodex-executor-verify",
151
- "version": "4.15.1",
151
+ "version": "4.16.1",
152
152
  "license": "MIT",
153
153
  "bin": {
154
154
  "lazycodex-executor-verify": "dist/cli.js"
@@ -165,7 +165,7 @@
165
165
  },
166
166
  "components/lsp": {
167
167
  "name": "@code-yeongyu/codex-lsp",
168
- "version": "4.15.1",
168
+ "version": "4.16.1",
169
169
  "license": "MIT",
170
170
  "dependencies": {
171
171
  "@code-yeongyu/lsp-daemon": "file:../../../../lsp-daemon"
@@ -185,7 +185,7 @@
185
185
  },
186
186
  "components/rules": {
187
187
  "name": "@code-yeongyu/codex-rules",
188
- "version": "4.15.1",
188
+ "version": "4.16.1",
189
189
  "license": "MIT",
190
190
  "dependencies": {
191
191
  "picomatch": "^4.0.3"
@@ -207,7 +207,7 @@
207
207
  },
208
208
  "components/start-work-continuation": {
209
209
  "name": "@code-yeongyu/codex-start-work-continuation",
210
- "version": "4.15.1",
210
+ "version": "4.16.1",
211
211
  "license": "MIT",
212
212
  "bin": {
213
213
  "omo-start-work-continuation": "dist/cli.js"
@@ -224,7 +224,7 @@
224
224
  },
225
225
  "components/teammode": {
226
226
  "name": "@sisyphuslabs/codex-teammode",
227
- "version": "4.15.1",
227
+ "version": "4.16.1",
228
228
  "devDependencies": {
229
229
  "@types/node": "^25.9.3",
230
230
  "bun-types": "^1.3.1",
@@ -237,7 +237,7 @@
237
237
  },
238
238
  "components/telemetry": {
239
239
  "name": "@code-yeongyu/codex-telemetry",
240
- "version": "4.15.1",
240
+ "version": "4.16.1",
241
241
  "license": "MIT",
242
242
  "bin": {
243
243
  "omo-telemetry": "dist/cli.js"
@@ -255,7 +255,7 @@
255
255
  },
256
256
  "components/ultrawork": {
257
257
  "name": "@code-yeongyu/codex-ultrawork",
258
- "version": "4.15.1",
258
+ "version": "4.16.1",
259
259
  "license": "MIT",
260
260
  "bin": {
261
261
  "omo-ultrawork": "dist/cli.js"
@@ -273,7 +273,7 @@
273
273
  },
274
274
  "components/ulw-loop": {
275
275
  "name": "@code-yeongyu/codex-ulw-loop",
276
- "version": "4.15.1",
276
+ "version": "4.16.1",
277
277
  "license": "MIT",
278
278
  "bin": {
279
279
  "omo-ulw-loop": "dist/cli.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/omo-codex-plugin",
3
- "version": "4.15.1",
3
+ "version": "4.16.1",
4
4
  "description": "Aggregate Codex plugin root for OMO components.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { spawnSync } from "node:child_process";
2
+ import { spawn } from "node:child_process";
3
+ import { availableParallelism } from "node:os";
3
4
  import { readdir, readFile, writeFile } from "node:fs/promises";
4
5
  import { builtinModules } from "node:module";
5
6
  import { dirname, join } from "node:path";
@@ -11,22 +12,50 @@ const workspaces = Array.isArray(packageJson.workspaces) ? packageJson.workspace
11
12
  const workspaceSet = new Set(workspaces);
12
13
  const builtinModuleNames = new Set(builtinModules.filter((moduleName) => !moduleName.startsWith("_")));
13
14
 
15
+ const workspaceComponents = [];
14
16
  for (const workspace of workspaces) {
15
17
  if (typeof workspace !== "string" || !workspace.startsWith("components/")) continue;
16
18
  if (!(await hasBuildScript(workspace))) continue;
17
-
18
- console.log(`Building ${workspace}`);
19
- run("npm", ["run", "--workspace", workspace, "build"], root);
20
- await bundleCli(workspace);
19
+ workspaceComponents.push({
20
+ componentPath: workspace,
21
+ buildCommand: "npm",
22
+ buildArgs: ["run", "--workspace", workspace, "build"],
23
+ buildCwd: root,
24
+ });
21
25
  }
22
26
 
27
+ const standaloneComponents = [];
23
28
  for (const componentName of await readStandaloneComponentNames()) {
24
29
  const componentPath = `components/${componentName}`;
25
30
  if (!(await hasBuildScript(componentPath))) continue;
31
+ standaloneComponents.push({
32
+ componentPath,
33
+ buildCommand: "npm",
34
+ buildArgs: ["run", "build"],
35
+ buildCwd: join(root, componentPath),
36
+ });
37
+ }
38
+
39
+ const tasks = [...workspaceComponents, ...standaloneComponents];
40
+ const concurrency = Math.max(1, Math.min(tasks.length, availableParallelism()));
41
+ await runTasksWithConcurrency(tasks, concurrency);
42
+
43
+ async function runTasksWithConcurrency(items, limit) {
44
+ let nextIndex = 0;
45
+ const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
46
+ while (true) {
47
+ const index = nextIndex;
48
+ nextIndex += 1;
49
+ if (index >= items.length) return;
50
+ await buildComponent(items[index]);
51
+ }
52
+ });
53
+ await Promise.all(workers);
54
+ }
26
55
 
27
- console.log(`Building ${componentPath} (standalone)`);
28
- run("npm", ["run", "build"], join(root, componentPath));
29
- await bundleCli(componentPath);
56
+ async function buildComponent(task) {
57
+ await runCaptured(task.buildCommand, task.buildArgs, task.buildCwd, `Building ${task.componentPath}`);
58
+ await bundleCli(task.componentPath);
30
59
  }
31
60
 
32
61
  async function readStandaloneComponentNames() {
@@ -51,19 +80,36 @@ async function hasBuildScript(relativePath) {
51
80
  async function bundleCli(workspace) {
52
81
  const entry = join(root, workspace, "src", "cli.ts");
53
82
  const output = join(root, workspace, "dist", "cli.js");
54
- console.log(`Bundling ${workspace}/dist/cli.js`);
55
- run("bun", ["build", entry, "--target", "node", "--format", "esm", "--outfile", output], root);
83
+ await runCaptured("bun", ["build", entry, "--target", "node", "--format", "esm", "--outfile", output], root, `Bundling ${workspace}/dist/cli.js`);
56
84
  await normalizeBuiltinImports(output);
57
85
  }
58
86
 
59
- function run(command, args, cwd) {
60
- const result = spawnSync(command, args, {
61
- cwd,
62
- shell: process.platform === "win32",
63
- stdio: "inherit",
87
+ // Buffers each child's stdout/stderr and flushes it as one contiguous block so
88
+ // concurrent builds never interleave, keeping a failing component's output readable.
89
+ function runCaptured(command, args, cwd, label) {
90
+ return new Promise((resolve, reject) => {
91
+ const child = spawn(command, args, {
92
+ cwd,
93
+ shell: process.platform === "win32",
94
+ stdio: ["ignore", "pipe", "pipe"],
95
+ });
96
+ const chunks = [];
97
+ child.stdout.on("data", (chunk) => chunks.push(chunk));
98
+ child.stderr.on("data", (chunk) => chunks.push(chunk));
99
+ child.on("error", (error) => reject(error));
100
+ child.on("close", (status, signal) => {
101
+ const output = Buffer.concat(chunks).toString("utf8");
102
+ process.stdout.write(`${label}\n${output}`);
103
+ if (status === 0) {
104
+ resolve();
105
+ return;
106
+ }
107
+ const reason = signal ? `signal ${signal}` : `exit code ${status}`;
108
+ const error = new Error(`${label} failed with ${reason}`);
109
+ error.exitCode = status ?? 1;
110
+ reject(error);
111
+ });
64
112
  });
65
- if (result.error !== undefined) throw result.error;
66
- if (result.status !== 0) process.exit(result.status ?? 1);
67
113
  }
68
114
 
69
115
  async function normalizeBuiltinImports(output) {