oh-my-opencode 4.8.1 → 4.9.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 (509) hide show
  1. package/dist/agents/prometheus/system-prompt.d.ts +1 -1
  2. package/dist/agents/sisyphus/claude-fable-5.d.ts +19 -0
  3. package/dist/agents/sisyphus/claude-opus-4-7.d.ts +3 -1
  4. package/dist/agents/sisyphus/claude-opus-4-8.d.ts +19 -0
  5. package/dist/agents/sisyphus/index.d.ts +4 -0
  6. package/dist/agents/types.d.ts +2 -2
  7. package/dist/cli/doctor/checks/codex.d.ts +1 -0
  8. package/dist/cli/doctor/checks/dependencies.d.ts +2 -2
  9. package/dist/cli/doctor/checks/tools-gh.d.ts +8 -1
  10. package/dist/cli/doctor/index.d.ts +1 -0
  11. package/dist/cli/doctor/types.d.ts +2 -0
  12. package/dist/cli/index.js +1908 -787
  13. package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -1
  14. package/dist/cli/install-codex/codex-config-plugins.d.ts +1 -0
  15. package/dist/cli/install-codex/codex-config-toml.d.ts +1 -0
  16. package/dist/cli/install-codex/codex-installer-bin-dir.d.ts +8 -0
  17. package/dist/cli/install-codex/install-codex.d.ts +1 -8
  18. package/dist/cli/install-codex/lsp-daemon-reaper.d.ts +5 -0
  19. package/dist/cli/sparkshell-condense.d.ts +10 -0
  20. package/dist/cli/sparkshell-parse.d.ts +3 -0
  21. package/dist/cli/sparkshell-session-context.d.ts +20 -0
  22. package/dist/cli/sparkshell-spark.d.ts +23 -0
  23. package/dist/cli/sparkshell.d.ts +8 -1
  24. package/dist/cli-node/index.js +92564 -0
  25. package/dist/config/schema/agent-names.d.ts +2 -0
  26. package/dist/config/schema/hooks.d.ts +0 -2
  27. package/dist/config/schema/keyword-detector.d.ts +0 -6
  28. package/dist/config/schema/oh-my-opencode-config.d.ts +2 -4
  29. package/dist/create-hooks.d.ts +0 -2
  30. package/dist/features/background-agent/parent-wake-dedupe.d.ts +2 -0
  31. package/dist/features/background-agent/parent-wake-flush-runner.d.ts +2 -0
  32. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -0
  33. package/dist/features/background-agent/parent-wake-session-history.d.ts +4 -0
  34. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -0
  35. package/dist/features/builtin-commands/templates/handoff.d.ts +1 -1
  36. package/dist/features/builtin-skills/index.d.ts +1 -1
  37. package/dist/features/builtin-skills/skills.d.ts +4 -0
  38. package/dist/features/opencode-runtime-skills/source-server.d.ts +16 -1
  39. package/dist/features/opencode-skill-loader/skill-definition-record.d.ts +2 -0
  40. package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +2 -0
  41. package/dist/features/team-mode/types.d.ts +1 -0
  42. package/dist/features/tmux-subagent/failed-readiness-cache.d.ts +28 -0
  43. package/dist/features/tmux-subagent/manager.d.ts +1 -9
  44. package/dist/features/tmux-subagent/resolve-server-url.d.ts +3 -0
  45. package/dist/hooks/anthropic-context-window-limit-recovery/executor.d.ts +1 -1
  46. package/dist/hooks/index.d.ts +0 -1
  47. package/dist/hooks/keyword-detector/constants.d.ts +0 -4
  48. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +1 -1
  49. package/dist/index.js +9001 -1795
  50. package/dist/oh-my-opencode.schema.json +2 -4
  51. package/dist/plugin/chat-params.d.ts +1 -8
  52. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -2
  53. package/dist/plugin/hooks/create-session-hooks.d.ts +0 -2
  54. package/dist/plugin/hooks/create-transform-hooks.d.ts +1 -2
  55. package/dist/plugin/messages-transform.d.ts +0 -1
  56. package/dist/shared/model-availability.d.ts +10 -2
  57. package/dist/shared/module-resolution-failure.d.ts +7 -0
  58. package/package.json +25 -18
  59. package/packages/ast-grep-mcp/dist/cli.js +2 -10
  60. package/packages/git-bash-mcp/dist/cli.js +11 -4
  61. package/packages/lsp-daemon/dist/cli.d.ts +2 -0
  62. package/packages/lsp-daemon/dist/cli.js +3711 -0
  63. package/packages/lsp-daemon/dist/daemon-client.d.ts +19 -0
  64. package/packages/lsp-daemon/dist/daemon-client.js +114 -0
  65. package/packages/lsp-daemon/dist/daemon-server.d.ts +12 -0
  66. package/packages/lsp-daemon/dist/daemon-server.js +106 -0
  67. package/packages/lsp-daemon/dist/ensure-daemon.d.ts +21 -0
  68. package/packages/lsp-daemon/dist/ensure-daemon.js +97 -0
  69. package/packages/lsp-daemon/dist/index.d.ts +5 -0
  70. package/packages/lsp-daemon/dist/index.js +3573 -0
  71. package/packages/lsp-daemon/dist/lock.d.ts +7 -0
  72. package/packages/lsp-daemon/dist/lock.js +61 -0
  73. package/packages/lsp-daemon/dist/package.json +6 -0
  74. package/packages/lsp-daemon/dist/paths.d.ts +11 -0
  75. package/packages/lsp-daemon/dist/paths.js +49 -0
  76. package/packages/lsp-daemon/dist/proxy.d.ts +10 -0
  77. package/packages/lsp-daemon/dist/proxy.js +61 -0
  78. package/packages/lsp-daemon/dist/request-routing.d.ts +9 -0
  79. package/packages/lsp-daemon/dist/request-routing.js +44 -0
  80. package/packages/lsp-daemon/dist/run-daemon.d.ts +1 -0
  81. package/packages/lsp-daemon/dist/run-daemon.js +11 -0
  82. package/packages/lsp-daemon/dist/socket-jsonrpc.d.ts +5 -0
  83. package/packages/lsp-daemon/dist/socket-jsonrpc.js +25 -0
  84. package/packages/lsp-daemon/package.json +38 -0
  85. package/packages/lsp-tools-mcp/dist/cli.js +0 -0
  86. package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +40 -17
  87. package/packages/lsp-tools-mcp/dist/lsp/client.js +11 -9
  88. package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +5 -5
  89. package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js +5 -3
  90. package/packages/lsp-tools-mcp/dist/lsp/effective-extension.d.ts +1 -0
  91. package/packages/lsp-tools-mcp/dist/lsp/effective-extension.js +8 -0
  92. package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js +3 -2
  93. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js +1 -0
  94. package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +12 -0
  95. package/packages/lsp-tools-mcp/dist/lsp/server-install-state.d.ts +12 -0
  96. package/packages/lsp-tools-mcp/dist/lsp/server-install-state.js +51 -0
  97. package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +2 -1
  98. package/packages/lsp-tools-mcp/dist/request-context.d.ts +7 -0
  99. package/packages/lsp-tools-mcp/dist/request-context.js +14 -0
  100. package/packages/lsp-tools-mcp/dist/tools.js +44 -1
  101. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +46 -33
  102. package/packages/omo-codex/plugin/.mcp.json +1 -1
  103. package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.d.ts +7 -0
  104. package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.js +173 -0
  105. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.d.ts +2 -0
  106. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +10 -0
  107. package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.d.ts +22 -0
  108. package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.js +165 -0
  109. package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.d.ts +1 -0
  110. package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.js +1 -0
  111. package/packages/omo-codex/plugin/components/comment-checker/dist/core.d.ts +5 -0
  112. package/packages/omo-codex/plugin/components/comment-checker/dist/core.js +4 -0
  113. package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.d.ts +6 -0
  114. package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.js +10 -0
  115. package/packages/omo-codex/plugin/components/comment-checker/dist/record.d.ts +2 -0
  116. package/packages/omo-codex/plugin/components/comment-checker/dist/record.js +11 -0
  117. package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.d.ts +3 -0
  118. package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.js +104 -0
  119. package/packages/omo-codex/plugin/components/comment-checker/dist/runner.d.ts +26 -0
  120. package/packages/omo-codex/plugin/components/comment-checker/dist/runner.js +144 -0
  121. package/packages/omo-codex/plugin/components/comment-checker/dist/types.d.ts +43 -0
  122. package/packages/omo-codex/plugin/components/comment-checker/dist/types.js +1 -0
  123. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  124. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  125. package/packages/omo-codex/plugin/components/git-bash/dist/cli.d.ts +2 -0
  126. package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +29 -0
  127. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.d.ts +28 -0
  128. package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +137 -0
  129. package/packages/omo-codex/plugin/components/git-bash/dist/index.d.ts +1 -0
  130. package/packages/omo-codex/plugin/components/git-bash/dist/index.js +1 -0
  131. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  132. package/packages/omo-codex/plugin/components/git-bash/package.json +5 -2
  133. package/packages/omo-codex/plugin/components/lsp/.mcp.json +1 -1
  134. package/packages/omo-codex/plugin/components/lsp/dist/cli.d.ts +2 -0
  135. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +42 -0
  136. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.d.ts +2 -0
  137. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.js +40 -0
  138. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.d.ts +16 -0
  139. package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +180 -0
  140. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.d.ts +12 -0
  141. package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +95 -0
  142. package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.d.ts +6 -0
  143. package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.js +79 -0
  144. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  145. package/packages/omo-codex/plugin/components/lsp/package.json +7 -7
  146. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-daemon.mjs +68 -0
  147. package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.mjs +45 -22
  148. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  149. package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +1 -1
  150. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +6 -2
  151. package/packages/omo-codex/plugin/components/lsp/src/lsp-session-state.ts +4 -0
  152. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +68 -0
  153. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +8 -20
  154. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +69 -96
  155. package/packages/omo-codex/plugin/components/rules/dist/cli.d.ts +2 -0
  156. package/packages/omo-codex/plugin/components/rules/dist/cli.js +118 -0
  157. package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.d.ts +5 -0
  158. package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.js +1 -0
  159. package/packages/omo-codex/plugin/components/rules/dist/codex-hook.d.ts +47 -0
  160. package/packages/omo-codex/plugin/components/rules/dist/codex-hook.js +127 -0
  161. package/packages/omo-codex/plugin/components/rules/dist/config.d.ts +2 -0
  162. package/packages/omo-codex/plugin/components/rules/dist/config.js +100 -0
  163. package/packages/omo-codex/plugin/components/rules/dist/context-pressure.d.ts +2 -0
  164. package/packages/omo-codex/plugin/components/rules/dist/context-pressure.js +26 -0
  165. package/packages/omo-codex/plugin/components/rules/dist/debug-log.d.ts +8 -0
  166. package/packages/omo-codex/plugin/components/rules/dist/debug-log.js +36 -0
  167. package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.d.ts +7 -0
  168. package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.js +65 -0
  169. package/packages/omo-codex/plugin/components/rules/dist/event-budget.d.ts +3 -0
  170. package/packages/omo-codex/plugin/components/rules/dist/event-budget.js +14 -0
  171. package/packages/omo-codex/plugin/components/rules/dist/hook-output.d.ts +2 -0
  172. package/packages/omo-codex/plugin/components/rules/dist/hook-output.js +24 -0
  173. package/packages/omo-codex/plugin/components/rules/dist/path-utils.d.ts +4 -0
  174. package/packages/omo-codex/plugin/components/rules/dist/path-utils.js +24 -0
  175. package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.d.ts +13 -0
  176. package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.js +172 -0
  177. package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.d.ts +6 -0
  178. package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.js +74 -0
  179. package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.d.ts +4 -0
  180. package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.js +6 -0
  181. package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.d.ts +1 -0
  182. package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.js +32 -0
  183. package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.d.ts +13 -0
  184. package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.js +29 -0
  185. package/packages/omo-codex/plugin/components/rules/dist/rules/cache.d.ts +9 -0
  186. package/packages/omo-codex/plugin/components/rules/dist/rules/cache.js +51 -0
  187. package/packages/omo-codex/plugin/components/rules/dist/rules/constants.d.ts +70 -0
  188. package/packages/omo-codex/plugin/components/rules/dist/rules/constants.js +101 -0
  189. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.d.ts +5 -0
  190. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.js +60 -0
  191. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.d.ts +6 -0
  192. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.js +61 -0
  193. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.d.ts +7 -0
  194. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.js +60 -0
  195. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.d.ts +11 -0
  196. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.js +75 -0
  197. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.d.ts +6 -0
  198. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.js +29 -0
  199. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.d.ts +44 -0
  200. package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.js +1 -0
  201. package/packages/omo-codex/plugin/components/rules/dist/rules/engine.d.ts +5 -0
  202. package/packages/omo-codex/plugin/components/rules/dist/rules/engine.js +85 -0
  203. package/packages/omo-codex/plugin/components/rules/dist/rules/errors.d.ts +6 -0
  204. package/packages/omo-codex/plugin/components/rules/dist/rules/errors.js +12 -0
  205. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.d.ts +14 -0
  206. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.js +51 -0
  207. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.d.ts +6 -0
  208. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.js +33 -0
  209. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.d.ts +5 -0
  210. package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.js +40 -0
  211. package/packages/omo-codex/plugin/components/rules/dist/rules/finder.d.ts +28 -0
  212. package/packages/omo-codex/plugin/components/rules/dist/rules/finder.js +146 -0
  213. package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.d.ts +7 -0
  214. package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.js +112 -0
  215. package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.d.ts +18 -0
  216. package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.js +93 -0
  217. package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.d.ts +3 -0
  218. package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.js +27 -0
  219. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.d.ts +7 -0
  220. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.js +30 -0
  221. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.d.ts +2 -0
  222. package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.js +237 -0
  223. package/packages/omo-codex/plugin/components/rules/dist/rules/parser.d.ts +3 -0
  224. package/packages/omo-codex/plugin/components/rules/dist/rules/parser.js +31 -0
  225. package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.d.ts +1 -0
  226. package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.js +48 -0
  227. package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.d.ts +1 -0
  228. package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.js +23 -0
  229. package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.d.ts +14 -0
  230. package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.js +111 -0
  231. package/packages/omo-codex/plugin/components/rules/dist/rules/sources.d.ts +3 -0
  232. package/packages/omo-codex/plugin/components/rules/dist/rules/sources.js +9 -0
  233. package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.d.ts +18 -0
  234. package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.js +59 -0
  235. package/packages/omo-codex/plugin/components/rules/dist/rules/types.d.ts +126 -0
  236. package/packages/omo-codex/plugin/components/rules/dist/rules/types.js +8 -0
  237. package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.d.ts +6 -0
  238. package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.js +20 -0
  239. package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.d.ts +3 -0
  240. package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.js +41 -0
  241. package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.d.ts +10 -0
  242. package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.js +90 -0
  243. package/packages/omo-codex/plugin/components/rules/dist/static-injection.d.ts +3 -0
  244. package/packages/omo-codex/plugin/components/rules/dist/static-injection.js +128 -0
  245. package/packages/omo-codex/plugin/components/rules/dist/tool-paths.d.ts +6 -0
  246. package/packages/omo-codex/plugin/components/rules/dist/tool-paths.js +168 -0
  247. package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.d.ts +4 -0
  248. package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.js +49 -0
  249. package/packages/omo-codex/plugin/components/rules/dist/transcript-search.d.ts +4 -0
  250. package/packages/omo-codex/plugin/components/rules/dist/transcript-search.js +91 -0
  251. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  252. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  253. package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +4 -2
  254. package/packages/omo-codex/plugin/components/rules/src/config.ts +13 -0
  255. package/packages/omo-codex/plugin/components/rules/src/event-budget.ts +17 -0
  256. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +4 -1
  257. package/packages/omo-codex/plugin/components/rules/src/post-compact-directive.ts +39 -0
  258. package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +16 -0
  259. package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +8 -0
  260. package/packages/omo-codex/plugin/components/rules/src/rules/types.ts +4 -0
  261. package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +53 -4
  262. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +127 -7
  263. package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +9 -1
  264. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +4 -2
  265. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +7 -2
  266. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +9 -9
  267. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +10 -4
  268. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +241 -0
  269. package/packages/omo-codex/plugin/components/rules/test/event-budget.test.ts +168 -0
  270. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -0
  271. package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +86 -3
  272. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +15 -15
  273. package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.d.ts +16 -0
  274. package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.js +146 -0
  275. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.d.ts +2 -0
  276. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +49 -0
  277. package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.d.ts +2 -0
  278. package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.js +80 -0
  279. package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.d.ts +1 -0
  280. package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.js +2 -0
  281. package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.d.ts +5 -0
  282. package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.js +3 -0
  283. package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.d.ts +20 -0
  284. package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.js +1 -0
  285. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  286. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  287. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +24 -2
  288. package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.d.ts +1 -0
  289. package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.js +18 -0
  290. package/packages/omo-codex/plugin/components/telemetry/dist/cli.d.ts +2 -0
  291. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +62 -0
  292. package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.d.ts +15 -0
  293. package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.js +42 -0
  294. package/packages/omo-codex/plugin/components/telemetry/dist/data-path.d.ts +10 -0
  295. package/packages/omo-codex/plugin/components/telemetry/dist/data-path.js +35 -0
  296. package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.d.ts +12 -0
  297. package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.js +108 -0
  298. package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.d.ts +4 -0
  299. package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.js +31 -0
  300. package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.d.ts +8 -0
  301. package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.js +68 -0
  302. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.d.ts +21 -0
  303. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +133 -0
  304. package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.d.ts +8 -0
  305. package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.js +29 -0
  306. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  307. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  308. package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +5 -13
  309. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +61 -185
  310. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  311. package/packages/omo-codex/plugin/components/ultrawork/directive.md +122 -117
  312. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.d.ts +2 -0
  313. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +48 -0
  314. package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.d.ts +7 -0
  315. package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.js +122 -0
  316. package/packages/omo-codex/plugin/components/ultrawork/dist/directive.d.ts +1 -0
  317. package/packages/omo-codex/plugin/components/ultrawork/dist/directive.js +2 -0
  318. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  319. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  320. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +20 -11
  321. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +17 -11
  322. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +2 -5
  323. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -71
  324. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +16 -0
  325. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +200 -0
  326. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.d.ts +17 -0
  327. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +97 -0
  328. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.d.ts +4 -0
  329. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +183 -0
  330. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +6 -0
  331. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +55 -0
  332. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +12 -0
  333. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +145 -0
  334. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.d.ts +2 -0
  335. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +39 -0
  336. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +13 -0
  337. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +100 -0
  338. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +26 -0
  339. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +97 -0
  340. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +28 -0
  341. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +145 -0
  342. package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.d.ts +34 -0
  343. package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.js +1 -0
  344. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +16 -0
  345. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +41 -0
  346. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +95 -0
  347. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.js +1 -0
  348. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +31 -0
  349. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +119 -0
  350. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +12 -0
  351. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +69 -0
  352. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +16 -0
  353. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +59 -0
  354. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +48 -0
  355. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +119 -0
  356. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +8 -0
  357. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +89 -0
  358. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +6 -0
  359. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +123 -0
  360. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +16 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +70 -0
  362. package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.d.ts +10 -0
  363. package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.js +13 -0
  364. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +63 -0
  365. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.js +1 -0
  366. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +6 -0
  367. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +292 -0
  368. package/packages/omo-codex/plugin/components/ulw-loop/dist/types.d.ts +5 -0
  369. package/packages/omo-codex/plugin/components/ulw-loop/dist/types.js +5 -0
  370. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  371. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  372. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +14 -14
  373. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +24 -25
  374. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -3
  375. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +2 -1
  376. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -1
  377. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +95 -0
  378. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +0 -96
  379. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +23 -0
  380. package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +46 -0
  381. package/packages/omo-codex/plugin/hooks/hooks.json +16 -16
  382. package/packages/omo-codex/plugin/package-lock.json +10 -9
  383. package/packages/omo-codex/plugin/package.json +27 -26
  384. package/packages/omo-codex/plugin/scripts/auto-update.mjs +64 -15
  385. package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -0
  386. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +82 -18
  387. package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +2 -2
  388. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +23 -11
  389. package/packages/omo-codex/plugin/scripts/sync-version.mjs +94 -0
  390. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +9 -9
  391. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
  392. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +93 -0
  393. package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +11 -0
  394. package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +17 -13
  395. package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +139 -0
  396. package/packages/omo-codex/plugin/skills/lsp-setup/references/bash/README.md +60 -0
  397. package/packages/omo-codex/plugin/skills/lsp-setup/references/c-cpp/README.md +61 -0
  398. package/packages/omo-codex/plugin/skills/lsp-setup/references/csharp/README.md +71 -0
  399. package/packages/omo-codex/plugin/skills/lsp-setup/references/dart/README.md +48 -0
  400. package/packages/omo-codex/plugin/skills/lsp-setup/references/elixir/README.md +51 -0
  401. package/packages/omo-codex/plugin/skills/lsp-setup/references/go/README.md +57 -0
  402. package/packages/omo-codex/plugin/skills/lsp-setup/references/haskell/README.md +57 -0
  403. package/packages/omo-codex/plugin/skills/lsp-setup/references/java/README.md +57 -0
  404. package/packages/omo-codex/plugin/skills/lsp-setup/references/julia/README.md +60 -0
  405. package/packages/omo-codex/plugin/skills/lsp-setup/references/kotlin/README.md +59 -0
  406. package/packages/omo-codex/plugin/skills/lsp-setup/references/lua/README.md +66 -0
  407. package/packages/omo-codex/plugin/skills/lsp-setup/references/php/README.md +62 -0
  408. package/packages/omo-codex/plugin/skills/lsp-setup/references/python/README.md +71 -0
  409. package/packages/omo-codex/plugin/skills/lsp-setup/references/ruby/README.md +53 -0
  410. package/packages/omo-codex/plugin/skills/lsp-setup/references/rust/README.md +59 -0
  411. package/packages/omo-codex/plugin/skills/lsp-setup/references/swift/README.md +51 -0
  412. package/packages/omo-codex/plugin/skills/lsp-setup/references/terraform/README.md +62 -0
  413. package/packages/omo-codex/plugin/skills/lsp-setup/references/typescript/README.md +77 -0
  414. package/packages/omo-codex/plugin/skills/lsp-setup/references/yaml/README.md +70 -0
  415. package/packages/omo-codex/plugin/skills/lsp-setup/references/zig/README.md +49 -0
  416. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
  417. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
  418. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/tsconfig.json +17 -0
  419. package/packages/omo-codex/plugin/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
  420. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +9 -9
  421. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +10 -10
  422. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +20 -22
  423. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +38 -61
  424. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +135 -677
  425. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -14
  426. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +24 -25
  427. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +20 -11
  428. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +17 -11
  429. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +9 -9
  430. package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
  431. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +1 -1
  432. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +5 -5
  433. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +6 -6
  434. package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +194 -0
  435. package/packages/omo-codex/plugin/test/auto-update.test.mjs +17 -0
  436. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +15 -44
  437. package/packages/omo-codex/plugin/test/lsp-prebuild-layouts.test.mjs +140 -0
  438. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +189 -7
  439. package/packages/omo-codex/plugin/test/start-work-skill.test.mjs +9 -31
  440. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +68 -4
  441. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +119 -0
  442. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +11 -112
  443. package/packages/omo-codex/plugin/test/sync-version.test.mjs +68 -0
  444. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +126 -0
  445. package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +2 -2
  446. package/packages/omo-codex/scripts/install/bin-dir.mjs +20 -0
  447. package/packages/omo-codex/scripts/install/bin-links.mjs +43 -6
  448. package/packages/omo-codex/scripts/install/cache.mjs +4 -0
  449. package/packages/omo-codex/scripts/install/config.mjs +4 -4
  450. package/packages/omo-codex/scripts/install/delegated-command.mjs +5 -1
  451. package/packages/omo-codex/scripts/install/git-bash-mcp-env.mjs +28 -0
  452. package/packages/omo-codex/scripts/install/git-bash.mjs +12 -4
  453. package/packages/omo-codex/scripts/install/git-bash.test.mjs +39 -4
  454. package/packages/omo-codex/scripts/install/hook-targets.mjs +46 -0
  455. package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +12 -2
  456. package/packages/omo-codex/scripts/install/process.mjs +1 -0
  457. package/packages/omo-codex/scripts/install-bin-links.test.mjs +131 -3
  458. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +91 -0
  459. package/packages/omo-codex/scripts/install-config.test.mjs +50 -44
  460. package/packages/omo-codex/scripts/install-delegated-command.test.mjs +78 -0
  461. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +93 -0
  462. package/packages/omo-codex/scripts/install-hook-targets.test.mjs +100 -0
  463. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +3 -1
  464. package/packages/omo-codex/scripts/install-local.mjs +7 -18
  465. package/packages/omo-codex/scripts/install-local.test.mjs +34 -1
  466. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
  467. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +93 -0
  468. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +11 -0
  469. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +17 -13
  470. package/packages/shared-skills/skills/lsp-setup/SKILL.md +139 -0
  471. package/packages/shared-skills/skills/lsp-setup/references/bash/README.md +60 -0
  472. package/packages/shared-skills/skills/lsp-setup/references/c-cpp/README.md +61 -0
  473. package/packages/shared-skills/skills/lsp-setup/references/csharp/README.md +71 -0
  474. package/packages/shared-skills/skills/lsp-setup/references/dart/README.md +48 -0
  475. package/packages/shared-skills/skills/lsp-setup/references/elixir/README.md +51 -0
  476. package/packages/shared-skills/skills/lsp-setup/references/go/README.md +57 -0
  477. package/packages/shared-skills/skills/lsp-setup/references/haskell/README.md +57 -0
  478. package/packages/shared-skills/skills/lsp-setup/references/java/README.md +57 -0
  479. package/packages/shared-skills/skills/lsp-setup/references/julia/README.md +60 -0
  480. package/packages/shared-skills/skills/lsp-setup/references/kotlin/README.md +59 -0
  481. package/packages/shared-skills/skills/lsp-setup/references/lua/README.md +66 -0
  482. package/packages/shared-skills/skills/lsp-setup/references/php/README.md +62 -0
  483. package/packages/shared-skills/skills/lsp-setup/references/python/README.md +71 -0
  484. package/packages/shared-skills/skills/lsp-setup/references/ruby/README.md +53 -0
  485. package/packages/shared-skills/skills/lsp-setup/references/rust/README.md +59 -0
  486. package/packages/shared-skills/skills/lsp-setup/references/swift/README.md +51 -0
  487. package/packages/shared-skills/skills/lsp-setup/references/terraform/README.md +62 -0
  488. package/packages/shared-skills/skills/lsp-setup/references/typescript/README.md +77 -0
  489. package/packages/shared-skills/skills/lsp-setup/references/yaml/README.md +70 -0
  490. package/packages/shared-skills/skills/lsp-setup/references/zig/README.md +49 -0
  491. package/packages/shared-skills/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
  492. package/packages/shared-skills/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
  493. package/packages/shared-skills/skills/lsp-setup/scripts/tsconfig.json +17 -0
  494. package/packages/shared-skills/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
  495. package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
  496. package/packages/shared-skills/skills/review-work/SKILL.md +10 -14
  497. package/packages/shared-skills/skills/start-work/SKILL.md +30 -59
  498. package/packages/shared-skills/skills/ultraresearch/SKILL.md +126 -667
  499. package/dist/hooks/anthropic-effort/hook.d.ts +0 -26
  500. package/dist/hooks/anthropic-effort/index.d.ts +0 -1
  501. package/dist/hooks/keyword-detector/analyze/default.d.ts +0 -12
  502. package/dist/hooks/keyword-detector/analyze/index.d.ts +0 -1
  503. package/dist/hooks/keyword-detector/search/default.d.ts +0 -12
  504. package/dist/hooks/keyword-detector/search/index.d.ts +0 -1
  505. package/dist/hooks/thinking-block-validator/hook.d.ts +0 -12
  506. package/dist/hooks/thinking-block-validator/index.d.ts +0 -1
  507. package/packages/omo-codex/plugin/components/ultrawork/test/directive-contract.test.ts +0 -18
  508. package/packages/omo-codex/plugin/test/global-review-debug-gate.test.mjs +0 -29
  509. package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +0 -151
