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

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 (217) hide show
  1. package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
  2. package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
  3. package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
  4. package/README.ja.md +1 -1
  5. package/README.ko.md +1 -1
  6. package/README.md +1 -1
  7. package/README.ru.md +1 -1
  8. package/README.zh-cn.md +1 -1
  9. package/THIRD-PARTY-NOTICES.md +27 -99
  10. package/dist/cli/index.js +48342 -48539
  11. package/dist/cli-node/index.js +49017 -49214
  12. package/dist/config/index.d.ts +1 -1
  13. package/dist/config/schema/hooks.d.ts +0 -1
  14. package/dist/config/schema/oh-my-opencode-config.d.ts +0 -10
  15. package/dist/config/schema.d.ts +0 -1
  16. package/dist/create-hooks.d.ts +0 -1
  17. package/dist/hooks/index.d.ts +0 -1
  18. package/dist/index.js +11675 -13715
  19. package/dist/mcp/index.d.ts +0 -4
  20. package/dist/mcp/types.d.ts +0 -1
  21. package/dist/oh-my-opencode.schema.json +1 -45
  22. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
  23. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
  24. package/dist/shared/omo-process-sweep.d.ts +2 -4
  25. package/dist/skills/init-deep/SKILL.md +13 -13
  26. package/dist/skills/ulw-plan/SKILL.md +0 -1
  27. package/dist/tui.js +44809 -44883
  28. package/package.json +16 -18
  29. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +0 -17
  30. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -3
  31. package/packages/omo-codex/plugin/.mcp.json +0 -6
  32. package/packages/omo-codex/plugin/AGENTS.md +5 -5
  33. package/packages/omo-codex/plugin/README.md +1 -1
  34. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1 -15
  35. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  36. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  38. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  39. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  40. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  41. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  42. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  43. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
  44. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  45. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  46. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  47. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  48. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  49. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  50. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +1 -1
  52. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  53. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  54. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +2 -2
  55. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  56. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  57. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +0 -1
  58. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  59. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
  60. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  61. package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -1
  62. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +2 -2
  63. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  64. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  65. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +1 -0
  66. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -0
  67. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +10 -3
  68. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +35 -38
  69. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +278 -193
  70. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +5 -0
  71. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +7 -51
  72. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +39 -22
  73. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  74. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +64 -8
  75. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  76. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +37 -18
  77. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  78. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  79. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -1
  80. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  81. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +6 -0
  82. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +10 -3
  83. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +32 -63
  84. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +7 -53
  85. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +50 -31
  86. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +67 -14
  87. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  88. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +36 -17
  89. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +26 -0
  90. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +47 -2
  91. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  92. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  93. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  94. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  95. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  99. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  115. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  116. package/packages/omo-codex/plugin/package-lock.json +12 -146
  117. package/packages/omo-codex/plugin/package.json +1 -2
  118. package/packages/omo-codex/plugin/scripts/AGENTS.md +0 -1
  119. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +0 -1
  120. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  121. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  122. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  123. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  124. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  125. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
  126. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  127. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +2 -2
  128. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -1
  129. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +0 -1
  130. package/packages/omo-codex/plugin/test/AGENTS.md +2 -2
  131. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +2 -21
  132. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -2
  133. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  134. package/packages/omo-codex/plugin/test/auto-update.test.mjs +0 -25
  135. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  136. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +0 -50
  137. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +0 -1
  138. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  139. package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
  140. package/packages/omo-codex/scripts/install-dist/install-local.mjs +227 -435
  141. package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
  142. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
  143. package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
  144. package/packages/shared-skills/skills/ulw-plan/SKILL.md +0 -1
  145. package/dist/config/schema/codegraph.d.ts +0 -12
  146. package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
  147. package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
  148. package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
  149. package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
  150. package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
  151. package/dist/mcp/codegraph.d.ts +0 -16
  152. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  153. package/packages/omo-codex/plugin/components/codegraph/LICENSE +0 -21
  154. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  155. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  156. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12326
  157. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9908
  158. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  159. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  160. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  161. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  162. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  163. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  164. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  165. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -310
  166. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -92
  167. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  168. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  169. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  170. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  171. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  172. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -22
  173. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  174. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  175. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  176. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  177. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  178. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  179. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  180. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  181. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  182. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  183. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  184. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  185. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  186. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  187. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  188. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  189. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  190. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  191. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  192. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  193. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  194. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  195. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  196. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +0 -47
  197. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  198. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  199. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  200. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  201. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  202. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  203. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  204. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  205. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  206. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  207. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  208. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  209. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +0 -101
  210. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  211. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  212. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  213. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  214. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  215. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  216. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  217. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
