oh-my-opencode 5.0.0-beta.31 → 5.0.0-beta.32

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 (227) hide show
  1. package/dist/cli/index.js +136 -44
  2. package/dist/cli-node/index.js +136 -44
  3. package/dist/features/background-agent/parent-wake-notifier-types.d.ts +1 -1
  4. package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -1
  5. package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -1
  6. package/dist/features/monitor/manager-internals.d.ts +1 -1
  7. package/dist/features/monitor/output-injector-types.d.ts +1 -1
  8. package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +1 -0
  9. package/dist/features/team-mode/tools/messaging-runtime.d.ts +1 -0
  10. package/dist/hooks/anthropic-context-window-limit-recovery/tool-result-storage.d.ts +11 -0
  11. package/dist/index.js +286 -99
  12. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  13. package/dist/tools/session-manager/directory-filter.d.ts +2 -0
  14. package/dist/tui.js +109 -23
  15. package/package.json +16 -15
  16. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +47 -19
  17. package/packages/lsp-core/src/lsp/client-diagnostics-pull-timeout.test.ts +64 -0
  18. package/packages/lsp-core/src/lsp/client.ts +6 -3
  19. package/packages/lsp-core/src/lsp/controlled-clock-test-support.ts +61 -0
  20. package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +10 -3
  21. package/packages/lsp-core/src/lsp/timer-provider.ts +13 -0
  22. package/packages/lsp-core/src/lsp/transport-request-timeout.test.ts +73 -0
  23. package/packages/lsp-core/src/lsp/transport.ts +7 -2
  24. package/packages/lsp-core/src/lsp/workspace-document-state.test.ts +84 -1
  25. package/packages/lsp-core/src/lsp/workspace-document-state.ts +30 -11
  26. package/packages/lsp-core/src/tools/parameters.test.ts +51 -0
  27. package/packages/lsp-daemon/dist/cli.js +41 -16
  28. package/packages/lsp-daemon/dist/client.js +41 -16
  29. package/packages/lsp-daemon/dist/index.js +41 -16
  30. package/packages/lsp-tools-mcp/dist/cli.js +41 -16
  31. package/packages/lsp-tools-mcp/dist/lsp/manager.js +41 -16
  32. package/packages/lsp-tools-mcp/dist/mcp.js +41 -16
  33. package/packages/lsp-tools-mcp/dist/tools.js +41 -16
  34. package/packages/lsp-tools-mcp/package.json +1 -1
  35. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  36. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  37. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +3 -17
  39. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +3 -17
  40. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  41. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  42. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  43. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  44. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  45. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  46. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  47. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  48. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +39 -16
  49. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  50. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  52. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  53. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  56. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  57. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -4
  58. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +489 -4
  59. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  60. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -2
  61. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +30 -14
  62. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +4 -0
  63. package/packages/omo-codex/plugin/components/ultrawork/src/directive.ts +5 -2
  64. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +14 -8
  65. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +12 -1
  66. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
  67. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  68. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +4 -2
  69. package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -0
  70. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +9 -0
  71. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +14 -0
  72. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +10 -1
  73. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.d.ts +8 -0
  74. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +113 -0
  75. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +7 -5
  76. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  77. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  78. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +1 -0
  79. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +2 -0
  80. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +775 -312
  81. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +18 -0
  82. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +13 -0
  83. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +14 -0
  84. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +17 -9
  85. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +17 -2
  86. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +13 -0
  87. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +19 -0
  88. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +2 -0
  89. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +53 -0
  90. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.d.ts +9 -0
  91. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +85 -0
  92. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +1 -1
  93. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +41 -99
  94. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +4 -2
  95. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +184 -14
  96. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +6 -0
  97. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +33 -0
  98. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +3 -0
  99. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +15 -0
  100. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  101. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  102. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +17 -0
  103. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +7 -0
  104. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +25 -1
  105. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +127 -0
  106. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +8 -12
  107. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +2 -1
  108. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +1 -0
  109. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +2 -0
  110. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +18 -0
  111. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +23 -0
  112. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +19 -9
  113. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +18 -3
  114. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +27 -0
  115. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +57 -0
  116. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +103 -0
  117. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +1 -1
  118. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +50 -116
  119. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +4 -2
  120. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +186 -12
  121. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +36 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +22 -0
  123. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +66 -3
  124. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +92 -0
  125. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-status-next-actions.test.ts +183 -0
  126. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +13 -3
  127. package/packages/omo-codex/plugin/components/ulw-loop/test/guided-recovery.test.ts +105 -0
  128. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +101 -0
  129. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +16 -15
  130. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-senpi-surface.test.ts +131 -0
  131. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +5 -0
  132. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +300 -3
  133. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +9 -3
  134. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  135. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  136. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  137. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  138. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  139. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  140. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  141. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  142. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  143. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  144. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  145. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  146. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  147. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  148. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  149. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  151. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  157. package/packages/omo-codex/plugin/package-lock.json +13 -13
  158. package/packages/omo-codex/plugin/package.json +1 -1
  159. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +31 -2
  160. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  161. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +17 -0
  162. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +11 -1
  163. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +13 -0
  164. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +5 -2
  165. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  166. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -2
  167. package/dist/features/builtin-skills/index.d.ts +0 -1
  168. package/dist/features/builtin-skills/skill-file-loader.d.ts +0 -1
  169. package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +0 -1
  170. package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +0 -1
  171. package/dist/features/builtin-skills/skills/debugging.d.ts +0 -1
  172. package/dist/features/builtin-skills/skills/dev-browser.d.ts +0 -1
  173. package/dist/features/builtin-skills/skills/frontend.d.ts +0 -1
  174. package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +0 -1
  175. package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +0 -1
  176. package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +0 -1
  177. package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +0 -1
  178. package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +0 -1
  179. package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +0 -1
  180. package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +0 -1
  181. package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +0 -1
  182. package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +0 -1
  183. package/dist/features/builtin-skills/skills/git-master.d.ts +0 -1
  184. package/dist/features/builtin-skills/skills/index.d.ts +0 -1
  185. package/dist/features/builtin-skills/skills/init-deep.d.ts +0 -1
  186. package/dist/features/builtin-skills/skills/playwright-cli.d.ts +0 -1
  187. package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +0 -1
  188. package/dist/features/builtin-skills/skills/playwright.d.ts +0 -1
  189. package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +0 -1
  190. package/dist/features/builtin-skills/skills/review-work.d.ts +0 -1
  191. package/dist/features/builtin-skills/skills/security-research.d.ts +0 -1
  192. package/dist/features/builtin-skills/skills/security-review.d.ts +0 -1
  193. package/dist/features/builtin-skills/skills/team-mode.d.ts +0 -1
  194. package/dist/features/builtin-skills/skills/visual-qa.d.ts +0 -1
  195. package/dist/features/builtin-skills/skills.d.ts +0 -1
  196. package/dist/features/builtin-skills/types.d.ts +0 -1
  197. package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +0 -1
  198. package/dist/features/claude-code-plugin-loader/command-loader.d.ts +0 -1
  199. package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +0 -1
  200. package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +0 -1
  201. package/dist/features/claude-code-plugin-loader/discovery.d.ts +0 -1
  202. package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +0 -1
  203. package/dist/features/claude-code-plugin-loader/index.d.ts +0 -1
  204. package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +0 -1
  205. package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +0 -1
  206. package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +0 -1
  207. package/dist/features/claude-code-plugin-loader/loader.d.ts +0 -1
  208. package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +0 -1
  209. package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +0 -1
  210. package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +0 -1
  211. package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +0 -1
  212. package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +0 -1
  213. package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +0 -1
  214. package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +0 -1
  215. package/dist/features/claude-code-plugin-loader/types.d.ts +0 -1
  216. package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +0 -1
  217. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +0 -1
  218. package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +0 -1
  219. package/dist/shared/prompt-async-gate/queue.d.ts +0 -1
  220. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +0 -1
  221. package/dist/shared/prompt-async-gate/reservations.d.ts +0 -1
  222. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +0 -1
  223. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +0 -1
  224. package/dist/shared/prompt-async-gate/timing.d.ts +0 -1
  225. package/dist/shared/prompt-async-gate/types.d.ts +0 -1
  226. package/packages/omo-codex/plugin/components/ultrawork/directive.md +0 -483
  227. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +0 -490