@@ -0,0 +1,49 @@
1
+ import { readTranscriptSearchText } from "./transcript-search.js";
2
+ export function filterRulesAlreadyInTranscript(rules, transcriptPath, markInjected, options = {}) {
3
+ if (rules.length === 0 || transcriptPath === null) {
4
+ return [...rules];
5
+ }
6
+ const transcriptText = readTranscriptSearchText(transcriptPath, options);
7
+ return filterRulesNotInTranscriptText(rules, transcriptText, markInjected);
8
+ }
9
+ export function filterRulesNotInTranscriptText(rules, transcriptText, markInjected) {
10
+ if (rules.length === 0 || transcriptText === null) {
11
+ return [...rules];
12
+ }
13
+ const pendingRules = [];
14
+ for (const rule of rules) {
15
+ if (isRuleAlreadyInTranscript(rule, transcriptText)) {
16
+ markInjected(rule);
17
+ continue;
18
+ }
19
+ pendingRules.push(rule);
20
+ }
21
+ return pendingRules;
22
+ }
23
+ function isRuleAlreadyInTranscript(rule, transcriptText) {
24
+ const staticReferenceNeedles = [
25
+ `- [${displayFilename(rule)}]{${rule.path}}`,
26
+ `- [${displayFilename(rule)}]{${rule.realPath}}`,
27
+ ];
28
+ if (staticReferenceNeedles.some((needle) => transcriptText.includes(needle))) {
29
+ return true;
30
+ }
31
+ const bodyNeedle = rule.body.trim().slice(0, 2_000);
32
+ if (bodyNeedle.length === 0 || !transcriptText.includes(bodyNeedle)) {
33
+ return false;
34
+ }
35
+ const markers = [
36
+ `Instructions from: ${rule.path}`,
37
+ `Instructions from: ${rule.realPath}`,
38
+ rule.relativePath.length === 0 ? null : rule.relativePath,
39
+ ].filter((marker) => marker !== null);
40
+ return markers.some((marker) => transcriptText.includes(marker));
41
+ }
42
+ function displayFilename(rule) {
43
+ const normalizedPath = rule.relativePath.length > 0 ? rule.relativePath : rule.path;
44
+ const segments = normalizedPath
45
+ .replace(/\\/g, "/")
46
+ .split("/")
47
+ .filter((segment) => segment.length > 0);
48
+ return segments.at(-1) ?? normalizedPath;
49
+ }
@@ -0,0 +1,4 @@
1
+ export interface TranscriptSearchOptions {
2
+ readonly latestCompactedReplacementOnly?: boolean;
3
+ }
4
+ export declare function readTranscriptSearchText(transcriptPath: string, options?: TranscriptSearchOptions): string | null;
@@ -0,0 +1,91 @@
1
+ import { readFileSync } from "node:fs";
2
+ export function readTranscriptSearchText(transcriptPath, options = {}) {
3
+ try {
4
+ const rawTranscript = readFileSync(transcriptPath, "utf8");
5
+ if (options.latestCompactedReplacementOnly === true) {
6
+ return latestCompactedReplacementSearchText(rawTranscript);
7
+ }
8
+ return [rawTranscript, ...collectJsonLineStrings(rawTranscript)].join("\n");
9
+ }
10
+ catch (error) {
11
+ if (!(error instanceof Error)) {
12
+ throw error;
13
+ }
14
+ return null;
15
+ }
16
+ }
17
+ function latestCompactedReplacementSearchText(rawTranscript) {
18
+ const lines = rawTranscript.split(/\r?\n/);
19
+ let latestCompactedLineIndex = -1;
20
+ let replacementHistory = null;
21
+ for (const [index, line] of lines.entries()) {
22
+ const parsed = parseJsonLine(line);
23
+ if (!isRecord(parsed) || parsed["type"] !== "compacted") {
24
+ continue;
25
+ }
26
+ const payload = parsed["payload"];
27
+ if (!isRecord(payload)) {
28
+ continue;
29
+ }
30
+ const candidateReplacementHistory = payload["replacement_history"];
31
+ if (!Array.isArray(candidateReplacementHistory)) {
32
+ continue;
33
+ }
34
+ latestCompactedLineIndex = index;
35
+ replacementHistory = candidateReplacementHistory;
36
+ }
37
+ if (replacementHistory === null) {
38
+ return null;
39
+ }
40
+ const values = [];
41
+ collectStrings(replacementHistory, values);
42
+ const laterTranscript = lines.slice(latestCompactedLineIndex + 1).join("\n");
43
+ values.push(laterTranscript, ...collectJsonLineStrings(laterTranscript));
44
+ return values.join("\n");
45
+ }
46
+ function collectJsonLineStrings(rawTranscript) {
47
+ const values = [];
48
+ for (const line of rawTranscript.split(/\r?\n/)) {
49
+ const parsed = parseJsonLine(line);
50
+ if (parsed !== null) {
51
+ collectStrings(parsed, values);
52
+ }
53
+ }
54
+ return values;
55
+ }
56
+ function parseJsonLine(line) {
57
+ if (line.trim().length === 0) {
58
+ return null;
59
+ }
60
+ try {
61
+ const parsed = JSON.parse(line);
62
+ return parsed;
63
+ }
64
+ catch (error) {
65
+ if (!(error instanceof Error)) {
66
+ throw error;
67
+ }
68
+ return null;
69
+ }
70
+ }
71
+ function collectStrings(value, output) {
72
+ if (typeof value === "string") {
73
+ output.push(value);
74
+ return;
75
+ }
76
+ if (Array.isArray(value)) {
77
+ for (const item of value) {
78
+ collectStrings(item, output);
79
+ }
80
+ return;
81
+ }
82
+ if (!isRecord(value)) {
83
+ return;
84
+ }
85
+ for (const item of Object.values(value)) {
86
+ collectStrings(item, output);
87
+ }
88
+ }
89
+ function isRecord(value) {
90
+ return typeof value === "object" && value !== null && !Array.isArray(value);
91
+ }
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
9
9
  "timeout": 10,
