lazycodex-ai 4.18.2 → 4.19.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 (225) hide show
  1. package/README.ja.md +6 -6
  2. package/README.ko.md +6 -6
  3. package/README.md +8 -8
  4. package/README.ru.md +6 -6
  5. package/README.zh-cn.md +6 -6
  6. package/dist/cli/index.js +781 -215
  7. package/dist/cli-node/index.js +781 -215
  8. package/package.json +1 -1
  9. package/packages/git-bash-mcp/dist/cli.js +54 -8
  10. package/packages/lsp-daemon/dist/cli.js +319 -51
  11. package/packages/lsp-daemon/dist/client.js +136 -48
  12. package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -10
  13. package/packages/lsp-daemon/dist/daemon-client.js +4 -34
  14. package/packages/lsp-daemon/dist/daemon-failure-result.d.ts +3 -0
  15. package/packages/lsp-daemon/dist/daemon-failure-result.js +38 -0
  16. package/packages/lsp-daemon/dist/daemon-request-error.d.ts +14 -0
  17. package/packages/lsp-daemon/dist/daemon-request-error.js +26 -0
  18. package/packages/lsp-daemon/dist/daemon-server.js +5 -1
  19. package/packages/lsp-daemon/dist/index.js +137 -48
  20. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  21. package/packages/lsp-daemon/dist/proxy.js +1 -0
  22. package/packages/lsp-daemon/dist/version-reap.d.ts +26 -0
  23. package/packages/lsp-daemon/dist/version-reap.js +182 -0
  24. package/packages/lsp-tools-mcp/dist/cli.js +61 -10
  25. package/packages/lsp-tools-mcp/dist/lsp/manager.js +6 -1
  26. package/packages/lsp-tools-mcp/dist/mcp.js +61 -10
  27. package/packages/lsp-tools-mcp/dist/tools.js +6 -1
  28. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  29. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +416 -25
  30. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  31. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  32. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +22 -2
  33. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  34. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +638 -267
  35. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +178 -89
  36. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  37. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  38. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +3 -1
  39. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +98 -32
  40. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +5 -0
  41. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +15 -6
  42. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -2
  43. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +1 -0
  44. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  45. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +148 -0
  46. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +31 -2
  47. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +1 -1
  48. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +65 -1
  49. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -7
  50. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -1
  51. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +57 -3
  52. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +41 -0
  53. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +109 -8
  54. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +2 -2
  55. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +43 -0
  56. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  57. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  58. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  59. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  60. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  61. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  62. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  63. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  64. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +80 -40
  65. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  66. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  67. package/packages/omo-codex/plugin/components/rules/dist/cli.js +11 -0
  68. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  69. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  70. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +11 -0
  71. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +60 -0
  72. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  73. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
  74. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  75. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  76. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
  77. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  78. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
  79. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  80. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
  81. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  82. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  83. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  84. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  85. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  87. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +2 -2
  88. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
  89. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  90. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  91. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +2 -2
  92. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  93. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  94. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  95. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  96. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  97. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +31 -8
  98. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  99. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  100. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  101. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +42 -0
  102. package/packages/omo-codex/plugin/components/ulw-loop/README.md +6 -4
  103. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.d.ts +21 -0
  104. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +64 -0
  105. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +15 -2
  106. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +1 -1
  107. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  108. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  109. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +3 -3
  110. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +3 -0
  111. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +85 -0
  112. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +0 -1
  113. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -33
  114. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +998 -593
  115. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +1 -0
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -1
  117. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +2 -0
  118. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +6 -0
  119. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +1 -0
  120. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +3 -0
  121. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +1 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +4 -0
  123. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  124. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +10 -2
  125. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +1 -1
  126. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.d.ts +15 -0
  127. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +84 -0
  128. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +5 -0
  129. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +81 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +7 -59
  131. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +12 -4
  132. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.d.ts +9 -0
  133. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.js +122 -0
  134. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  135. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  136. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -6
  137. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +84 -0
  138. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +13 -2
  139. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +1 -1
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +1 -1
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +3 -3
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +49 -0
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +13 -45
  144. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -0
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +2 -0
  146. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +7 -0
  147. package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +4 -0
  148. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +4 -1
  149. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +20 -2
  150. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +1 -1
  151. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +125 -0
  152. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +59 -0
  153. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +6 -58
  154. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +12 -4
  155. package/packages/omo-codex/plugin/components/ulw-loop/src/validation-batch.ts +122 -0
  156. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +76 -0
  157. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +111 -0
  158. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +67 -0
  159. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +57 -0
  160. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +1 -0
  161. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +152 -0
  162. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +29 -0
  163. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch-checkpoint.test.ts +147 -0
  164. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch.test.ts +73 -0
  165. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  170. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  171. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  172. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  173. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  174. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  175. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  176. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -2
  177. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  178. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -2
  179. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  180. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -2
  181. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  182. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  183. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  184. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  185. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  186. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  187. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  188. package/packages/omo-codex/plugin/package-lock.json +41 -41
  189. package/packages/omo-codex/plugin/package.json +1 -1
  190. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  191. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  192. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  193. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
  194. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +43 -0
  195. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  196. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
  197. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +31 -8
  198. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  199. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  200. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +11 -11
  201. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +26 -0
  202. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +41 -0
  203. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  204. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  205. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  206. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  207. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  208. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
  209. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  210. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  211. package/packages/omo-codex/scripts/install-dist/install-local.mjs +401 -22
  212. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  213. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  214. package/packages/shared-skills/skills/ulw-plan/SKILL.md +31 -8
  215. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  216. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  217. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  218. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  219. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  220. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  221. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  222. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  223. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  224. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  225. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -5903,7 +5903,7 @@ var package_default;