@@ -15,6 +15,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
15
15
  // ../lsp-core/src/lsp/connection.ts
16
16
  import { pathToFileURL } from "node:url";
17
17
 
18
+ // ../lsp-core/src/lsp/timer-provider.ts
19
+ var realTimerProvider = {
20
+ now: () => Date.now(),
21
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
22
+ clearTimeout: (handle) => clearTimeout(handle)
23
+ };
24
+
18
25
  // ../lsp-core/src/lsp/constants.ts
19
26
  var DEFAULT_MAX_REFERENCES = 200;
20
27
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -631,6 +638,7 @@ class LspClientTransport {
631
638
  this.documentFormattingSupported = false;
632
639
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
633
640
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
641
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
634
642
  }
635
643
  pid() {
636
644
  return this.proc?.pid;
@@ -731,7 +739,7 @@ class LspClientTransport {
731
739
  const options = args[1];
732
740
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
733
741
  const timeoutController = new AbortController;
734
- const timeoutHandle = setTimeout(() => {
742
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
735
743
  const stderrTail = this.stderrBuffer.slice(-5).join(`
736
744
  `);
737
745
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -750,7 +758,7 @@ class LspClientTransport {
750
758
  }
751
759
  throw error;
752
760
  } finally {
753
- clearTimeout(timeoutHandle);
761
+ this.timerProvider.clearTimeout(timeoutHandle);
754
762
  combinedSignal.dispose();
755
763
  }
756
764
  }
@@ -1141,6 +1149,17 @@ function canonicalPath(filePath) {
1141
1149
  return absolute;
1142
1150
  }
1143
1151
  }
1152
+ function normalizeDocumentUri(uri) {
1153
+ let decoded = uri;
1154
+ try {
1155
+ decoded = decodeURIComponent(uri);
1156
+ } catch {
1157
+ decoded = uri;
1158
+ }
1159
+ if (process.platform !== "win32")
1160
+ return decoded;
1161
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1162
+ }
1144
1163
  function isSameOrDescendant(candidate, parent) {
1145
1164
  const suffix = relative(parent, candidate);
1146
1165
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1157,7 +1176,12 @@ class WorkspaceDocumentState {
1157
1176
  this.openDocuments = new Map;
1158
1177
  this.openByUri = new Map;
1159
1178
  this.openPromises = new Map;
1160
- this.now = options.now ?? (() => Date.now());
1179
+ this.timerProvider = options.timerProvider ?? {
1180
+ now: options.now ?? (() => Date.now()),
1181
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1182
+ clearTimeout: (handle) => clearTimeout(handle)
1183
+ };
1184
+ this.now = () => this.timerProvider.now();
1161
1185
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1162
1186
  }
1163
1187
  async openFile(filePath) {
@@ -1179,7 +1203,7 @@ class WorkspaceDocumentState {
1179
1203
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1180
1204
  }
1181
1205
  getStoredDiagnostics(uri) {
1182
- const state = this.openByUri.get(uri);
1206
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1183
1207
  if (!state)
1184
1208
  return [];
1185
1209
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1201,13 +1225,13 @@ class WorkspaceDocumentState {
1201
1225
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1202
1226
  }
1203
1227
  getPullCache(snapshot) {
1204
- const state = this.openByUri.get(snapshot.uri);
1228
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1205
1229
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1206
1230
  return null;
1207
1231
  return state.pullCache;
1208
1232
  }
1209
1233
  recordPullDiagnostics(snapshot, report) {
1210
- const state = this.openByUri.get(snapshot.uri);
1234
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1211
1235
  if (!state)
1212
1236
  return;
1213
1237
  state.pullCache = {
@@ -1217,7 +1241,7 @@ class WorkspaceDocumentState {
1217
1241
  };
1218
1242
  }
1219
1243
  recordPublishedDiagnostics(params) {
1220
- const state = this.openByUri.get(params.uri);
1244
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1221
1245
  if (!state)
1222
1246
  return;
1223
1247
  state.publishGeneration += 1;
@@ -1231,7 +1255,7 @@ class WorkspaceDocumentState {
1231
1255
  this.notifyWaiters(state);
1232
1256
  }
1233
1257
  resolvePushDiagnostics(snapshot) {
1234
- const state = this.openByUri.get(snapshot.uri);
1258
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1235
1259
  if (!state?.lastPublish)
1236
1260
  return { status: "missing" };
1237
1261
  const publish = state.lastPublish;
@@ -1245,7 +1269,7 @@ class WorkspaceDocumentState {
1245
1269
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1246
1270
  }
1247
1271
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1248
- const state = this.openByUri.get(snapshot.uri);
1272
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1249
1273
  if (!state || timeoutMs <= 0)
1250
1274
  return Promise.resolve();
1251
1275
  return new Promise((resolveActivity) => {
@@ -1254,11 +1278,11 @@ class WorkspaceDocumentState {
1254
1278
  if (settled)
1255
1279
  return;
1256
1280
  settled = true;
1257
- clearTimeout(timer);
1281
+ this.timerProvider.clearTimeout(timer);
1258
1282
  state.waiters.delete(finish);
1259
1283
  resolveActivity();
1260
1284
  };
1261
- const timer = setTimeout(finish, timeoutMs);
1285
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1262
1286
  if (typeof timer.unref === "function")
1263
1287
  timer.unref();
1264
1288
  state.waiters.add(finish);
@@ -1366,7 +1390,7 @@ class WorkspaceDocumentState {
1366
1390
  waiters: new Set
1367
1391
  };
1368
1392
  this.openDocuments.set(path, state);
1369
- this.openByUri.set(state.uri, state);
1393
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1370
1394
  this.notifyWaiters(state);
1371
1395
  await this.sendNotification("textDocument/didOpen", {
1372
1396
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1391,7 +1415,7 @@ class WorkspaceDocumentState {
1391
1415
  }
1392
1416
  async closeDocument(state) {
1393
1417
  this.openDocuments.delete(state.path);
1394
- this.openByUri.delete(state.uri);
1418
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1395
1419
  this.clearDiagnostics(state.uri);
1396
1420
  this.notifyWaiters(state);
1397
1421
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -2478,6 +2502,7 @@ class LspClient extends LspClientConnection {
2478
2502
  this.diagnosticPullErrors = [];
2479
2503
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2480
2504
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2505
+ timerProvider: this.timerProvider,
2481
2506
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2482
2507
  });
2483
2508
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -2581,7 +2606,7 @@ class LspClient extends LspClientConnection {
2581
2606
  const absPath = this.resolveWorkspacePath(filePath);
2582
2607
  const uri = pathToFileURL3(absPath).href;
2583
2608
  await this.openFile(absPath);
2584
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
2609
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
2585
2610
  for (;; ) {
2586
2611
  signal?.throwIfAborted();
2587
2612
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -2594,7 +2619,7 @@ class LspClient extends LspClientConnection {
2594
2619
  if (!pushFallbackOnly) {
2595
2620
  const cached = this.documents.getPullCache(snapshot);
2596
2621
  try {
2597
- const remainingMs2 = deadlineAt - Date.now();
2622
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
2598
2623
  if (remainingMs2 <= 0)
2599
2624
  return this.freshnessTimeout(absPath);
2600
2625
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -2629,7 +2654,7 @@ class LspClient extends LspClientConnection {
2629
2654
  }
2630
2655
  if (!pushFallbackOnly)
2631
2656
  continue;
2632
- const remainingMs = deadlineAt - Date.now();
2657
+ const remainingMs = deadlineAt - this.timerProvider.now();
2633
2658
  if (remainingMs <= 0) {
2634
2659
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
2635
2660
  const cached = this.documents.getPullCache(snapshot);
@@ -596,6 +596,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
596
596
  // ../lsp-core/src/lsp/connection.ts
597
597
  import { pathToFileURL } from "node:url";
598
598
 
599
+ // ../lsp-core/src/lsp/timer-provider.ts
600
+ var realTimerProvider = {
601
+ now: () => Date.now(),
602
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
603
+ clearTimeout: (handle) => clearTimeout(handle)
604
+ };
605
+
599
606
  // ../lsp-core/src/lsp/constants.ts
600
607
  var DEFAULT_MAX_REFERENCES = 200;
601
608
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -1135,6 +1142,7 @@ class LspClientTransport {
1135
1142
  this.documentFormattingSupported = false;
1136
1143
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1137
1144
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1145
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
1138
1146
  }
1139
1147
  pid() {
1140
1148
  return this.proc?.pid;
@@ -1235,7 +1243,7 @@ class LspClientTransport {
1235
1243
  const options = args[1];
1236
1244
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
1237
1245
  const timeoutController = new AbortController;
1238
- const timeoutHandle = setTimeout(() => {
1246
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
1239
1247
  const stderrTail = this.stderrBuffer.slice(-5).join(`
1240
1248
  `);
1241
1249
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -1254,7 +1262,7 @@ class LspClientTransport {
1254
1262
  }
1255
1263
  throw error;
1256
1264
  } finally {
1257
- clearTimeout(timeoutHandle);
1265
+ this.timerProvider.clearTimeout(timeoutHandle);
1258
1266
  combinedSignal.dispose();
1259
1267
  }
1260
1268
  }
@@ -1635,6 +1643,17 @@ function canonicalPath(filePath) {
1635
1643
  return absolute;
1636
1644
  }
1637
1645
  }
1646
+ function normalizeDocumentUri(uri) {
1647
+ let decoded = uri;
1648
+ try {
1649
+ decoded = decodeURIComponent(uri);
1650
+ } catch {
1651
+ decoded = uri;
1652
+ }
1653
+ if (process.platform !== "win32")
1654
+ return decoded;
1655
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1656
+ }
1638
1657
  function isSameOrDescendant(candidate, parent) {
1639
1658
  const suffix = relative2(parent, candidate);
1640
1659
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1651,7 +1670,12 @@ class WorkspaceDocumentState {
1651
1670
  this.openDocuments = new Map;
1652
1671
  this.openByUri = new Map;
1653
1672
  this.openPromises = new Map;
1654
- this.now = options.now ?? (() => Date.now());
1673
+ this.timerProvider = options.timerProvider ?? {
1674
+ now: options.now ?? (() => Date.now()),
1675
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1676
+ clearTimeout: (handle) => clearTimeout(handle)
1677
+ };
1678
+ this.now = () => this.timerProvider.now();
1655
1679
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1656
1680
  }
1657
1681
  async openFile(filePath) {
@@ -1673,7 +1697,7 @@ class WorkspaceDocumentState {
1673
1697
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1674
1698
  }
1675
1699
  getStoredDiagnostics(uri) {
1676
- const state = this.openByUri.get(uri);
1700
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1677
1701
  if (!state)
1678
1702
  return [];
1679
1703
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1695,13 +1719,13 @@ class WorkspaceDocumentState {
1695
1719
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1696
1720
  }
1697
1721
  getPullCache(snapshot) {
1698
- const state = this.openByUri.get(snapshot.uri);
1722
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1699
1723
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1700
1724
  return null;
1701
1725
  return state.pullCache;
1702
1726
  }
1703
1727
  recordPullDiagnostics(snapshot, report) {
1704
- const state = this.openByUri.get(snapshot.uri);
1728
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1705
1729
  if (!state)
1706
1730
  return;
1707
1731
  state.pullCache = {
@@ -1711,7 +1735,7 @@ class WorkspaceDocumentState {
1711
1735
  };
1712
1736
  }
1713
1737
  recordPublishedDiagnostics(params) {
1714
- const state = this.openByUri.get(params.uri);
1738
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1715
1739
  if (!state)
1716
1740
  return;
1717
1741
  state.publishGeneration += 1;
@@ -1725,7 +1749,7 @@ class WorkspaceDocumentState {
1725
1749
  this.notifyWaiters(state);
1726
1750
  }
1727
1751
  resolvePushDiagnostics(snapshot) {
1728
- const state = this.openByUri.get(snapshot.uri);
1752
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1729
1753
  if (!state?.lastPublish)
1730
1754
  return { status: "missing" };
1731
1755
  const publish = state.lastPublish;
@@ -1739,7 +1763,7 @@ class WorkspaceDocumentState {
1739
1763
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1740
1764
  }
1741
1765
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1742
- const state = this.openByUri.get(snapshot.uri);
1766
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1743
1767
  if (!state || timeoutMs <= 0)
1744
1768
  return Promise.resolve();
1745
1769
  return new Promise((resolveActivity) => {
@@ -1748,11 +1772,11 @@ class WorkspaceDocumentState {
1748
1772
  if (settled)
1749
1773
  return;
1750
1774
  settled = true;
1751
- clearTimeout(timer);
1775
+ this.timerProvider.clearTimeout(timer);
1752
1776
  state.waiters.delete(finish);
1753
1777
  resolveActivity();
1754
1778
  };
1755
- const timer = setTimeout(finish, timeoutMs);
1779
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1756
1780
  if (typeof timer.unref === "function")
1757
1781
  timer.unref();
1758
1782
  state.waiters.add(finish);
@@ -1860,7 +1884,7 @@ class WorkspaceDocumentState {
1860
1884
  waiters: new Set
1861
1885
  };
1862
1886
  this.openDocuments.set(path, state);
1863
- this.openByUri.set(state.uri, state);
1887
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1864
1888
  this.notifyWaiters(state);
1865
1889
  await this.sendNotification("textDocument/didOpen", {
1866
1890
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1885,7 +1909,7 @@ class WorkspaceDocumentState {
1885
1909
  }
1886
1910
  async closeDocument(state) {
1887
1911
  this.openDocuments.delete(state.path);
1888
- this.openByUri.delete(state.uri);
1912
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1889
1913
  this.clearDiagnostics(state.uri);
1890
1914
  this.notifyWaiters(state);
1891
1915
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -2972,6 +2996,7 @@ class LspClient extends LspClientConnection {
2972
2996
  this.diagnosticPullErrors = [];
2973
2997
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2974
2998
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2999
+ timerProvider: this.timerProvider,
2975
3000
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2976
3001
  });
2977
3002
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -3075,7 +3100,7 @@ class LspClient extends LspClientConnection {
3075
3100
  const absPath = this.resolveWorkspacePath(filePath);
3076
3101
  const uri = pathToFileURL3(absPath).href;
3077
3102
  await this.openFile(absPath);
3078
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
3103
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
3079
3104
  for (;; ) {
3080
3105
  signal?.throwIfAborted();
3081
3106
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -3088,7 +3113,7 @@ class LspClient extends LspClientConnection {
3088
3113
  if (!pushFallbackOnly) {
3089
3114
  const cached = this.documents.getPullCache(snapshot);
3090
3115
  try {
3091
- const remainingMs2 = deadlineAt - Date.now();
3116
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
3092
3117
  if (remainingMs2 <= 0)
3093
3118
  return this.freshnessTimeout(absPath);
3094
3119
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -3123,7 +3148,7 @@ class LspClient extends LspClientConnection {
3123
3148
  }
3124
3149
  if (!pushFallbackOnly)
3125
3150
  continue;
3126
- const remainingMs = deadlineAt - Date.now();
3151
+ const remainingMs = deadlineAt - this.timerProvider.now();
3127
3152
  if (remainingMs <= 0) {
3128
3153
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
3129
3154
  const cached = this.documents.getPullCache(snapshot);
@@ -284,6 +284,13 @@ import { pathToFileURL as pathToFileURL3 } from "node:url";
284
284
  // ../lsp-core/src/lsp/connection.ts
285
285
  import { pathToFileURL } from "node:url";
286
286
 
287
+ // ../lsp-core/src/lsp/timer-provider.ts
288
+ var realTimerProvider = {
289
+ now: () => Date.now(),
290
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
291
+ clearTimeout: (handle) => clearTimeout(handle)
292
+ };
293
+
287
294
  // ../lsp-core/src/lsp/constants.ts
288
295
  var DEFAULT_MAX_REFERENCES = 200;
289
296
  var DEFAULT_MAX_SYMBOLS = 200;
@@ -823,6 +830,7 @@ class LspClientTransport {
823
830
  this.documentFormattingSupported = false;
824
831
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
825
832
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
833
+ this.timerProvider = timeouts.timerProvider ?? realTimerProvider;
826
834
  }
827
835
  pid() {
828
836
  return this.proc?.pid;
@@ -923,7 +931,7 @@ class LspClientTransport {
923
931
  const options = args[1];
924
932
  const timeoutMs = options?.timeoutMs ?? this.requestTimeoutMs;
925
933
  const timeoutController = new AbortController;
926
- const timeoutHandle = setTimeout(() => {
934
+ const timeoutHandle = this.timerProvider.setTimeout(() => {
927
935
  const stderrTail = this.stderrBuffer.slice(-5).join(`
928
936
  `);
929
937
  timeoutController.abort(new LspRequestTimeoutError(method, stderrTail || undefined));
@@ -942,7 +950,7 @@ class LspClientTransport {
942
950
  }
943
951
  throw error;
944
952
  } finally {
945
- clearTimeout(timeoutHandle);
953
+ this.timerProvider.clearTimeout(timeoutHandle);
946
954
  combinedSignal.dispose();
947
955
  }
948
956
  }
@@ -1323,6 +1331,17 @@ function canonicalPath(filePath) {
1323
1331
  return absolute;
1324
1332
  }
1325
1333
  }
1334
+ function normalizeDocumentUri(uri) {
1335
+ let decoded = uri;
1336
+ try {
1337
+ decoded = decodeURIComponent(uri);
1338
+ } catch {
1339
+ decoded = uri;
1340
+ }
1341
+ if (process.platform !== "win32")
1342
+ return decoded;
1343
+ return decoded.replace(/^(file:\/\/\/)([a-z]):/, (_match, prefix, drive) => `${prefix}${drive.toUpperCase()}:`);
1344
+ }
1326
1345
  function isSameOrDescendant(candidate, parent) {
1327
1346
  const suffix = relative2(parent, candidate);
1328
1347
  return suffix === "" || !suffix.startsWith("..") && suffix !== "..";
@@ -1339,7 +1358,12 @@ class WorkspaceDocumentState {
1339
1358
  this.openDocuments = new Map;
1340
1359
  this.openByUri = new Map;
1341
1360
  this.openPromises = new Map;
1342
- this.now = options.now ?? (() => Date.now());
1361
+ this.timerProvider = options.timerProvider ?? {
1362
+ now: options.now ?? (() => Date.now()),
1363
+ setTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
1364
+ clearTimeout: (handle) => clearTimeout(handle)
1365
+ };
1366
+ this.now = () => this.timerProvider.now();
1343
1367
  this.versionlessPublishQuiescenceMs = options.versionlessPublishQuiescenceMs ?? DEFAULT_VERSIONLESS_PUBLISH_QUIESCENCE_MS;
1344
1368
  }
1345
1369
  async openFile(filePath) {
@@ -1361,7 +1385,7 @@ class WorkspaceDocumentState {
1361
1385
  return this.openDocuments.get(canonicalPath(filePath))?.version;
1362
1386
  }
1363
1387
  getStoredDiagnostics(uri) {
1364
- const state = this.openByUri.get(uri);
1388
+ const state = this.openByUri.get(normalizeDocumentUri(uri));
1365
1389
  if (!state)
1366
1390
  return [];
1367
1391
  return state.lastPublish?.diagnostics ?? state.pullCache?.diagnostics ?? [];
@@ -1383,13 +1407,13 @@ class WorkspaceDocumentState {
1383
1407
  return state !== undefined && state.uri === snapshot.uri && state.version === snapshot.version && state.generation === snapshot.documentGeneration;
1384
1408
  }
1385
1409
  getPullCache(snapshot) {
1386
- const state = this.openByUri.get(snapshot.uri);
1410
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1387
1411
  if (!state?.pullCache || state.pullCache.documentVersion !== snapshot.version)
1388
1412
  return null;
1389
1413
  return state.pullCache;
1390
1414
  }
1391
1415
  recordPullDiagnostics(snapshot, report) {
1392
- const state = this.openByUri.get(snapshot.uri);
1416
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1393
1417
  if (!state)
1394
1418
  return;
1395
1419
  state.pullCache = {
@@ -1399,7 +1423,7 @@ class WorkspaceDocumentState {
1399
1423
  };
1400
1424
  }
1401
1425
  recordPublishedDiagnostics(params) {
1402
- const state = this.openByUri.get(params.uri);
1426
+ const state = this.openByUri.get(normalizeDocumentUri(params.uri));
1403
1427
  if (!state)
1404
1428
  return;
1405
1429
  state.publishGeneration += 1;
@@ -1413,7 +1437,7 @@ class WorkspaceDocumentState {
1413
1437
  this.notifyWaiters(state);
1414
1438
  }
1415
1439
  resolvePushDiagnostics(snapshot) {
1416
- const state = this.openByUri.get(snapshot.uri);
1440
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1417
1441
  if (!state?.lastPublish)
1418
1442
  return { status: "missing" };
1419
1443
  const publish = state.lastPublish;
@@ -1427,7 +1451,7 @@ class WorkspaceDocumentState {
1427
1451
  return waitMs === 0 ? { status: "ready", diagnostics: publish.diagnostics } : { status: "wait", waitMs };
1428
1452
  }
1429
1453
  waitForDiagnosticsActivity(snapshot, timeoutMs) {
1430
- const state = this.openByUri.get(snapshot.uri);
1454
+ const state = this.openByUri.get(normalizeDocumentUri(snapshot.uri));
1431
1455
  if (!state || timeoutMs <= 0)
1432
1456
  return Promise.resolve();
1433
1457
  return new Promise((resolveActivity) => {
@@ -1436,11 +1460,11 @@ class WorkspaceDocumentState {
1436
1460
  if (settled)
1437
1461
  return;
1438
1462
  settled = true;
1439
- clearTimeout(timer);
1463
+ this.timerProvider.clearTimeout(timer);
1440
1464
  state.waiters.delete(finish);
1441
1465
  resolveActivity();
1442
1466
  };
1443
- const timer = setTimeout(finish, timeoutMs);
1467
+ const timer = this.timerProvider.setTimeout(finish, timeoutMs);
1444
1468
  if (typeof timer.unref === "function")
1445
1469
  timer.unref();
1446
1470
  state.waiters.add(finish);
@@ -1548,7 +1572,7 @@ class WorkspaceDocumentState {
1548
1572
  waiters: new Set
1549
1573
  };
1550
1574
  this.openDocuments.set(path, state);
1551
- this.openByUri.set(state.uri, state);
1575
+ this.openByUri.set(normalizeDocumentUri(state.uri), state);
1552
1576
  this.notifyWaiters(state);
1553
1577
  await this.sendNotification("textDocument/didOpen", {
1554
1578
  textDocument: { uri: state.uri, languageId: state.languageId, version: state.version, text }
@@ -1573,7 +1597,7 @@ class WorkspaceDocumentState {
1573
1597
  }
1574
1598
  async closeDocument(state) {
1575
1599
  this.openDocuments.delete(state.path);
1576
- this.openByUri.delete(state.uri);
1600
+ this.openByUri.delete(normalizeDocumentUri(state.uri));
1577
1601
  this.clearDiagnostics(state.uri);
1578
1602
  this.notifyWaiters(state);
1579
1603
  await this.sendNotification("textDocument/didClose", { textDocument: { uri: state.uri } });
@@ -2660,6 +2684,7 @@ class LspClient extends LspClientConnection {
2660
2684
  this.diagnosticPullErrors = [];
2661
2685
  this.diagnosticsFreshnessTimeoutMs = options.diagnosticsFreshnessTimeoutMs ?? DIAGNOSTICS_FRESHNESS_TIMEOUT_MS;
2662
2686
  this.documents = new WorkspaceDocumentState((method, params) => this.sendNotification(method, params), (uri) => this.diagnosticsStore.delete(uri), {
2687
+ timerProvider: this.timerProvider,
2663
2688
  versionlessPublishQuiescenceMs: options.versionlessPublishQuiescenceMs ?? VERSIONLESS_PUBLISH_QUIESCENCE_MS
2664
2689
  });
2665
2690
  this.workspaceMutations = new WorkspaceMutationController(root, this.documents);
@@ -2763,7 +2788,7 @@ class LspClient extends LspClientConnection {
2763
2788
  const absPath = this.resolveWorkspacePath(filePath);
2764
2789
  const uri = pathToFileURL3(absPath).href;
2765
2790
  await this.openFile(absPath);
2766
- const deadlineAt = Date.now() + this.diagnosticsFreshnessTimeoutMs;
2791
+ const deadlineAt = this.timerProvider.now() + this.diagnosticsFreshnessTimeoutMs;
2767
2792
  for (;; ) {
2768
2793
  signal?.throwIfAborted();
2769
2794
  const snapshot = this.documents.captureDiagnosticSnapshot(absPath);
@@ -2776,7 +2801,7 @@ class LspClient extends LspClientConnection {
2776
2801
  if (!pushFallbackOnly) {
2777
2802
  const cached = this.documents.getPullCache(snapshot);
2778
2803
  try {
2779
- const remainingMs2 = deadlineAt - Date.now();
2804
+ const remainingMs2 = deadlineAt - this.timerProvider.now();
2780
2805
  if (remainingMs2 <= 0)
2781
2806
  return this.freshnessTimeout(absPath);
2782
2807
  const result = await this.sendRequest("textDocument/diagnostic", {
@@ -2811,7 +2836,7 @@ class LspClient extends LspClientConnection {
2811
2836
  }
2812
2837
  if (!pushFallbackOnly)
2813
2838
  continue;
2814
- const remainingMs = deadlineAt - Date.now();
2839
+ const remainingMs = deadlineAt - this.timerProvider.now();
2815
2840
  if (remainingMs <= 0) {
2816
2841
  if (!this.isDiagnosticPullSupported() && snapshot.publishGeneration === 0) {
2817
2842
  const cached = this.documents.getPullCache(snapshot);
@@ -32,7 +32,7 @@
32
32
  "CHANGELOG.md"
33
33
  ],
34
34
  "scripts": {
35
- "build": "node scripts/ensure-core-links.mjs && rm -rf dist && tsc -p tsconfig.build.json --emitDeclarationOnly && bun build src/cli.ts src/mcp.ts src/tools.ts src/request-context.ts src/lsp/manager.ts --outdir dist --target node --format esm",
35
+ "build": "node scripts/ensure-core-links.mjs && node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json --emitDeclarationOnly && bun build src/cli.ts src/mcp.ts src/tools.ts src/request-context.ts src/lsp/manager.ts --outdir dist --target node --format esm",
36
36
  "test": "vitest --run",
37
37
  "test:watch": "vitest",
38
38
  "typecheck": "tsc --noEmit",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo",
3
- "version": "5.0.0-beta.31",
3
+ "version": "5.0.0-beta.32",
4
4
  "description": "One Codex plugin namespace for Yeongyu's local Codex components.",
5
5
  "author": {
6
6
  "name": "Yeongyu Kim",
@@ -8,7 +8,7 @@
8
8
  "command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
9
9
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 5.0.0-beta.31) Checking Bootstrap Provisioning"
11
+ "statusMessage": "(OmO 5.0.0-beta.32) Checking Bootstrap Provisioning"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-bootstrap",
3
- "version": "5.0.0-beta.31",
3
+ "version": "5.0.0-beta.32",
4
4
  "description": "Codex SessionStart bootstrap component that provisions LazyCodex runtime dependencies from a detached worker.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -5582,11 +5582,7 @@ var OmoMemorySearchSchema = object({
5582
5582
  }).strict();
5583
5583
  var OmoMemoryRecallSchema = object({
5584
5584
  enabled: boolean2().default(true),
5585
- max_items: number2().int().min(1).max(5).default(2),
5586
- budget_tokens: number2().int().positive().default(600),
5587
- excerpt_chars: number2().int().positive().default(200),
5588
- min_score: number2().optional(),
5589
- exclude: array(string2()).default([])
5585
+ max_items: number2().int().min(1).max(5).default(2)
5590
5586
  }).strict();
5591
5587
  var OmoMemoryNudgeSchema = object({
5592
5588
  enabled: boolean2().default(true),
@@ -5636,11 +5632,7 @@ var OmoMemorySearchLayerSchema = object({
5636
5632
  }).strict();
5637
5633
  var OmoMemoryRecallLayerSchema = object({
5638
5634
  enabled: boolean2().optional(),
5639
- max_items: number2().int().min(1).max(5).optional(),
5640
- budget_tokens: number2().int().positive().optional(),
5641
- excerpt_chars: number2().int().positive().optional(),
5642
- min_score: number2().optional(),
5643
- exclude: array(string2()).optional()
5635
+ max_items: number2().int().min(1).max(5).optional()
5644
5636
  }).strict();
5645
5637
  var OmoMemoryNudgeLayerSchema = object({
5646
5638
  enabled: boolean2().optional(),
@@ -5711,13 +5703,7 @@ var OmoMemorySettingsSchema = object({
5711
5703
  write_notice: OmoMemoryWriteNoticeSchema.default({ enabled: true }),
5712
5704
  sync: OmoMemorySyncSchema.default({ enabled: true }),
5713
5705
  search: OmoMemorySearchSchema.default({ enabled: true }),
5714
- recall: OmoMemoryRecallSchema.default({
5715
- enabled: true,
5716
- max_items: 2,
5717
- budget_tokens: 600,
5718
- excerpt_chars: 200,
5719
- exclude: []
5720
- }),
5706
+ recall: OmoMemoryRecallSchema.default({ enabled: true, max_items: 2 }),
5721
5707
  compile_warn_tokens: number2().int().positive().default(30000),
5722
5708
  agents: record(string2(), OmoMemoryAgentOverridesSchema).default({})
5723
5709
  }).strict();