10
- "statusMessage": "LazyCodex(0.1.0): Loading Project Rules"
10
+ "statusMessage": "LazyCodex(4.9.1): Loading Project Rules"
11
11
  }
12
12
  ]
13
13
  }
@@ -19,7 +19,7 @@
19
19
  "type": "command",
20
20
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
21
21
  "timeout": 10,
22
- "statusMessage": "LazyCodex(0.1.0): Loading Project Rules"
22
+ "statusMessage": "LazyCodex(4.9.1): Loading Project Rules"
23
23
  }
24
24
  ]
25
25
  }
@@ -32,7 +32,7 @@
32
32
  "type": "command",
33
33
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
34
34
  "timeout": 10,
35
- "statusMessage": "LazyCodex(0.1.0): Matching Project Rules"
35
+ "statusMessage": "LazyCodex(4.9.1): Matching Project Rules"
36
36
  }
37
37
  ]
38
38
  }
@@ -45,7 +45,7 @@
45
45
  "type": "command",
46
46
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
47
47
  "timeout": 10,
48
- "statusMessage": "LazyCodex(0.1.0): Resetting Project Rule Cache"
48
+ "statusMessage": "LazyCodex(4.9.1): Resetting Project Rule Cache"
49
49
  }
50
50
  ]
51
51
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-rules",
3
- "version": "0.1.0",
3
+ "version": "4.9.1",
4
4
  "description": "Codex plugin that injects project rule files into model context through lifecycle hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -3,6 +3,7 @@ import { configFromEnvironment } from "./config.js";