@@ -1,76 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { chmodSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { dirname, join, resolve } from "node:path";
5
- import { spawnSync } from "node:child_process";
6
- import { fileURLToPath } from "node:url";
7
-
8
- const componentRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
9
-
10
- describe("built CodeGraph serve wrappers", () => {
11
- it("#given built serve entry #when invoked with a fake CodeGraph binary #then it runs serve mcp exactly once", () => {
12
- // given
13
- const tempRoot = createFakeCodegraphRoot();
14
- try {
15
- // when
16
- const result = runBuiltWrapper("dist/serve.js", tempRoot);
17
-
18
- // then
19
- expect(result.status).toBe(0);
20
- expect(result.stderr).toBe("");
21
- expect(readInvocations(tempRoot)).toEqual(['["serve","--mcp"]']);
22
- } finally {
23
- rmSync(tempRoot, { recursive: true, force: true });
24
- }
25
- });
26
-
27
- it("#given built cli entry #when invoked with a fake CodeGraph binary #then it runs serve mcp exactly once", () => {
28
- // given
29
- const tempRoot = createFakeCodegraphRoot();
30
- try {
31
- // when
32
- const result = runBuiltWrapper("dist/cli.js", tempRoot);
33
-
34
- // then
35
- expect(result.status).toBe(0);
36
- expect(result.stderr).toBe("");
37
- expect(readInvocations(tempRoot)).toEqual(['["serve","--mcp"]']);
38
- } finally {
39
- rmSync(tempRoot, { recursive: true, force: true });
40
- }
41
- });
42
- });
43
-
44
- function createFakeCodegraphRoot(): string {
45
- const tempRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-wrapper-"));
46
- const fakeBinaryPath = join(tempRoot, "codegraph-fake.cjs");
47
- writeFileSync(
48
- fakeBinaryPath,
49
- [
50
- "#!/usr/bin/env node",
51
- "const fs = require('node:fs');",
52
- "fs.appendFileSync(process.env.CODEGRAPH_FAKE_LOG, JSON.stringify(process.argv.slice(2)) + '\\n');",
53
- "",
54
- ].join("\n"),
55
- );
56
- chmodSync(fakeBinaryPath, 0o755);
57
- return tempRoot;
58
- }
59
-
60
- function runBuiltWrapper(entryPath: string, tempRoot: string): ReturnType<typeof spawnSync> {
61
- return spawnSync(process.execPath, [join(componentRoot, entryPath)], {
62
- cwd: componentRoot,
63
- encoding: "utf8",
64
- env: {
65
- ...process.env,
66
- CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
67
- CODEGRAPH_FAKE_LOG: join(tempRoot, "invocations.log"),
68
- OMO_CODEGRAPH_BIN: join(tempRoot, "codegraph-fake.cjs"),
69
- },
70
- timeout: 5000,
71
- });
72
- }
73
-
74
- function readInvocations(tempRoot: string): readonly string[] {
75
- return readFileSync(join(tempRoot, "invocations.log"), "utf8").trim().split("\n");
76
- }
@@ -1,133 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { PassThrough, Writable } from "node:stream";
5
- import { fileURLToPath } from "node:url";
6
-
7
- import { isProcessAlive } from "../../../../../mcp-stdio-core/src/index.ts";
8
- import { runCodegraphServe } from "../src/serve.ts";
9
- import {
10
- frameMcpRequest,
11
- writeFakeExitingCodegraph,
12
- writeFakeHeldOpenCodegraph,
13
- } from "./mcp-bridge-fixtures.ts";
14
-
15
- const componentRoot = realpathSync(
16
- fileURLToPath(new URL("..", import.meta.url)),
17
- );
18
-
19
- describe("runCodegraphServe MCP bridge lifecycle", () => {
20
- it("#given an exiting Codegraph child and delayed closed parent output #when the final response write fails #then the output error is preserved", async () => {
21
- const tempRoot = mkdtempSync(
22
- join(componentRoot, ".tmp-codegraph-exit-output-failure-"),
23
- );
24
- const projectRoot = join(tempRoot, "project");
25
- const fakeCodegraph = join(tempRoot, "codegraph-exiting.cjs");
26
- const input = new PassThrough();
27
- const outputError = Object.assign(
28
- new Error("parent output closed after child exit"),
29
- { code: "EPIPE" },
30
- );
31
- const writeStarted = Promise.withResolvers<void>();
32
- const output = new Writable({
33
- write(_chunk, _encoding, callback) {
34
- writeStarted.resolve();
35
- setTimeout(() => callback(outputError), 150);
36
- },
37
- });
38
-
39
- try {
40
- mkdirSync(projectRoot, { recursive: true });
41
- writeFakeExitingCodegraph(fakeCodegraph);
42
- const run = runCodegraphServe({
43
- cwd: tempRoot,
44
- env: {
45
- CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
46
- OMO_CODEGRAPH_BIN: fakeCodegraph,
47
- OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
48
- PATH: process.env["PATH"],
49
- },
50
- nodeVersion: "22.14.0",
51
- buildEnv: () => ({}),
52
- resolve: () => ({
53
- argsPrefix: [],
54
- command: fakeCodegraph,
55
- exists: true,
56
- source: "env",
57
- }),
58
- stderr: { write: () => undefined },
59
- stdin: input,
60
- stdout: output,
61
- });
62
-
63
- input.end(frameMcpRequest({ id: 1, method: "tools/list", params: {} }));
64
-
65
- await writeStarted.promise;
66
- await expect(run).rejects.toBe(outputError);
67
- } finally {
68
- rmSync(tempRoot, { recursive: true, force: true });
69
- }
70
- });
71
-
72
- it("#given a held-open Codegraph child and a dead parent #when the bridge watchdog polls #then the child is terminated and the bridge settles through the child-exit path", async () => {
73
- // given
74
- const tempRoot = mkdtempSync(
75
- join(componentRoot, ".tmp-codegraph-orphan-"),
76
- );
77
- const projectRoot = join(tempRoot, "project");
78
- const fakeCodegraph = join(tempRoot, "codegraph-held-open.cjs");
79
- const childPidFile = join(tempRoot, "child.pid");
80
- // Client stdio is held open and never sees EOF, so the parent-liveness
81
- // watchdog is the only settle path. The probe reports the parent alive
82
- // until the child has started, making the poll fire deterministically.
83
- const input = new PassThrough();
84
- const output = new PassThrough();
85
- output.resume();
86
- let childPid: number | undefined;
87
-
88
- try {
89
- mkdirSync(projectRoot, { recursive: true });
90
- writeFakeHeldOpenCodegraph(fakeCodegraph);
91
- const run = runCodegraphServe({
92
- cwd: tempRoot,
93
- env: {
94
- CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
95
- CODEGRAPH_FAKE_LOG: childPidFile,
96
- OMO_CODEGRAPH_BIN: fakeCodegraph,
97
- OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
98
- PATH: process.env["PATH"],
99
- },
100
- nodeVersion: "22.14.0",
101
- buildEnv: () => ({}),
102
- resolve: () => ({
103
- argsPrefix: [],
104
- command: fakeCodegraph,
105
- exists: true,
106
- source: "env",
107
- }),
108
- stderr: { write: () => undefined },
109
- stdin: input,
110
- stdout: output,
111
- parentWatchdog: {
112
- pollIntervalMs: 10,
113
- probeAlive: () => !existsSync(childPidFile),
114
- },
115
- });
116
-
117
- // when
118
- const exitCode = await run;
119
-
120
- // then
121
- expect(exitCode).not.toBe(0);
122
- childPid = Number(readFileSync(childPidFile, "utf8"));
123
- expect(isProcessAlive(childPid)).toBe(false);
124
- } finally {
125
- if (childPid !== undefined && isProcessAlive(childPid)) {
126
- process.kill(childPid, "SIGKILL");
127
- }
128
- input.destroy();
129
- output.destroy();
130
- rmSync(tempRoot, { recursive: true, force: true });
131
- }
132
- });
133
- });
@@ -1,245 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { PassThrough, Writable } from "node:stream";
5
- import { fileURLToPath } from "node:url";
6
-
7
- import { runCodegraphServe } from "../src/serve.ts";
8
- import {
9
- arrayProperty,
10
- CODEGRAPH_150_DEFAULT_TOOLS,
11
- findTool,
12
- frameMcpRequest,
13
- parseMcpBodies,
14
- recordProperty,
15
- recordValue,
16
- stringProperty,
17
- writeFakeContractCodegraph,
18
- writeFakeHeldOpenCodegraph,
19
- writeFakeNewlineCodegraph,
20
- } from "./mcp-bridge-fixtures.ts";
21
-
22
- const componentRoot = realpathSync(fileURLToPath(new URL("..", import.meta.url)));
23
-
24
- describe("runCodegraphServe MCP protocol bridge", () => {
25
- it("#given Codex framed stdio and a newline-json CodeGraph child #when listing tools #then it bridges frames and serves from the project cwd", async () => {
26
- // given
27
- const tempRoot = mkdtempSync(join(componentRoot, ".tmp-codegraph-bridge-"));
28
- const projectRoot = join(tempRoot, "project");
29
- const pluginCacheRoot = join(tempRoot, "plugin-cache");
30
- const fakeCodegraph = join(tempRoot, "codegraph-fake.cjs");
31
- const childLog = join(tempRoot, "child.log");
32
- const input = new PassThrough();
33
- const output = new PassThrough();
34
- let stdout = "";
35
- output.on("data", (chunk: Buffer) => {
36
- stdout += chunk.toString("utf8");
37
- });
38
-
39
- try {
40
- mkdirSync(projectRoot, { recursive: true });
41
- mkdirSync(pluginCacheRoot, { recursive: true });
42
- writeFakeNewlineCodegraph(fakeCodegraph);
43
-
44
- const run = runCodegraphServe({
45
- cwd: pluginCacheRoot,
46
- env: {
47
- CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
48
- CODEGRAPH_FAKE_LOG: childLog,
49
- OMO_CODEGRAPH_BIN: fakeCodegraph,
50
- OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
51
- PATH: process.env["PATH"],
52
- },
53
- nodeVersion: "22.14.0",
54
- buildEnv: () => ({}),
55
- resolve: () => ({ argsPrefix: [], command: fakeCodegraph, exists: true, source: "env" }),
56
- stderr: { write: () => undefined },
57
- stdin: input,
58
- stdout: output,
59
- });
60
-
61
- // when
62
- input.end([
63
- frameMcpRequest({
64
- id: 1,
65
- method: "initialize",
66
- params: {
67
- capabilities: {},
68
- clientInfo: { name: "codex", version: "0.141.0" },
69
- protocolVersion: "2025-06-18",
70
- },
71
- }),
72
- frameMcpRequest({
73
- id: 2,
74
- method: "tools/list",
75
- params: {},
76
- }),
77
- ].join(""));
78
- const exitCode = await run;
79
-
80
- // then
81
- expect(exitCode).toBe(0);
82
- const bodies = parseMcpBodies(stdout);
83
- expect(bodies).toEqual([
84
- {
85
- id: 1,
86
- jsonrpc: "2.0",
87
- result: {
88
- capabilities: { tools: { listChanged: false } },
89
- protocolVersion: "2025-06-18",
90
- serverInfo: { name: "codegraph", version: "1.5.0" },
91
- },
92
- },
93
- {
94
- id: 2,
95
- jsonrpc: "2.0",
96
- result: {
97
- tools: CODEGRAPH_150_DEFAULT_TOOLS,
98
- },
99
- },
100
- ]);
101
- expect(readFileSync(childLog, "utf8")).toContain(`cwd=${realpathSync(projectRoot)}`);
102
- } finally {
103
- rmSync(tempRoot, { recursive: true, force: true });
104
- }
105
- });
106
-
107
- it("#given old upstream codegraph_node metadata and container outline guidance #when bridging #then it exposes the corrected LazyCodex contract", async () => {
108
- // given
109
- const tempRoot = mkdtempSync(join(componentRoot, ".tmp-codegraph-contract-"));
110
- const projectRoot = join(tempRoot, "project");
111
- const fakeCodegraph = join(tempRoot, "codegraph-contract-fake.cjs");
112
- const childLog = join(tempRoot, "child.log");
113
- const input = new PassThrough();
114
- const output = new PassThrough();
115
- let stdout = "";
116
- output.on("data", (chunk: Buffer) => {
117
- stdout += chunk.toString("utf8");
118
- });
119
-
120
- try {
121
- mkdirSync(projectRoot, { recursive: true });
122
- writeFakeContractCodegraph(fakeCodegraph);
123
-
124
- const run = runCodegraphServe({
125
- cwd: tempRoot,
126
- env: {
127
- CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
128
- CODEGRAPH_FAKE_LOG: childLog,
129
- OMO_CODEGRAPH_BIN: fakeCodegraph,
130
- OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
131
- PATH: process.env["PATH"],
132
- },
133
- nodeVersion: "22.14.0",
134
- buildEnv: () => ({}),
135
- resolve: () => ({ argsPrefix: [], command: fakeCodegraph, exists: true, source: "env" }),
136
- stderr: { write: () => undefined },
137
- stdin: input,
138
- stdout: output,
139
- });
140
-
141
- // when
142
- input.end([
143
- frameMcpRequest({
144
- id: 1,
145
- method: "tools/list",
146
- params: {},
147
- }),
148
- frameMcpRequest({
149
- id: 2,
150
- method: "tools/call",
151
- params: {
152
- arguments: { includeCode: true, symbol: "JsonlMCP" },
153
- name: "codegraph_node",
154
- },
155
- }),
156
- ].join(""));
157
- const exitCode = await run;
158
-
159
- // then
160
- expect(exitCode).toBe(0);
161
- const bodies = parseMcpBodies(stdout);
162
- const tools = arrayProperty(recordProperty(recordValue(bodies[0]), "result"), "tools");
163
- const nodeTool = findTool(tools, "codegraph_node");
164
- const searchTool = findTool(tools, "codegraph_search");
165
- expect(stringProperty(nodeTool, "description")).toContain("Container symbols");
166
- expect(stringProperty(nodeTool, "description")).toContain("file mode");
167
- expect(stringProperty(nodeTool, "description")).not.toContain("verbatim source");
168
- expect(stringProperty(nodeTool, "description")).not.toContain("full body");
169
- expect(
170
- stringProperty(
171
- recordProperty(recordProperty(recordProperty(nodeTool, "inputSchema"), "properties"), "includeCode"),
172
- "description",
173
- ),
174
- ).toBe(
175
- "Symbol mode: include leaf-symbol source when available. Container symbols such as classes, interfaces, structs, enums, modules, and namespaces intentionally return structural outlines with members; request a specific member symbol or use file mode with symbolsOnly=false plus offset/limit for source.",
176
- );
177
- expect(searchTool).toEqual({ description: "search stays unchanged", name: "codegraph_search" });
178
-
179
- const callResult = recordProperty(recordValue(bodies[1]), "result");
180
- const text = stringProperty(recordValue(arrayProperty(callResult, "content")[0]), "text");
181
- expect(text).toContain("Container symbols intentionally return structural outlines");
182
- expect(text).toContain("specific member symbol");
183
- expect(text).toContain("file mode");
184
- expect(text).toContain("symbolsOnly=false");
185
- expect(text).not.toContain("Read tool");
186
- } finally {
187
- rmSync(tempRoot, { recursive: true, force: true });
188
- }
189
- });
190
-
191
- it("#given a held-open Codegraph child and closed parent output #when response forwarding fails #then the child is terminated before rejection", async () => {
192
- const tempRoot = mkdtempSync(join(componentRoot, ".tmp-codegraph-output-failure-"));
193
- const projectRoot = join(tempRoot, "project");
194
- const fakeCodegraph = join(tempRoot, "codegraph-held-open.cjs");
195
- const childPidFile = join(tempRoot, "child.pid");
196
- const input = new PassThrough();
197
- const outputError = Object.assign(new Error("parent output closed"), { code: "EPIPE" });
198
- const output = new Writable({
199
- write(_chunk, _encoding, callback) {
200
- callback(outputError);
201
- },
202
- });
203
- let childPid: number | undefined;
204
-
205
- try {
206
- mkdirSync(projectRoot, { recursive: true });
207
- writeFakeHeldOpenCodegraph(fakeCodegraph);
208
- const run = runCodegraphServe({
209
- cwd: tempRoot,
210
- env: {
211
- CODEGRAPH_ALLOW_UNSAFE_NODE: "1",
212
- CODEGRAPH_FAKE_LOG: childPidFile,
213
- OMO_CODEGRAPH_BIN: fakeCodegraph,
214
- OMO_CODEGRAPH_PROJECT_CWD: projectRoot,
215
- PATH: process.env["PATH"],
216
- },
217
- nodeVersion: "22.14.0",
218
- buildEnv: () => ({}),
219
- resolve: () => ({ argsPrefix: [], command: fakeCodegraph, exists: true, source: "env" }),
220
- stderr: { write: () => undefined },
221
- stdin: input,
222
- stdout: output,
223
- });
224
-
225
- input.end(frameMcpRequest({ id: 1, method: "tools/list", params: {} }));
226
-
227
- await expect(run).rejects.toBe(outputError);
228
- childPid = Number(readFileSync(childPidFile, "utf8"));
229
- expect(isProcessAlive(childPid)).toBe(false);
230
- } finally {
231
- if (childPid !== undefined && isProcessAlive(childPid)) process.kill(childPid, "SIGKILL");
232
- rmSync(tempRoot, { recursive: true, force: true });
233
- }
234
- });
235
- });
236
-
237
- function isProcessAlive(pid: number): boolean {
238
- try {
239
- process.kill(pid, 0);
240
- return true;
241
- } catch (error) {
242
- if (error instanceof Error && "code" in error && error.code === "ESRCH") return false;
243
- throw error;
244
- }
245
- }
@@ -1,69 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { PassThrough } from "node:stream";
3
-
4
- import { runCodegraphServe } from "../src/serve.ts";
5
-
6
- describe("runCodegraphServe MCP unavailable facade", () => {
7
- it("#given CodeGraph is unavailable #when an MCP client initializes #then it answers with an empty-tool facade", async () => {
8
- // given
9
- const input = new PassThrough();
10
- const output = new PassThrough();
11
- const stderr: string[] = [];
12
- let stdout = "";
13
- output.on("data", (chunk: Buffer) => {
14
- stdout += chunk.toString("utf8");
15
- });
16
-
17
- const run = runCodegraphServe({
18
- config: { codegraph: { auto_provision: false, enabled: true }, sources: [], warnings: [] },
19
- env: { PATH: "/bin" },
20
- nodeVersion: "22.14.0",
21
- buildEnv: () => ({}),
22
- resolve: () => ({ argsPrefix: [], command: "codegraph", exists: false, source: "path" }),
23
- stderr: { write: (chunk: string) => stderr.push(chunk) },
24
- stdin: input,
25
- stdout: output,
26
- });
27
-
28
- // when
29
- input.end(frameMcpRequest({
30
- id: 1,
31
- method: "initialize",
32
- params: {
33
- capabilities: {},
34
- clientInfo: { name: "ulw-red", version: "0.0.0" },
35
- protocolVersion: "2025-06-18",
36
- },
37
- }));
38
- const exitCode = await run;
39
-
40
- // then
41
- expect(exitCode).toBe(0);
42
- expect(stderr).toEqual([
43
- "CodeGraph MCP skipped: codegraph binary not found. Install CodeGraph or set OMO_CODEGRAPH_BIN.\n",
44
- ]);
45
- expect(parseFirstJsonRpcBody(stdout)).toEqual({
46
- id: 1,
47
- jsonrpc: "2.0",
48
- result: {
49
- capabilities: { tools: { listChanged: false } },
50
- protocolVersion: "2025-06-18",
51
- serverInfo: { name: "codegraph", version: "1.5.0" },
52
- },
53
- });
54
- });
55
- });
56
-
57
- function frameMcpRequest(request: {
58
- readonly id: number;
59
- readonly method: string;
60
- readonly params: Record<string, unknown>;
61
- }): string {
62
- const body = JSON.stringify({ jsonrpc: "2.0", ...request });
63
- return `Content-Length: ${Buffer.byteLength(body)}\r\n\r\n${body}`;
64
- }
65
-
66
- function parseFirstJsonRpcBody(transcript: string): unknown {
67
- const [, body = ""] = transcript.split("\r\n\r\n", 2);
68
- return JSON.parse(body);
69
- }
@@ -1,43 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { PassThrough } from "node:stream";
3
-
4
- import { CODEGRAPH_UNSAFE_NODE_ENV } from "../../../../../utils/src/codegraph/node-support.ts";
5
- import { runCodegraphServe } from "../src/serve.ts";
6
-
7
- describe("runCodegraphServe node support", () => {
8
- it("#given Node is too new and no command resolves #when serving MCP #then the unsupported-node hint wins", async () => {
9
- // given
10
- const stderr: string[] = [];
11
- const spawned: string[] = [];
12
-
13
- // when
14
- const exitCode = await runCodegraphServe({
15
- ...closedMcpStdio(),
16
- env: { PATH: "/bin" },
17
- nodeVersion: "26.3.0",
18
- buildEnv: () => ({}),
19
- resolve: () => ({ argsPrefix: [], command: "codegraph", exists: false, source: "path" }),
20
- runProcess: (command: string) => {
21
- spawned.push(command);
22
- return Promise.resolve(0);
23
- },
24
- stderr: { write: (chunk: string) => stderr.push(chunk) },
25
- });
26
-
27
- // then
28
- expect(exitCode).toBe(0);
29
- expect(spawned).toEqual([]);
30
- expect(stderr).toHaveLength(1);
31
- expect(stderr[0]).toContain("CodeGraph MCP skipped");
32
- expect(stderr[0]).toContain("Node 26 is unsupported");
33
- expect(stderr[0]).toContain(CODEGRAPH_UNSAFE_NODE_ENV);
34
- });
35
- });
36
-
37
- function closedMcpStdio(): { readonly stdin: PassThrough; readonly stdout: PassThrough } {
38
- const stdin = new PassThrough();
39
- const stdout = new PassThrough();
40
- stdout.resume();
41
- stdin.end();
42
- return { stdin, stdout };
43
- }