5903
5903
  var init_package = __esm(() => {
5904
5904
  package_default = {
5905
5905
  name: "@oh-my-opencode/omo-codex",
5906
- version: "4.18.2",
5906
+ version: "4.19.1",
5907
5907
  type: "module",
5908
5908
  private: true,
5909
5909
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -6429,7 +6429,7 @@ function whereCommand(command) {
6429
6429
  }
6430
6430
  }
6431
6431
  // packages/omo-codex/src/install/codex-process.ts
6432
- var WINDOWS_CMD_SHIM_COMMANDS = new Set(["npm", "npx"]);
6432
+ var WINDOWS_CMD_SHIM_COMMANDS = new Set(["codex", "npm", "npx"]);
6433
6433
  function resolveRunCommandInvocation(command, args, platform = process.platform) {
6434
6434
  if (platform !== "win32" || !WINDOWS_CMD_SHIM_COMMANDS.has(command.toLowerCase())) {
6435
6435
  return { command, args: [...args] };
@@ -7068,6 +7068,7 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
7068
7068
  const packageJsonPaths = [];
7069
7069
  await collectPackageJsonPaths(pluginRoot, pluginRoot, packageJsonPaths);
7070
7070
  const packageLock = await readPackageLock(pluginRoot);
7071
+ let rewroteAnyPackageJson = false;
7071
7072
  for (const packageJsonPath of packageJsonPaths) {
7072
7073
  const raw = await readFile5(packageJsonPath, "utf8");
7073
7074
  const parsed = JSON.parse(raw);
@@ -7103,13 +7104,16 @@ async function rewriteCachedPackageLocalFileDependencies(pluginRoot, sourceRoot)
7103
7104
  changed = true;
7104
7105
  }
7105
7106
  }
7106
- if (changed)
7107
+ if (changed) {
7107
7108
  await writeFile2(packageJsonPath, `${JSON.stringify(parsed, null, "\t")}
7108
7109
  `);
7110
+ rewroteAnyPackageJson = true;
7111
+ }
7109
7112
  }
7110
7113
  if (packageLock.changed)
7111
7114
  await writeFile2(packageLock.path, `${JSON.stringify(packageLock.value, null, "\t")}
7112
7115
  `);
7116
+ return rewroteAnyPackageJson;
7113
7117
  }
7114
7118
  async function readPackageLock(pluginRoot) {
7115
7119
  const path = join8(pluginRoot, "package-lock.json");
@@ -7530,10 +7534,11 @@ async function installCachedPlugin(input) {
7530
7534
  await rm4(tempPath, { recursive: true, force: true });
7531
7535
  try {
7532
7536
  await copyDirectory(input.sourcePath, tempPath);
7533
- await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
7537
+ const rewroteLocalFileDependencies = await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
7534
7538
  await copyBundledMcpRuntimeDists({ pluginRoot: tempPath, sourceRoot: input.sourcePath });
7535
7539
  await copyRootRuntimeDists({ pluginRoot: tempPath, sourcePath: input.sourcePath });
7536
- await maybeRunNpmInstall(tempPath, input.runCommand, npmInstallEnv, ["ci", "--omit=dev"]);
7540
+ const installArgs = rewroteLocalFileDependencies ? ["install", "--omit=dev", "--no-audit", "--no-fund"] : ["ci", "--omit=dev"];
7541
+ await maybeRunNpmInstall(tempPath, input.runCommand, npmInstallEnv, installArgs);
7537
7542
  await removeCachedManagedNpmBinShims(tempPath);
7538
7543
  if (input.buildSource === false)
7539
7544
  await maybeRunNpmSyncSkills(tempPath, input.runCommand, env);
@@ -7837,9 +7842,16 @@ function findTomlSection(config, header) {
7837
7842
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
7838
7843
  let offset = 0;
7839
7844
  let start = -1;
7845
+ let multilineQuote = null;
7840
7846
  for (const line of lines) {
7841
7847
  if (line.length === 0)
7842
7848
  break;
7849
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7850
+ multilineQuote = multilineScan.nextQuote;
7851
+ if (multilineScan.wasInside) {
7852
+ offset += line.length;
7853
+ continue;
7854
+ }
7843
7855
  const trimmed = line.trim();
7844
7856
  if (start === -1) {
7845
7857
  if (tomlTableHeaderMatches(trimmed, headerLine, targetHeaderPath))
@@ -7854,8 +7866,37 @@ function findTomlSection(config, header) {
7854
7866
  return { start, end: config.length, text: config.slice(start) };
7855
7867
  }
7856
7868
  function replaceOrInsertSetting(config, section, key, value) {
7857
- const linePattern = new RegExp(`^[ \\t]*${escapeRegExp(key)}[ \\t]*=.*$`, "m");
7858
- const replacement = linePattern.test(section.text) ? section.text.replace(linePattern, `${key} = ${value}`) : insertSetting(section.text, key, value);
7869
+ const targetPath = parseTomlDottedKey(key);
7870
+ if (!targetPath)
7871
+ return config;
7872
+ const lines = section.text.match(/[^\n]*\n?|$/g) ?? [];
7873
+ let offset = 0;
7874
+ let multilineQuote = null;
7875
+ for (const line of lines) {
7876
+ if (line.length === 0)
7877
+ break;
7878
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7879
+ multilineQuote = multilineScan.nextQuote;
7880
+ if (multilineScan.wasInside) {
7881
+ offset += line.length;
7882
+ continue;
7883
+ }
7884
+ const assignmentIndex = findUnquotedAssignment(line);
7885
+ if (assignmentIndex < 0) {
7886
+ offset += line.length;
7887
+ continue;
7888
+ }
7889
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
7890
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
7891
+ offset += line.length;
7892
+ continue;
7893
+ }
7894
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
7895
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(section.text, offset + line.length, multilineScan.nextQuote) : offset + line.length;
7896
+ const sectionReplacement = section.text.slice(0, offset) + replacement2 + section.text.slice(assignmentEnd);
7897
+ return config.slice(0, section.start) + sectionReplacement + config.slice(section.end);
7898
+ }
7899
+ const replacement = insertSetting(section.text, key, value);
7859
7900
  return config.slice(0, section.start) + replacement + config.slice(section.end);
7860
7901
  }
7861
7902
  function removeSetting(config, section, key) {
@@ -7875,6 +7916,50 @@ function replaceOrInsertRootSetting(config, key, value) {
7875
7916
  return replacement;
7876
7917
  return `${replacement.trimEnd()}
7877
7918
 
7919
+ ${suffix.trimStart()}`;
7920
+ }
7921
+ function replaceOrInsertRootDottedSetting(config, keyPath, value) {
7922
+ const targetPath = parseTomlDottedKey(keyPath);
7923
+ if (!targetPath)
7924
+ return config;
7925
+ const lines = config.match(/[^\n]*\n?|$/g) ?? [];
7926
+ let offset = 0;
7927
+ let multilineQuote = null;
7928
+ for (const line of lines) {
7929
+ if (line.length === 0)
7930
+ break;
7931
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7932
+ multilineQuote = multilineScan.nextQuote;
7933
+ if (multilineScan.wasInside) {
7934
+ offset += line.length;
7935
+ continue;
7936
+ }
7937
+ if (isTomlTableHeaderLine(line))
7938
+ break;
7939
+ const assignmentIndex = findUnquotedAssignment(line);
7940
+ if (assignmentIndex < 0) {
7941
+ offset += line.length;
7942
+ continue;
7943
+ }
7944
+ const settingPath = parseTomlDottedKey(line.slice(0, assignmentIndex).trim());
7945
+ if (!settingPath || !tomlPathMatches(settingPath, targetPath)) {
7946
+ offset += line.length;
7947
+ continue;
7948
+ }
7949
+ const replacement2 = replaceTomlAssignmentValue(line, assignmentIndex, value);
7950
+ const assignmentEnd = multilineScan.nextQuote ? findTomlMultilineValueEnd(config, offset + line.length, multilineScan.nextQuote) : offset + line.length;
7951
+ return config.slice(0, offset) + replacement2 + config.slice(assignmentEnd);
7952
+ }
7953
+ const sectionStart = findFirstTableStart(config);
7954
+ const root = config.slice(0, sectionStart).trimEnd();
7955
+ const suffix = config.slice(sectionStart);
7956
+ const replacement = `${root}${root.length > 0 ? `
7957
+ ` : ""}${keyPath} = ${value}
7958
+ `;
7959
+ if (suffix.length === 0)
7960
+ return replacement;
7961
+ return `${replacement.trimEnd()}
7962
+
7878
7963
  ${suffix.trimStart()}`;
7879
7964
  }
7880
7965
  function appendBlock(config, block) {
@@ -7887,9 +7972,16 @@ function appendBlock(config, block) {
7887
7972
  function findFirstTableStart(config) {
7888
7973
  const lines = config.match(/[^\n]*\n?|$/g) ?? [];
7889
7974
  let offset = 0;
7975
+ let multilineQuote = null;
7890
7976
  for (const line of lines) {
7891
7977
  if (line.length === 0)
7892
7978
  break;
7979
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
7980
+ multilineQuote = multilineScan.nextQuote;
7981
+ if (multilineScan.wasInside) {
7982
+ offset += line.length;
7983
+ continue;
7984
+ }
7893
7985
  if (isTomlTableHeaderLine(line))
7894
7986
  return offset;
7895
7987
  offset += line.length;
@@ -7927,6 +8019,131 @@ function isTomlTableHeaderLine(line) {
7927
8019
  const normalizedLine = stripUnquotedInlineComment(line).trim();
7928
8020
  return normalizedLine.startsWith("[") && normalizedLine.endsWith("]");
7929
8021
  }
8022
+ function scanTomlMultilineLine(line, currentQuote) {
8023
+ if (currentQuote) {
8024
+ return {
8025
+ wasInside: true,
8026
+ nextQuote: findTomlMultilineDelimiter(line, currentQuote, 0) === -1 ? currentQuote : null
8027
+ };
8028
+ }
8029
+ let quote = null;
8030
+ let index = 0;
8031
+ while (index < line.length) {
8032
+ const char = line[index];
8033
+ if (quote === '"') {
8034
+ if (char === "\\") {
8035
+ index += 2;
8036
+ continue;
8037
+ }
8038
+ if (char === '"')
8039
+ quote = null;
8040
+ index += 1;
8041
+ continue;
8042
+ }
8043
+ if (quote === "'") {
8044
+ if (char === "'")
8045
+ quote = null;
8046
+ index += 1;
8047
+ continue;
8048
+ }
8049
+ if (char === "#")
8050
+ break;
8051
+ const delimiter2 = line.startsWith('"""', index) ? '"""' : line.startsWith("'''", index) ? "'''" : null;
8052
+ if (delimiter2) {
8053
+ const closingIndex = findTomlMultilineDelimiter(line, delimiter2, index + delimiter2.length);
8054
+ return { wasInside: false, nextQuote: closingIndex === -1 ? delimiter2 : null };
8055
+ }
8056
+ if (char === '"' || char === "'")
8057
+ quote = char;
8058
+ index += 1;
8059
+ }
8060
+ return { wasInside: false, nextQuote: null };
8061
+ }
8062
+ function findTomlMultilineDelimiter(line, delimiter2, startIndex) {
8063
+ let index = line.indexOf(delimiter2, startIndex);
8064
+ while (index !== -1) {
8065
+ if (delimiter2 === "'''" || countPrecedingBackslashes(line, index) % 2 === 0)
8066
+ return index;
8067
+ index = line.indexOf(delimiter2, index + 1);
8068
+ }
8069
+ return -1;
8070
+ }
8071
+ function countPrecedingBackslashes(line, index) {
8072
+ let count = 0;
8073
+ let cursor = index - 1;
8074
+ while (cursor >= 0 && line[cursor] === "\\") {
8075
+ count += 1;
8076
+ cursor -= 1;
8077
+ }
8078
+ return count;
8079
+ }
8080
+ function findUnquotedAssignment(line) {
8081
+ return findUnquotedCharacter(line, "=", 0);
8082
+ }
8083
+ function findUnquotedComment(line, startIndex) {
8084
+ return findUnquotedCharacter(line, "#", startIndex);
8085
+ }
8086
+ function findUnquotedCharacter(line, target, startIndex) {
8087
+ let quote = null;
8088
+ let index = startIndex;
8089
+ while (index < line.length) {
8090
+ const char = line[index];
8091
+ if (quote === '"') {
8092
+ if (char === "\\") {
8093
+ index += 2;
8094
+ continue;
8095
+ }
8096
+ if (char === '"')
8097
+ quote = null;
8098
+ index += 1;
8099
+ continue;
8100
+ }
8101
+ if (quote === "'") {
8102
+ if (char === "'")
8103
+ quote = null;
8104
+ index += 1;
8105
+ continue;
8106
+ }
8107
+ if (char === '"' || char === "'") {
8108
+ quote = char;
8109
+ index += 1;
8110
+ continue;
8111
+ }
8112
+ if (char === target)
8113
+ return index;
8114
+ if (char === "#")
8115
+ return -1;
8116
+ index += 1;
8117
+ }
8118
+ return -1;
8119
+ }
8120
+ function tomlPathMatches(candidate, target) {
8121
+ return candidate.length === target.length && candidate.every((part, index) => part === target[index]);
8122
+ }
8123
+ function replaceTomlAssignmentValue(line, assignmentIndex, value) {
8124
+ const newline = line.endsWith(`
8125
+ `) ? `
8126
+ ` : "";
8127
+ const lineBody = newline ? line.slice(0, -1) : line;
8128
+ const commentIndex = findUnquotedComment(lineBody, assignmentIndex + 1);
8129
+ const comment = commentIndex === -1 ? "" : ` ${lineBody.slice(commentIndex).trimStart()}`;
8130
+ return `${lineBody.slice(0, assignmentIndex + 1)} ${value}${comment}${newline}`;
8131
+ }
8132
+ function findTomlMultilineValueEnd(text, startOffset, quote) {
8133
+ const lines = text.slice(startOffset).match(/[^\n]*\n?|$/g) ?? [];
8134
+ let offset = startOffset;
8135
+ let currentQuote = quote;
8136
+ for (const line of lines) {
8137
+ if (line.length === 0)
8138
+ break;
8139
+ const scan = scanTomlMultilineLine(line, currentQuote);
8140
+ currentQuote = scan.nextQuote;
8141
+ offset += line.length;
8142
+ if (currentQuote === null)
8143
+ return offset;
8144
+ }
8145
+ return text.length;
8146
+ }
7930
8147
  function stripUnquotedInlineComment(line) {
7931
8148
  let quote = null;
7932
8149
  let index = 0;
@@ -8257,13 +8474,137 @@ function delay(milliseconds) {
8257
8474
  return new Promise((resolveDelay) => setTimeout(resolveDelay, milliseconds));
8258
8475
  }
8259
8476
 
8477
+ // packages/omo-codex/src/install/toml-setting-reader.ts
8478
+ function hasTomlSetting(config, keyPath) {
8479
+ const targetPath = parseTomlDottedKey(keyPath);
8480
+ if (!targetPath)
8481
+ return false;
8482
+ return hasTomlAssignment(config, (tablePath, settingPath) => {
8483
+ const fullPath = [...tablePath, ...settingPath];
8484
+ return fullPath.length === targetPath.length && fullPath.every((part, index) => part === targetPath[index]);
8485
+ });
8486
+ }
8487
+ function hasTomlRootDottedKeyPrefix(config, rootKey) {
8488
+ return hasTomlAssignment(config, (tablePath, settingPath) => tablePath.length === 0 && settingPath.length > 1 && settingPath[0] === rootKey);
8489
+ }
8490
+ function hasTomlAssignment(config, predicate) {
8491
+ let tablePath = [];
8492
+ let multilineQuote = null;
8493
+ for (const line of config.split(`
8494
+ `)) {
8495
+ const multilineScan = scanTomlMultilineLine(line, multilineQuote);
8496
+ multilineQuote = multilineScan.nextQuote;
8497
+ if (multilineScan.wasInside)
8498
+ continue;
8499
+ const normalizedLine = stripUnquotedInlineComment2(line).trim();
8500
+ if (normalizedLine.length === 0)
8501
+ continue;
8502
+ const headerPath = parseTomlTableHeader2(normalizedLine);
8503
+ if (headerPath) {
8504
+ tablePath = headerPath;
8505
+ continue;
8506
+ }
8507
+ if (isTomlTableHeaderLine2(normalizedLine)) {
8508
+ tablePath = null;
8509
+ continue;
8510
+ }
8511
+ if (!tablePath)
8512
+ continue;
8513
+ const assignmentIndex = findUnquotedAssignment2(normalizedLine);
8514
+ if (assignmentIndex < 0)
8515
+ continue;
8516
+ const settingPath = parseTomlDottedKey(normalizedLine.slice(0, assignmentIndex).trim());
8517
+ if (!settingPath)
8518
+ continue;
8519
+ if (predicate(tablePath, settingPath))
8520
+ return true;
8521
+ }
8522
+ return false;
8523
+ }
8524
+ function parseTomlTableHeader2(line) {
8525
+ if (!line.startsWith("[") || !line.endsWith("]") || line.startsWith("[["))
8526
+ return null;
8527
+ return parseTomlDottedKey(line.slice(1, -1).trim());
8528
+ }
8529
+ function isTomlTableHeaderLine2(line) {
8530
+ return line.startsWith("[") && line.endsWith("]");
8531
+ }
8532
+ function stripUnquotedInlineComment2(line) {
8533
+ let quote = null;
8534
+ let index = 0;
8535
+ while (index < line.length) {
8536
+ const char = line[index];
8537
+ if (quote === '"') {
8538
+ if (char === "\\") {
8539
+ index += 2;
8540
+ continue;
8541
+ }
8542
+ if (char === '"')
8543
+ quote = null;
8544
+ index += 1;
8545
+ continue;
8546
+ }
8547
+ if (quote === "'") {
8548
+ if (char === "'")
8549
+ quote = null;
8550
+ index += 1;
8551
+ continue;
8552
+ }
8553
+ if (char === '"' || char === "'") {
8554
+ quote = char;
8555
+ index += 1;
8556
+ continue;
8557
+ }
8558
+ if (char === "#")
8559
+ return line.slice(0, index);
8560
+ index += 1;
8561
+ }
8562
+ return line;
8563
+ }
8564
+ function findUnquotedAssignment2(line) {
8565
+ let quote = null;
8566
+ let index = 0;
8567
+ while (index < line.length) {
8568
+ const char = line[index];
8569
+ if (quote === '"') {
8570
+ if (char === "\\") {
8571
+ index += 2;
8572
+ continue;
8573
+ }
8574
+ if (char === '"')
8575
+ quote = null;
8576
+ index += 1;
8577
+ continue;
8578
+ }
8579
+ if (quote === "'") {
8580
+ if (char === "'")
8581
+ quote = null;
8582
+ index += 1;
8583
+ continue;
8584
+ }
8585
+ if (char === '"' || char === "'") {
8586
+ quote = char;
8587
+ index += 1;
8588
+ continue;
8589
+ }
8590
+ if (char === "=")
8591
+ return index;
8592
+ index += 1;
8593
+ }
8594
+ return -1;
8595
+ }
8596
+
8260
8597
  // packages/omo-codex/src/install/codex-config-features.ts
8261
8598
  function ensureFeatureEnabled(config, featureName) {
8262
8599
  const section = findTomlSection(config, "features");
8263
- if (!section)
8600
+ if (!section) {
8601
+ if (hasTomlRootDottedKeyPrefix(config, "features")) {
8602
+ return replaceOrInsertRootDottedSetting(config, `features.${featureName}`, "true");
8603
+ }
8264
8604
  return appendBlock(config, `[features]
8265
8605
  ${featureName} = true
8266
8606
  `);
8607
+ }
8267
8608
  return replaceOrInsertSetting(config, section, featureName, "true");
8268
8609
  }
8269
8610
 
@@ -8331,7 +8672,7 @@ function ensureAutonomousPermissions(config) {
8331
8672
  next = replaceOrInsertRootSetting(next, "sandbox_mode", JSON.stringify("danger-full-access"));
8332
8673
  next = replaceOrInsertRootSetting(next, "network_access", JSON.stringify("enabled"));
8333
8674
  for (const featureName of AUTONOMOUS_FEATURES) {
8334
- next = ensureFeatureEnabled2(next, featureName);
8675
+ next = ensureFeatureEnabled(next, featureName);
8335
8676
  }
8336
8677
  next = removeWindowsSandboxSetting(next);
8337
8678
  next = ensureNoticeEnabled(next, "hide_full_access_warning");
@@ -8349,14 +8690,6 @@ function ensureNoticeEnabled(config, key) {
8349
8690
  return appendNoticeBlock(config, key);
8350
8691
  return replaceOrInsertSetting(config, section, key, "true");
8351
8692
  }
8352
- function ensureFeatureEnabled2(config, key) {
8353
- const section = findTomlSection(config, "features");
8354
- if (section === null)
8355
- return appendBlock(config, `[features]
8356
- ${key} = true
8357
- `);
8358
- return replaceOrInsertSetting(config, section, key, "true");
8359
- }
8360
8693
  function appendNoticeBlock(config, key) {
8361
8694
  return appendBlock(config, `[notice]
8362
8695
  ${key} = true
@@ -8428,7 +8761,7 @@ function readStringArraySetting(sectionText, key) {
8428
8761
  const assignmentIndex = line.indexOf("=");
8429
8762
  if (assignmentIndex === -1)
8430
8763
  return null;
8431
- return parseTomlStringArray(stripUnquotedInlineComment2(line.slice(assignmentIndex + 1)).trim());
8764
+ return parseTomlStringArray(stripUnquotedInlineComment3(line.slice(assignmentIndex + 1)).trim());
8432
8765
  }
8433
8766
  return null;
8434
8767
  }
@@ -8472,7 +8805,7 @@ function parseTomlString(input, startIndex) {
8472
8805
  }
8473
8806
  return null;
8474
8807
  }
8475
- function stripUnquotedInlineComment2(line) {
8808
+ function stripUnquotedInlineComment3(line) {
8476
8809
  let quote = null;
8477
8810
  let index = 0;
8478
8811
  while (index < line.length) {
@@ -8686,24 +9019,27 @@ import { readFileSync } from "node:fs";
8686
9019
  import { dirname as dirname7, isAbsolute as isAbsolute6, join as join18 } from "node:path";
8687
9020
  var CODEX_AGENTS_HEADER = "agents";
8688
9021
  var CODEX_MULTI_AGENT_V2_HEADER = "features.multi_agent_v2";
9022
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY = `${CODEX_MULTI_AGENT_V2_HEADER}.max_concurrent_threads_per_session`;
8689
9023
  var CODEX_SUBAGENT_THREAD_LIMIT = 1000;
9024
+ var CODEX_MULTI_AGENT_V2_THREAD_LIMIT = 16;
8690
9025
  function ensureCodexMultiAgentV2Config(config, options = {}) {
8691
9026
  const featureFlag = removeFeatureFlagSetting(config, "multi_agent_v2");
8692
9027
  const v2Preferred = options.multiAgentVersion === "v2";
8693
9028
  const modelKnown = options.multiAgentVersion != null || readRootModel(featureFlag.config) !== null;
8694
9029
  const agentsConfig = v2Preferred ? removeAgentsMaxThreads(featureFlag.config) : modelKnown ? ensureAgentsMaxThreads(featureFlag.config) : raiseExistingAgentsMaxThreads(featureFlag.config);
8695
- const maxThreadsValue = CODEX_SUBAGENT_THREAD_LIMIT.toString();
8696
9030
  const preserveDisable = featureFlag.value === false && !v2Preferred;
8697
9031
  const featureConfig = preserveDisable ? setMultiAgentV2Disable(agentsConfig) : v2Preferred ? removeMultiAgentV2Disable(agentsConfig) : agentsConfig;
9032
+ if (hasTomlSetting(featureConfig, CODEX_MULTI_AGENT_V2_THREAD_LIMIT_KEY))
9033
+ return featureConfig;
8698
9034
  const section = findTomlSection(featureConfig, CODEX_MULTI_AGENT_V2_HEADER);
8699
9035
  if (!section) {
8700
9036
  const enabledSetting = preserveDisable ? `enabled = false
8701
9037
  ` : "";
8702
9038
  return appendBlock(featureConfig, `[${CODEX_MULTI_AGENT_V2_HEADER}]
8703
- ${enabledSetting}max_concurrent_threads_per_session = ${maxThreadsValue}
9039
+ ${enabledSetting}max_concurrent_threads_per_session = ${CODEX_MULTI_AGENT_V2_THREAD_LIMIT}
8704
9040
  `);
8705
9041
  }
8706
- return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", maxThreadsValue);
9042
+ return replaceOrInsertSetting(featureConfig, section, "max_concurrent_threads_per_session", CODEX_MULTI_AGENT_V2_THREAD_LIMIT.toString());
8707
9043
  }
8708
9044
  function resolveCodexMultiAgentVersion(config, configPath) {
8709
9045
  const model = readRootModel(config);
@@ -9061,6 +9397,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9061
9397
  {
9062
9398
  previous: { model: "gpt-5.5", effort: "xhigh" },
9063
9399
  current: { model: "gpt-5.6-sol", effort: "ultra" }
9400
+ },
9401
+ {
9402
+ previous: { model: "gpt-5.6-sol", effort: "ultra" },
9403
+ current: { model: "gpt-5.6-terra", effort: "high" }
9064
9404
  }
9065
9405
  ]
9066
9406
  ],
@@ -9070,6 +9410,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9070
9410
  {
9071
9411
  previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9072
9412
  current: { model: "gpt-5.6-sol", effort: "max" }
9413
+ },
9414
+ {
9415
+ previous: { model: "gpt-5.6-sol", effort: "max" },
9416
+ current: { model: "gpt-5.6-sol", effort: "high" }
9073
9417
  }
9074
9418
  ]
9075
9419
  ],
@@ -9079,6 +9423,37 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9079
9423
  {
9080
9424
  previous: { model: "gpt-5.6-sol", effort: "high" },
9081
9425
  current: { model: "gpt-5.6-luna", effort: "max" }
9426
+ },
9427
+ {
9428
+ previous: { model: "gpt-5.6-luna", effort: "max" },
9429
+ current: { model: "gpt-5.6-terra", effort: "high" }
9430
+ }
9431
+ ]
9432
+ ],
9433
+ [
9434
+ "lazycodex-worker-high",
9435
+ [
9436
+ {
9437
+ previous: { model: "gpt-5.6-sol", effort: "max" },
9438
+ current: { model: "gpt-5.6-sol", effort: "medium" }
9439
+ }
9440
+ ]
9441
+ ],
9442
+ [
9443
+ "lazycodex-code-reviewer",
9444
+ [
9445
+ {
9446
+ previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9447
+ current: { model: "gpt-5.6-terra", effort: "medium" }
9448
+ }
9449
+ ]
9450
+ ],
9451
+ [
9452
+ "lazycodex-clone-fidelity-reviewer",
9453
+ [
9454
+ {
9455
+ previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9456
+ current: { model: "gpt-5.6-terra", effort: "high" }
9082
9457
  }
9083
9458
  ]
9084
9459
  ],
@@ -9097,6 +9472,10 @@ var MANAGED_REASONING_DEFAULT_UPGRADES = new Map([
9097
9472
  {
9098
9473
  previous: { model: "gpt-5.6-sol", effort: "xhigh" },
9099
9474
  current: { model: "gpt-5.6-sol", effort: "high" }
9475
+ },
9476
+ {
9477
+ previous: { model: "gpt-5.6-sol", effort: "high" },
9478
+ current: { model: "gpt-5.6-sol", effort: "low" }
9100
9479
  }
9101
9480
  ]
9102
9481
  ]
@@ -0,0 +1,87 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test"
2
+ import { spawnSync } from "node:child_process"
3
+ import { copyFileSync, mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"
4
+ import { createRequire } from "node:module"
5
+ import { tmpdir } from "node:os"
6
+ import { dirname, join } from "node:path"
7
+
8
+ // Regression for lazycodex#111: the script must resolve `typescript` from the
9
+ // caller project (cwd), not from the script's own location, so it works when
10
+ // executed from an installed `~/.codex/...` skill cache.
11
+
12
+ const scriptSource = join(import.meta.dir, "check-no-excuse-rules.ts")
13
+ const repoRequire = createRequire(import.meta.url)
14
+ const typescriptPackageDir = dirname(repoRequire.resolve("typescript/package.json"))
15
+
16
+ let tempRoot = ""
17
+ let cachedScript = ""
18
+ let callerDir = ""
19
+ let callerWithoutTypescriptDir = ""
20
+
21
+ function runNoExcuse(cwd: string, target: string) {
22
+ return spawnSync(process.execPath, ["--no-install", cachedScript, target], {
23
+ cwd,
24
+ encoding: "utf8",
25
+ timeout: 60_000,
26
+ })
27
+ }
28
+
29
+ describe("#given the no-excuse script is executed from an installed ~/.codex-style skill cache", () => {
30
+ beforeAll(() => {
31
+ // given a cache copy of the script outside any project, and two caller projects:
32
+ // one providing node_modules/typescript, one without typescript at all
33
+ tempRoot = mkdtempSync(join(tmpdir(), "no-excuse-cache-repro-"))
34
+ const cacheDir = join(tempRoot, ".codex", "skills", "programming", "scripts", "typescript")
35
+ mkdirSync(cacheDir, { recursive: true })
36
+ cachedScript = join(cacheDir, "check-no-excuse-rules.ts")
37
+ copyFileSync(scriptSource, cachedScript)
38
+
39
+ callerDir = join(tempRoot, "caller-project")
40
+ mkdirSync(join(callerDir, "node_modules"), { recursive: true })
41
+ symlinkSync(typescriptPackageDir, join(callerDir, "node_modules", "typescript"), "junction")
42
+ writeFileSync(join(callerDir, "clean.ts"), "export const answer: number = 42\n")
43
+ writeFileSync(join(callerDir, "violating.ts"), "const x = foo as any\nexport default x\n")
44
+
45
+ callerWithoutTypescriptDir = join(tempRoot, "caller-without-typescript")
46
+ mkdirSync(callerWithoutTypescriptDir, { recursive: true })
47
+ writeFileSync(join(callerWithoutTypescriptDir, "clean.ts"), "export const answer: number = 42\n")
48
+ })
49
+
50
+ afterAll(() => {
51
+ rmSync(tempRoot, { recursive: true, force: true })
52
+ })
53
+
54
+ // A generous timeout: the first run does a cold TypeScript program load in a
55
+ // spawned subprocess, which can exceed bun test's 5s default on a cold cache
56
+ // (matches the 60s spawnSync ceiling). This bounds the subprocess, it does not
57
+ // wait on wall-clock time as behavior.
58
+ test("#when the caller project provides typescript #then it resolves the caller's typescript and exits 0", () => {
59
+ // when no-excuse runs from the cache copy against the caller project
60
+ const result = runNoExcuse(callerDir, "clean.ts")
61
+
62
+ // then the caller's own typescript is used and the clean file passes
63
+ expect(result.error).toBeUndefined()
64
+ expect(result.status).toBe(0)
65
+ expect(result.stdout).toContain("No violations in 1 file(s).")
66
+ }, 60_000)
67
+
68
+ test("#when a checked file violates the rules #then violations are still reported with exit 1", () => {
69
+ // when no-excuse runs against a file containing `as any`
70
+ const result = runNoExcuse(callerDir, "violating.ts")
71
+
72
+ // then the existing CLI behavior is unchanged
73
+ expect(result.error).toBeUndefined()
74
+ expect(result.status).toBe(1)
75
+ expect(result.stderr).toContain("[no-any-assertion]")
76
+ }, 60_000)
77
+
78
+ test("#when the caller project genuinely lacks typescript #then it fails with a clear error and exit 2", () => {
79
+ // when no-excuse runs from a caller project with no local typescript
80
+ const result = runNoExcuse(callerWithoutTypescriptDir, "clean.ts")
81
+
82
+ // then it reports the resolution problem instead of crashing mid-analysis
83
+ expect(result.error).toBeUndefined()
84
+ expect(result.status).toBe(2)
85
+ expect(result.stderr).toContain('cannot resolve "typescript" from the caller project')
86
+ }, 60_000)
87
+ })