3
3
  import { hasContextPressureMarker, transcriptHasContextPressureMarker } from "./context-pressure.js";
4
4
  import { createHookDebugTimer } from "./debug-log.js";
5
5
  import { fingerprintDynamicTargets } from "./dynamic-target-fingerprints.js";
6
+ import { withDynamicBudget } from "./event-budget.js";
6
7
  import { formatAdditionalContextOutput } from "./hook-output.js";
7
8
  import { displayPath, uniqueStrings } from "./path-utils.js";
8
9
  import {
@@ -175,11 +176,12 @@ export async function runPostToolUseHook(
175
176
  debugTimer.done({ outputBytes: 0, reason: "post-compact-recovery-in-progress" });
176
177
  return "";
177
178
  }
179
+ const dynamicConfig = withDynamicBudget(config);
178
180
  const engine = createRulesEngine(
179
181
  options,
180
182
  completedPostCompactKind !== undefined
181
- ? withPostCompactBudget(config, { model: input.model, transcriptPath: input.transcript_path })
182
- : config,
183
+ ? withPostCompactBudget(dynamicConfig, { model: input.model, transcriptPath: input.transcript_path })
184
+ : dynamicConfig,
183
185
  );
184
186
  hydrateEngineState(engine, cachePath);
185
187
  debugTimer.lap("hydrate", {
@@ -21,6 +21,19 @@ export function configFromEnvironment(env: NodeJS.ProcessEnv = process.env): PiR
21
21
  parsePositiveInteger(
22
22
  firstEnv(env, "CODEX_RULES_POST_COMPACT_MAX_RESULT_CHARS", "PI_RULES_POST_COMPACT_MAX_RESULT_CHARS"),
23
23
  ) ?? config.postCompactMaxResultChars;
24
+ config.dynamicMaxRuleChars =
25
+ parsePositiveInteger(firstEnv(env, "CODEX_RULES_DYNAMIC_MAX_RULE_CHARS", "PI_RULES_DYNAMIC_MAX_RULE_CHARS")) ??
26
+ config.dynamicMaxRuleChars;
27
+ config.dynamicMaxResultChars =
28
+ parsePositiveInteger(
29
+ firstEnv(env, "CODEX_RULES_DYNAMIC_MAX_RESULT_CHARS", "PI_RULES_DYNAMIC_MAX_RESULT_CHARS"),
30
+ ) ?? config.dynamicMaxResultChars;
31
+ config.promptMaxRuleChars =
32
+ parsePositiveInteger(firstEnv(env, "CODEX_RULES_PROMPT_MAX_RULE_CHARS", "PI_RULES_PROMPT_MAX_RULE_CHARS")) ??
33
+ config.promptMaxRuleChars;
34
+ config.promptMaxResultChars =
35
+ parsePositiveInteger(firstEnv(env, "CODEX_RULES_PROMPT_MAX_RESULT_CHARS", "PI_RULES_PROMPT_MAX_RESULT_CHARS")) ??
36
+ config.promptMaxResultChars;
24
37
  config.enabledSources = parseEnabledSources(
25
38
  firstEnv(env, "CODEX_RULES_ENABLED_SOURCES", "PI_RULES_ENABLED_SOURCES"),
26
39
  disableBundledRules,
@@ -0,0 +1,17 @@
1
+ import type { PiRulesConfig } from "./rules/types.js";
2
+
3
+ export function withDynamicBudget(config: PiRulesConfig): PiRulesConfig {
4
+ return {
5
+ ...config,
6
+ maxRuleChars: Math.min(config.maxRuleChars, config.dynamicMaxRuleChars),
7
+ maxResultChars: Math.min(config.maxResultChars, config.dynamicMaxResultChars),
8
+ };
9
+ }
10
+
11
+ export function withPromptBudget(config: PiRulesConfig): PiRulesConfig {
12
+ return {
13
+ ...config,
14
+ maxRuleChars: Math.min(config.maxRuleChars, config.promptMaxRuleChars),
15
+ maxResultChars: Math.min(config.maxResultChars, config.promptMaxResultChars),
16
+ };
17
+ }
@@ -68,8 +68,11 @@ export function clearSessionState(cachePath: string): void {
68
68
 
69
69
  export function markSessionCompacted(cachePath: string): void {
70
70
  const state = readSessionState(cachePath);
71
+ // Compaction drops injected static rule bodies, so pre-compaction static
72
+ // dedup marks must not suppress the post-compact recovery directive.
73
+ // Dynamic dedup survives: those rules are recovered as read-directive paths.
71
74
  writeSessionState(cachePath, {
72
- staticDedup: state.staticDedup,
75
+ staticDedup: [],
73
76
  dynamicDedup: state.dynamicDedup,
74
77
  ...(state.dynamicTargetFingerprints === undefined
75
78
  ? {}
@@ -0,0 +1,39 @@
1
+ import { uniqueStrings } from "./path-utils.js";
2
+
3
+ const DIRECTIVE_HEADER = [
4
+ "## MANDATORY: POST-COMPACTION RULE RECOVERY",
5
+ "",
6
+ "Context compaction DROPPED the project rule files listed below from your context.",
7
+ "YOU MUST READ THE FOLLOWING RULES with your file-reading tool RIGHT NOW, BEFORE ANY OTHER ACTION. NO EXCUSES.",
8
+ "Do not plan, answer, edit, or run anything until EVERY file below has been read end to end:",
9
+ "",
10
+ ].join("\n");
11
+
12
+ const DIRECTIVE_FOOTER =
13
+ "\nOperating without these rules is a protocol violation. Reconstructing them from memory is NOT reading. READ THEM ALL. NO EXCUSES.";
14
+
15
+ export function buildPostCompactReadDirective(rulePaths: ReadonlyArray<string>, maxChars: number): string {
16
+ const paths = uniqueStrings([...rulePaths]);
17
+ if (paths.length === 0) {
18
+ return "";
19
+ }
20
+
21
+ const lines: string[] = [];
22
+ let usedChars = DIRECTIVE_HEADER.length + DIRECTIVE_FOOTER.length;
23
+ let omittedCount = 0;
24
+ for (const rulePath of paths) {
25
+ const line = `- ${rulePath}`;
26
+ if (lines.length > 0 && usedChars + line.length + 1 > maxChars) {
27
+ omittedCount += 1;
28
+ continue;
29
+ }
30
+ lines.push(line);
31
+ usedChars += line.length + 1;
32
+ }
33
+ if (omittedCount > 0) {
34
+ lines.push(
35
+ `- (+${omittedCount} more rule files omitted - rescan the project rule directories and read those too)`,
36
+ );
37
+ }
38
+ return `${DIRECTIVE_HEADER}${lines.join("\n")}${DIRECTIVE_FOOTER}`;
39
+ }
@@ -87,6 +87,22 @@ export const DEFAULT_POST_COMPACT_MAX_RULE_CHARS = 3500;
87
87
 
88
88
  export const DEFAULT_POST_COMPACT_MAX_RESULT_CHARS = 4000;
89
89
 
90
+ /**
91
+ * Per-rule / total caps for dynamic (PostToolUse) injection. Kept far below the
92
+ * static defaults so mid-session rule matches stay lightweight.
93
+ */
94
+ export const DEFAULT_DYNAMIC_MAX_RULE_CHARS = 4000;
95
+
96
+ export const DEFAULT_DYNAMIC_MAX_RESULT_CHARS = 10000;
97
+
98
+ /**
99
+ * Per-rule / total caps for UserPromptSubmit static injection. SessionStart
100
+ * keeps the full budget; prompt-time stragglers inject at a reduced size.
101
+ */
102
+ export const DEFAULT_PROMPT_MAX_RULE_CHARS = 6000;
103
+
104
+ export const DEFAULT_PROMPT_MAX_RESULT_CHARS = 16000;
105
+
90
106
  /**
91
107
  * Truncation marker template. `{path}` is replaced with the relative path.
92
108
  */
@@ -7,10 +7,14 @@ import {
7
7
  markStaticInjected as markStaticInjectedInState,
8
8
  } from "./cache.js";
9
9
  import {
10
+ DEFAULT_DYNAMIC_MAX_RESULT_CHARS,
11
+ DEFAULT_DYNAMIC_MAX_RULE_CHARS,
10
12
  DEFAULT_MAX_RESULT_CHARS,
11
13
  DEFAULT_MAX_RULE_CHARS,
12
14
  DEFAULT_POST_COMPACT_MAX_RESULT_CHARS,
13
15
  DEFAULT_POST_COMPACT_MAX_RULE_CHARS,
16
+ DEFAULT_PROMPT_MAX_RESULT_CHARS,
17
+ DEFAULT_PROMPT_MAX_RULE_CHARS,
14
18
  } from "./constants.js";
15
19
  import { loadDynamicCandidates } from "./engine-dynamic-loader.js";
16
20
  import { loadStaticCandidates } from "./engine-static-loader.js";
@@ -29,6 +33,10 @@ export function defaultConfig(): PiRulesConfig {
29
33
  maxResultChars: DEFAULT_MAX_RESULT_CHARS,
30
34
  postCompactMaxRuleChars: DEFAULT_POST_COMPACT_MAX_RULE_CHARS,
31
35
  postCompactMaxResultChars: DEFAULT_POST_COMPACT_MAX_RESULT_CHARS,
36
+ dynamicMaxRuleChars: DEFAULT_DYNAMIC_MAX_RULE_CHARS,
37
+ dynamicMaxResultChars: DEFAULT_DYNAMIC_MAX_RESULT_CHARS,
38
+ promptMaxRuleChars: DEFAULT_PROMPT_MAX_RULE_CHARS,
39
+ promptMaxResultChars: DEFAULT_PROMPT_MAX_RESULT_CHARS,
32
40
  enabledSources: "auto",
33
41
  };
34
42
  }
@@ -112,6 +112,10 @@ export interface PiRulesConfig {
112
112
  maxResultChars: number;
113
113
  postCompactMaxRuleChars: number;
114
114
  postCompactMaxResultChars: number;
115
+ dynamicMaxRuleChars: number;
116
+ dynamicMaxResultChars: number;
117
+ promptMaxRuleChars: number;
118
+ promptMaxResultChars: number;
115
119
  enabledSources: RuleSource[] | "auto";
116
120
  }
117
121
 
@@ -1,5 +1,13 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
1
4
  type RuntimeEnv = Readonly<Record<string, string | undefined>>;
2
5
 
6
+ interface OmoResolutionDeps {
7
+ readonly fileExists?: (path: string) => boolean;
8
+ readonly platform?: NodeJS.Platform;
9
+ }
10
+
3
11
  const SPARKSHELL_AWARENESS_MARKER = "## Sparkshell Runtime";
4
12
 
5
13
  export const SPARKSHELL_AWARENESS_DEDUP_KEY = "__omo_sparkshell_awareness__";
@@ -23,7 +31,38 @@ function isSparkShellAppServerConfigured(env: RuntimeEnv = process.env): boolean
23
31
  return codexSocketPath.length > 0 || omoSocketPath.length > 0;
24
32
  }
25
33
 
26
- export function getSparkShellRuntimeAwareness(env: RuntimeEnv = process.env): string {
34
+ export function resolveOmoInvocation(env: RuntimeEnv = process.env, deps: OmoResolutionDeps = {}): string | null {
35
+ const fileExists = deps.fileExists ?? existsSync;
36
+ const platform = deps.platform ?? process.platform;
37
+ const binNames = platform === "win32" ? ["omo.cmd", "omo.exe", "omo"] : ["omo"];
38
+ const pathDelimiter = platform === "win32" ? ";" : ":";
39
+ const pathEntries = (env["PATH"] ?? "").split(pathDelimiter).filter((entry) => entry.trim().length > 0);
40
+ for (const pathEntry of pathEntries) {
41
+ for (const binName of binNames) {
42
+ if (fileExists(join(pathEntry, binName))) return "omo";
43
+ }
44
+ }
45
+ for (const candidateDir of omoCandidateBinDirs(env)) {
46
+ for (const binName of binNames) {
47
+ const candidate = join(candidateDir, binName);
48
+ if (fileExists(candidate)) return candidate;
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+
54
+ function omoCandidateBinDirs(env: RuntimeEnv): readonly string[] {
55
+ const dirs: string[] = [];
56
+ const localBinDir = env["CODEX_LOCAL_BIN_DIR"]?.trim() ?? "";
57
+ if (localBinDir.length > 0) dirs.push(localBinDir);
58
+ const home = env["HOME"]?.trim() || env["USERPROFILE"]?.trim() || "";
59
+ const codexHome = env["CODEX_HOME"]?.trim() || (home.length > 0 ? join(home, ".codex") : "");
60
+ if (codexHome.length > 0) dirs.push(join(codexHome, "bin"));
61
+ if (home.length > 0) dirs.push(join(home, ".local", "bin"));
62
+ return dirs;
63
+ }
64
+
65
+ export function getSparkShellRuntimeAwareness(env: RuntimeEnv = process.env, deps: OmoResolutionDeps = {}): string {
27
66
  const override = env["OMO_SPARKSHELL_AWARENESS"] ?? env["LAZYCODEX_SPARKSHELL_AWARENESS"];
28
67
  if (isFalsy(override)) {
29
68
  return "";
@@ -32,13 +71,23 @@ export function getSparkShellRuntimeAwareness(env: RuntimeEnv = process.env): st
32
71
  return "";
33
72
  }
34
73
 
74
+ const resolved = resolveOmoInvocation(env, deps);
75
+ const invocation = resolved ?? (isTruthy(override) ? "omo" : null);
76
+ if (invocation === null) {
77
+ return "";
78
+ }
79
+ const command = /\s/.test(invocation) ? `"${invocation}"` : invocation;
80
+
35
81
  return [
36
82
  SPARKSHELL_AWARENESS_MARKER,
37
83
  "",
38
- "- Prefer `omo sparkshell <command>` for repo inspection, CLI smoke tests, git/history checks, and bounded verification before falling back to raw shell commands.",
39
- "- Use `omo sparkshell --shell '<command>'` only when shell metacharacters are required.",
40
- "- Use `omo sparkshell --tmux-pane <pane-id> --tail-lines 400` to inspect an existing tmux pane. Tail lines must stay between 100 and 1000.",
84
+ `- Prefer \`${command} sparkshell <command>\` for repo inspection, CLI smoke tests, git/history checks, and bounded verification before falling back to raw shell commands.`,
85
+ `- Use \`${command} sparkshell --shell '<command>'\` only when shell metacharacters are required.`,
86
+ `- Use \`${command} sparkshell --tmux-pane <pane-id> --tail-lines 400\` to inspect an existing tmux pane. Tail lines must stay between 100 and 1000.`,
41
87
  "- When no native sidecar or appserver is available, Sparkshell silently falls back to raw command execution. `OMO_SPARKSHELL_BIN` selects a native sidecar path.",
88
+ "- When `CODEX_THREAD_ID` identifies a Codex session, Sparkshell appends recent session context (first/latest user request + last 5 conversation messages) after the shell result so output consumers stay aligned with the session goals. `OMO_SPARKSHELL_SESSION_CONTEXT=0` disables it.",
89
+ `- Route potentially huge output (full log files, big diffs, \`cat\`/\`grep\` over large artifacts) through \`${command} sparkshell\` instead of reading it raw: oversized output is condensed to a budget while preserving error signatures, repeated patterns, session-goal-relevant lines, and head/tail. Tune with \`--budget <chars>\`; disable with \`OMO_SPARKSHELL_CONDENSE=0\`.`,
90
+ "- Oversized output is first summarized by the spark model (`codex exec`, default `gpt-5.3-codex-spark`) fed with the session context: the summary reproduces the output as-is (no masking) and ends with a `[sparkshell caption]` line describing what ran and which lines were omitted. `OMO_SPARKSHELL_SPARK=0` skips the model and uses deterministic condensation directly.",
42
91
  ].join("\n");
43
92
  }
44
93
 
@@ -1,12 +1,20 @@
1
+ import { existsSync } from "node:fs";
2
+
1
3
  import type { CodexRulesHookOptions } from "./codex-hook-options.js";
2
4
  import { configFromEnvironment } from "./config.js";
5
+ import { withPromptBudget } from "./event-budget.js";
3
6
  import { formatAdditionalContextOutput } from "./hook-output.js";
4
7
  import { completePostCompactRecovery, hydrateEngineState, persistEngineState } from "./persistent-cache.js";
5
8
  import { withPostCompactBudget } from "./post-compact-budget.js";
9
+ import { buildPostCompactReadDirective } from "./post-compact-directive.js";
10
+ import type { Engine } from "./rules/engine.js";
11
+ import { isNeverTruncatedRule } from "./rules/truncator.js";
12
+ import type { LoadedRule, PiRulesConfig } from "./rules/types.js";
6
13
  import { createRulesEngine } from "./rules-engine-factory.js";
7
14
  import { getSparkShellRuntimeAwareness, SPARKSHELL_AWARENESS_DEDUP_KEY } from "./sparkshell-awareness.js";
8
- import { filterRulesAlreadyInTranscript } from "./transcript-rule-filter.js";
15
+ import { filterRulesAlreadyInTranscript, filterRulesNotInTranscriptText } from "./transcript-rule-filter.js";
9
16
  import type { TranscriptSearchOptions } from "./transcript-search.js";
17
+ import { readTranscriptSearchText } from "./transcript-search.js";
10
18
 
11
19
  export function runStaticInjection(
12
20
  cwd: string,
@@ -26,10 +34,20 @@ export function runStaticInjection(
26
34
  return "";
27
35
  }
28
36
 
29
- const effectiveConfig =
30
- completedPostCompactChannel === undefined
31
- ? config
32
- : withPostCompactBudget(config, { model: model ?? "", transcriptPath });
37
+ if (completedPostCompactChannel !== undefined) {
38
+ return runPostCompactRecovery({
39
+ cwd,
40
+ transcriptPath,
41
+ eventName,
42
+ cachePath,
43
+ options,
44
+ channel: completedPostCompactChannel,
45
+ model: model ?? "",
46
+ config,
47
+ });
48
+ }
49
+
50
+ const effectiveConfig = eventName === "UserPromptSubmit" ? withPromptBudget(config) : config;
33
51
  const engine = createRulesEngine(options, effectiveConfig);
34
52
  hydrateEngineState(engine, cachePath);
35
53
  engine.state.cwd = cwd;
@@ -47,7 +65,7 @@ export function runStaticInjection(
47
65
  ? ""
48
66
  : getSparkShellRuntimeAwareness(options.env);
49
67
  if (rules.length === 0 && sparkshellAwareness.length === 0) {
50
- persistEngineState(engine, cachePath, completedPostCompactChannel);
68
+ persistEngineState(engine, cachePath);
51
69
  return "";
52
70
  }
53
71
 
@@ -58,10 +76,112 @@ export function runStaticInjection(
58
76
  if (sparkshellAwareness.length > 0) {
59
77
  engine.state.staticDedup.add(SPARKSHELL_AWARENESS_DEDUP_KEY);
60
78
  }
61
- persistEngineState(engine, cachePath, completedPostCompactChannel);
79
+ persistEngineState(engine, cachePath);
62
80
  return formatAdditionalContextOutput(eventName, combineStaticContext(block, sparkshellAwareness));
63
81
  }
64
82
 
83
+ interface PostCompactRecoveryInput {
84
+ cwd: string;
85
+ transcriptPath: string | null;
86
+ eventName: "SessionStart" | "UserPromptSubmit";
87
+ cachePath: string;
88
+ options: CodexRulesHookOptions;
89
+ channel: "static";
90
+ model: string;
91
+ config: PiRulesConfig;
92
+ }
93
+
94
+ function runPostCompactRecovery(input: PostCompactRecoveryInput): string {
95
+ const effectiveConfig = withPostCompactBudget(input.config, {
96
+ model: input.model,
97
+ transcriptPath: input.transcriptPath,
98
+ });
99
+ const engine = createRulesEngine(input.options, effectiveConfig);
100
+ hydrateEngineState(engine, input.cachePath);
101
+ engine.state.cwd = input.cwd;
102
+
103
+ const loaded = engine.loadStaticRules(input.cwd);
104
+ const transcriptText = readRecoveryTranscriptText(input.transcriptPath);
105
+ const missingRules = filterRulesNotInTranscriptText(
106
+ loaded.rules.filter((rule) => !engine.isStaticInjected(rule)),
107
+ transcriptText,
108
+ (rule) => {
109
+ engine.markStaticInjected(rule);
110
+ },
111
+ );
112
+ const dynamicRulePaths = recoverDynamicRulePaths(engine, transcriptText, loaded.rules);
113
+ const sparkshellAwareness = engine.state.staticDedup.has(SPARKSHELL_AWARENESS_DEDUP_KEY)
114
+ ? ""
115
+ : getSparkShellRuntimeAwareness(input.options.env);
116
+
117
+ if (missingRules.length === 0 && dynamicRulePaths.length === 0 && sparkshellAwareness.length === 0) {
118
+ persistEngineState(engine, input.cachePath, input.channel);
119
+ return "";
120
+ }
121
+
122
+ const fullBodyRules = missingRules.filter((rule) => isNeverTruncatedRule(ruleDisplayPath(rule)));
123
+ const listedRules = missingRules.filter((rule) => !isNeverTruncatedRule(ruleDisplayPath(rule)));
124
+ const bodyBlock = fullBodyRules.length === 0 ? "" : engine.formatStatic(fullBodyRules);
125
+ const directive = buildPostCompactReadDirective(
126
+ [...listedRules.map((rule) => rule.path), ...dynamicRulePaths],
127
+ effectiveConfig.maxResultChars,
128
+ );
129
+ for (const rule of missingRules) {
130
+ engine.markStaticInjected(rule);
131
+ }
132
+ if (sparkshellAwareness.length > 0) {
133
+ engine.state.staticDedup.add(SPARKSHELL_AWARENESS_DEDUP_KEY);
134
+ }
135
+ persistEngineState(engine, input.cachePath, input.channel);
136
+ return formatAdditionalContextOutput(
137
+ input.eventName,
138
+ combineStaticContext(bodyBlock, directive, sparkshellAwareness),
139
+ );
140
+ }
141
+
142
+ function readRecoveryTranscriptText(transcriptPath: string | null): string | null {
143
+ if (transcriptPath === null) {
144
+ return null;
145
+ }
146
+ return (
147
+ readTranscriptSearchText(transcriptPath, { latestCompactedReplacementOnly: true }) ??
148
+ readTranscriptSearchText(transcriptPath)
149
+ );
150
+ }
151
+
152
+ function recoverDynamicRulePaths(
153
+ engine: Engine,
154
+ transcriptText: string | null,
155
+ staticRules: ReadonlyArray<LoadedRule>,
156
+ ): string[] {
157
+ const staticRulePaths = new Set(staticRules.map((rule) => rule.realPath));
158
+ const recoveredPaths = new Set<string>();
159
+ for (const dedupKeys of engine.state.dynamicDedup.values()) {
160
+ for (const dedupKey of dedupKeys) {
161
+ const separatorIndex = dedupKey.lastIndexOf("::");
162
+ if (separatorIndex <= 0) {
163
+ continue;
164
+ }
165
+ const rulePath = dedupKey.slice(0, separatorIndex);
166
+ if (staticRulePaths.has(rulePath)) {
167
+ continue;
168
+ }
169
+ if (transcriptText !== null && transcriptText.includes(rulePath)) {
170
+ continue;
171
+ }
172
+ if (!existsSync(rulePath)) {
173
+ continue;
174
+ }
175
+ recoveredPaths.add(rulePath);
176
+ }
177
+ }
178
+ return [...recoveredPaths].sort();
179
+ }
180
+
181
+ function ruleDisplayPath(rule: LoadedRule): string {
182
+ return rule.relativePath.length > 0 ? rule.relativePath : rule.path;
183
+ }
184
+
65
185
  function combineStaticContext(...blocks: readonly string[]): string {
66
186
  return blocks.filter((block) => block.trim().length > 0).join("\n\n");
67
187
  }
@@ -13,7 +13,15 @@ export function filterRulesAlreadyInTranscript(
13
13
  }
14
14
 
15
15
  const transcriptText = readTranscriptSearchText(transcriptPath, options);
16
- if (transcriptText === null) {
16
+ return filterRulesNotInTranscriptText(rules, transcriptText, markInjected);
17
+ }
18
+
19
+ export function filterRulesNotInTranscriptText(
20
+ rules: ReadonlyArray<LoadedRule>,
21
+ transcriptText: string | null,
22
+ markInjected: (rule: LoadedRule) => void,
23
+ ): LoadedRule[] {
24
+ if (rules.length === 0 || transcriptText === null) {
17
25
  return [...rules];
18
26
  }
19
27
 
@@ -200,7 +200,7 @@ describe("plugin bundled rules", () => {
200
200
  expect(output).toBe("");
201
201
  });
202
202
 
203
- it("#given bundled static context already injected #when UserPromptSubmit runs after PostCompact #then it emits no duplicate bundled context", async () => {
203
+ it("#given bundled static context dropped by compaction #when UserPromptSubmit runs after PostCompact #then it re-injects the bundled persona body in full", async () => {
204
204
  // given
205
205
  const { root, pluginData, bundledRulePath } = makeFixture();
206
206
  const firstOutput = await runSessionStartHook(sessionStartInput(root), {
@@ -219,7 +219,9 @@ describe("plugin bundled rules", () => {
219
219
 
220
220
  // then
221
221
  expect(compactOutput).toBe("");
222
- expect(output).toBe("");
222
+ expect(output).toContain(`Instructions from: ${bundledRulePath}`);
223
+ expect(output).toContain(BUNDLED_BODY);
224
+ expect(output).not.toContain("[Truncated. Full:");
223
225
  });
224
226
 
225
227
  it("#given bundled Hephaestus rule body exceeds per-rule cap #when SessionStart runs #then static context expands the body within result budget", async () => {