lazycodex-ai 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 (187) hide show
  1. package/README.ja.md +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/README.ru.md +1 -1
  5. package/README.zh-cn.md +1 -1
  6. package/dist/cli/index.js +48342 -48539
  7. package/dist/cli-node/index.js +49017 -49214
  8. package/package.json +2 -4
  9. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -3
  10. package/packages/omo-codex/plugin/.mcp.json +0 -6
  11. package/packages/omo-codex/plugin/AGENTS.md +5 -5
  12. package/packages/omo-codex/plugin/README.md +1 -1
  13. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1 -15
  14. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  15. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  16. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  17. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  18. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  19. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  20. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  21. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  22. package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
  23. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  24. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  25. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  27. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +1 -1
  31. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  32. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  33. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +2 -2
  34. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  35. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  36. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +0 -1
  37. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  38. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
  39. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  40. package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -1
  41. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +2 -2
  42. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
  43. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
  44. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +1 -0
  45. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -0
  46. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +10 -3
  47. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +35 -38
  48. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +278 -193
  49. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +5 -0
  50. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +7 -51
  51. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +39 -22
  52. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
  53. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +64 -8
  54. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
  55. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +37 -18
  56. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  57. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  58. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -1
  59. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
  60. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +6 -0
  61. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +10 -3
  62. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +32 -63
  63. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +7 -53
  64. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +50 -31
  65. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +67 -14
  66. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
  67. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +36 -17
  68. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +26 -0
  69. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +47 -2
  70. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
  71. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
  72. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
  73. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
  74. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  84. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  85. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  87. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  88. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  89. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  90. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
  91. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  92. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  93. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  94. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  95. package/packages/omo-codex/plugin/package-lock.json +12 -146
  96. package/packages/omo-codex/plugin/package.json +1 -2
  97. package/packages/omo-codex/plugin/scripts/AGENTS.md +0 -1
  98. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +0 -1
  99. package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
  100. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
  101. package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
  102. package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
  103. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
  104. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
  105. package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
  106. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +2 -2
  107. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -1
  108. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +0 -1
  109. package/packages/omo-codex/plugin/test/AGENTS.md +2 -2
  110. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +2 -21
  111. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -2
  112. package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
  113. package/packages/omo-codex/plugin/test/auto-update.test.mjs +0 -25
  114. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
  115. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +0 -50
  116. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +0 -1
  117. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
  118. package/packages/omo-codex/scripts/install-dist/install-local.mjs +227 -435
  119. package/packages/prompts-core/prompts/ultrawork/codex.md +2 -2
  120. package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
  121. package/packages/shared-skills/skills/ulw-plan/SKILL.md +0 -1
  122. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
  123. package/packages/omo-codex/plugin/components/codegraph/LICENSE +0 -21
  124. package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
  125. package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
  126. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12326
  127. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9908
  128. package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
  129. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
  130. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
  131. package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
  132. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
  133. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
  134. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
  135. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -310
  136. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -92
  137. package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
  138. package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
  139. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
  140. package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
  141. package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
  142. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -22
  143. package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
  144. package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
  145. package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
  146. package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
  147. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
  148. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
  149. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
  150. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
  151. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
  152. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
  153. package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
  154. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
  155. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
  156. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
  157. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
  158. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
  159. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
  160. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
  161. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
  162. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
  163. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
  164. package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
  165. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
  166. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +0 -47
  167. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
  168. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
  169. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
  170. package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
  171. package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
  172. package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
  173. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
  174. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
  175. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
  176. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
  177. package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
  178. package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
  179. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +0 -101
  180. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
  181. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
  182. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
  183. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
  184. package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
  185. package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
  186. package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
  187. package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
@@ -1,104 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { mkdtempSync, rmSync, utimesSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
-
6
- import {
7
- clearSessionStartCooldown,
8
- readSessionStartCooldown,
9
- recordSessionStartFailure,
10
- } from "../src/session-start-cooldown.ts";
11
- import {
12
- acquireSessionStartLock,
13
- releaseSessionStartLock,
14
- } from "../src/session-start-lock.ts";
15
-
16
- describe("CodeGraph SessionStart lock", () => {
17
- it("#given a live project lock #when a second hook acquires it #then the second hook is deduplicated", () => {
18
- // given
19
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-lock-home-"));
20
- const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-lock-project-"));
21
- try {
22
- const first = acquireSessionStartLock({ homeDir, nowMs: 10_000, projectRoot, staleMs: 60_000 });
23
- expect(first.kind).toBe("acquired");
24
-
25
- // when
26
- const second = acquireSessionStartLock({ homeDir, nowMs: 10_001, projectRoot, staleMs: 60_000 });
27
-
28
- // then
29
- expect(second).toEqual({ kind: "locked" });
30
- if (first.kind === "acquired") releaseSessionStartLock(first.lock);
31
- } finally {
32
- rmSync(homeDir, { recursive: true, force: true });
33
- rmSync(projectRoot, { recursive: true, force: true });
34
- }
35
- });
36
-
37
- it("#given a project lock older than the stale threshold #when another hook acquires it #then the stale lock is recovered", () => {
38
- // given
39
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-stale-home-"));
40
- const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-stale-project-"));
41
- try {
42
- const first = acquireSessionStartLock({ homeDir, nowMs: 1_000, projectRoot, staleMs: 500 });
43
- expect(first.kind).toBe("acquired");
44
- if (first.kind !== "acquired") return;
45
- const staleDate = new Date(1_000);
46
- utimesSync(first.lock.path, staleDate, staleDate);
47
-
48
- // when
49
- const second = acquireSessionStartLock({ homeDir, nowMs: 2_000, projectRoot, staleMs: 500 });
50
-
51
- // then
52
- expect(second.kind).toBe("acquired");
53
- if (second.kind === "acquired") {
54
- expect(second.recoveredStale).toBe(true);
55
- releaseSessionStartLock(second.lock);
56
- }
57
- } finally {
58
- rmSync(homeDir, { recursive: true, force: true });
59
- rmSync(projectRoot, { recursive: true, force: true });
60
- }
61
- });
62
- });
63
-
64
- describe("CodeGraph SessionStart cooldown", () => {
65
- it("#given a failed worker outcome #when the cooldown is checked #then retries are suppressed until expiry and the next failure backs off", () => {
66
- // given
67
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-cooldown-home-"));
68
- const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-cooldown-project-"));
69
- try {
70
- const first = recordSessionStartFailure({
71
- action: "failed",
72
- baseCooldownMs: 1_000,
73
- homeDir,
74
- nowMs: 1_000,
75
- projectRoot,
76
- });
77
-
78
- // when
79
- const active = readSessionStartCooldown({ baseCooldownMs: 1_000, homeDir, nowMs: 1_999, projectRoot });
80
- const expired = readSessionStartCooldown({ baseCooldownMs: 1_000, homeDir, nowMs: 2_000, projectRoot });
81
- const second = recordSessionStartFailure({
82
- action: "skipped-status",
83
- baseCooldownMs: 1_000,
84
- homeDir,
85
- nowMs: 2_000,
86
- projectRoot,
87
- });
88
-
89
- // then
90
- expect(first).toMatchObject({ cooldownUntil: 2_000, failureCount: 1 });
91
- expect(active).toMatchObject({ cooldownUntil: 2_000, failureCount: 1, kind: "active" });
92
- expect(expired).toEqual({ failureCount: 1, kind: "inactive" });
93
- expect(second).toMatchObject({ cooldownUntil: 4_000, failureCount: 2 });
94
- clearSessionStartCooldown({ homeDir, projectRoot });
95
- expect(readSessionStartCooldown({ baseCooldownMs: 1_000, homeDir, nowMs: 2_001, projectRoot })).toEqual({
96
- failureCount: 0,
97
- kind: "inactive",
98
- });
99
- } finally {
100
- rmSync(homeDir, { recursive: true, force: true });
101
- rmSync(projectRoot, { recursive: true, force: true });
102
- }
103
- });
104
- });
@@ -1,65 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
-
6
- import { runCodegraphSessionStartWorker } from "../src/hook.ts";
7
-
8
- describe("CodeGraph SessionStart trust boundary", () => {
9
- it("#given project config sets install_dir #when worker provisions CodeGraph #then it uses the trusted home install root", async () => {
10
- // given
11
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-untrusted-project-"));
12
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-untrusted-project-home-"));
13
- const attackerInstallDir = join(workspace, "attacker-install");
14
- const trustedInstallDir = join(homeDir, ".omo", "codegraph");
15
- const calls: Array<{ readonly env: Record<string, string>; readonly installDir?: string; readonly lockDir?: string }> = [];
16
- try {
17
- mkdirSync(join(workspace, ".omo"), { recursive: true });
18
- writeFileSync(join(workspace, ".omo", "omo.jsonc"), JSON.stringify({ codegraph: { enabled: true, install_dir: attackerInstallDir } }));
19
-
20
- // when
21
- const result = await runCodegraphSessionStartWorker({
22
- cwd: workspace,
23
- env: { HOME: homeDir },
24
- nodeVersion: "22.14.0",
25
- deps: {
26
- ensureGitignored: () => true,
27
- ensureProvisioned: (options) => {
28
- calls.push({
29
- env: {},
30
- ...(options.installDir === undefined ? {} : { installDir: options.installDir }),
31
- ...(options.lockDir === undefined ? {} : { lockDir: options.lockDir }),
32
- });
33
- return Promise.resolve({ binPath: join(trustedInstallDir, "bin", "codegraph"), provisioned: true });
34
- },
35
- prepareWorkspace: () => ({
36
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
37
- dataRoot: join(homeDir, ".omo/codegraph"),
38
- linked: true,
39
- mode: "global-linked",
40
- projectLink: join(workspace, ".codegraph"),
41
- }),
42
- resolveCommand: (options) => {
43
- expect(options?.provisioned?.()).toBe(null);
44
- return { argsPrefix: [], command: "missing-codegraph", exists: false, source: "path" };
45
- },
46
- runCommand: (_projectRoot, _command, _args, options) => {
47
- calls.push({ env: options.env });
48
- mkdirSync(join(workspace, ".codegraph"), { recursive: true });
49
- writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
50
- return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
51
- },
52
- },
53
- });
54
-
55
- // then
56
- expect(result).toEqual({ action: "initialized" });
57
- expect(calls[0]).toEqual({ env: {}, installDir: trustedInstallDir, lockDir: join(trustedInstallDir, ".locks") });
58
- expect(calls[1]?.env["CODEGRAPH_INSTALL_DIR"]).toBe(trustedInstallDir);
59
- expect(calls[1]?.env["CODEGRAPH_INSTALL_DIR"]).not.toBe(attackerInstallDir);
60
- } finally {
61
- rmSync(workspace, { recursive: true, force: true });
62
- rmSync(homeDir, { recursive: true, force: true });
63
- }
64
- });
65
- });
@@ -1,106 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { existsSync, mkdtempSync, rmSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
-
6
- import { runCodegraphSessionStartWorker } from "../src/hook.ts";
7
-
8
- describe("CodeGraph SessionStart worker availability", () => {
9
- it("#given CodeGraph cannot be resolved or provisioned #when worker runs #then it logs a graceful skip", async () => {
10
- // given
11
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-"));
12
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-home-"));
13
- const outcomes: unknown[] = [];
14
- const calls: string[] = [];
15
-
16
- try {
17
- // when
18
- const result = await runCodegraphSessionStartWorker({
19
- cwd: workspace,
20
- env: { HOME: homeDir },
21
- nodeVersion: "22.14.0",
22
- logOutcome: (outcome) => outcomes.push(outcome),
23
- deps: {
24
- ensureGitignored: () => {
25
- calls.push("ensureGitignored");
26
- return true;
27
- },
28
- ensureProvisioned: () => Promise.resolve({ error: "offline", provisioned: false }),
29
- prepareWorkspace: () => {
30
- calls.push("prepareWorkspace");
31
- return {
32
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
33
- dataRoot: join(homeDir, ".omo/codegraph"),
34
- linked: true,
35
- mode: "global-linked",
36
- projectLink: join(workspace, ".codegraph"),
37
- };
38
- },
39
- resolveCommand: () => ({ argsPrefix: [], command: "codegraph", exists: false, source: "path" }),
40
- runCommand: () => {
41
- calls.push("runCommand");
42
- return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
43
- },
44
- },
45
- });
46
-
47
- // then
48
- expect(result).toEqual({ action: "skipped-unavailable" });
49
- expect(calls).toEqual([]);
50
- expect(outcomes).toEqual([
51
- {
52
- action: "skipped-unavailable",
53
- error: "offline",
54
- projectRoot: workspace,
55
- source: "path",
56
- },
57
- ]);
58
- } finally {
59
- rmSync(workspace, { recursive: true, force: true });
60
- rmSync(homeDir, { recursive: true, force: true });
61
- }
62
- });
63
-
64
- it("#given CodeGraph is unavailable and auto provisioning is disabled #when worker runs #then it leaves the project untouched", async () => {
65
- // given
66
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-unavailable-"));
67
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-unavailable-home-"));
68
- const outcomes: unknown[] = [];
69
-
70
- try {
71
- // when
72
- const result = await runCodegraphSessionStartWorker({
73
- config: { codegraph: { auto_provision: false, enabled: true }, sources: [], warnings: [] },
74
- nodeVersion: "22.14.0",
75
- cwd: workspace,
76
- env: { HOME: homeDir },
77
- logOutcome: (outcome) => outcomes.push(outcome),
78
- deps: {
79
- ensureProvisioned: () => {
80
- throw new Error("auto provision should not run");
81
- },
82
- resolveCommand: () => ({ argsPrefix: [], command: "missing-codegraph", exists: false, source: "path" }),
83
- runCommand: () => {
84
- throw new Error("codegraph command should not run");
85
- },
86
- },
87
- });
88
-
89
- // then
90
- expect(result).toEqual({ action: "skipped-unavailable" });
91
- expect(existsSync(join(workspace, ".codegraph"))).toBe(false);
92
- expect(existsSync(join(workspace, ".git", "info", "exclude"))).toBe(false);
93
- expect(outcomes).toEqual([
94
- {
95
- action: "skipped-unavailable",
96
- error: "codegraph binary unavailable and auto_provision is disabled",
97
- projectRoot: workspace,
98
- source: "path",
99
- },
100
- ]);
101
- } finally {
102
- rmSync(workspace, { recursive: true, force: true });
103
- rmSync(homeDir, { recursive: true, force: true });
104
- }
105
- });
106
- });
@@ -1,116 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { mkdtempSync, rmSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
-
6
- import type { CodegraphSessionStartOutcome } from "../src/hook.ts";
7
- import { runCodegraphSessionStartWorker } from "../src/hook.ts";
8
- import { readSessionStartCooldown } from "../src/session-start-cooldown.ts";
9
-
10
- describe("CodeGraph SessionStart worker cooldown", () => {
11
- it("#given codegraph init times out #when the worker finishes #then it records a failed outcome and cooldown", async () => {
12
- // given
13
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-timeout-"));
14
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-timeout-home-"));
15
- const outcomes: CodegraphSessionStartOutcome[] = [];
16
- try {
17
- // when
18
- const result = await runCodegraphSessionStartWorker({
19
- config: { codegraph: { enabled: true, session_start_cooldown_ms: 60_000 }, sources: [], warnings: [] },
20
- cwd: workspace,
21
- env: { HOME: homeDir },
22
- logOutcome: (outcome) => outcomes.push(outcome),
23
- nodeVersion: "22.14.0",
24
- nowMs: 1_000,
25
- projectProbe: () => ({ kind: "uninitialized" }),
26
- deps: {
27
- ensureGitignored: () => true,
28
- ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
29
- prepareWorkspace: () => ({
30
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
31
- dataRoot: join(homeDir, ".omo/codegraph"),
32
- linked: true,
33
- mode: "global-linked",
34
- projectLink: join(workspace, ".codegraph"),
35
- }),
36
- resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
37
- runCommand: () => Promise.resolve({ exitCode: 1, stdout: "", timedOut: true }),
38
- },
39
- });
40
- const cooldown = readSessionStartCooldown({
41
- baseCooldownMs: 60_000,
42
- homeDir,
43
- nowMs: 2_000,
44
- projectRoot: workspace,
45
- });
46
-
47
- // then
48
- expect(result).toEqual({ action: "failed" });
49
- expect(outcomes).toEqual([{
50
- action: "failed",
51
- error: "codegraph init timed out",
52
- exitCode: 1,
53
- projectRoot: workspace,
54
- source: "path",
55
- timedOut: true,
56
- }]);
57
- expect(cooldown).toEqual({ cooldownUntil: 61_000, failureCount: 1, kind: "active" });
58
- } finally {
59
- rmSync(homeDir, { recursive: true, force: true });
60
- rmSync(workspace, { recursive: true, force: true });
61
- }
62
- });
63
-
64
- it("#given codegraph init exits zero without an exact database #when the worker verifies the result #then it records a failure cooldown", async () => {
65
- // given
66
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-no-db-"));
67
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-no-db-home-"));
68
- const outcomes: CodegraphSessionStartOutcome[] = [];
69
- try {
70
- // when
71
- const result = await runCodegraphSessionStartWorker({
72
- config: { codegraph: { enabled: true, session_start_cooldown_ms: 60_000 }, sources: [], warnings: [] },
73
- cwd: workspace,
74
- env: { HOME: homeDir },
75
- logOutcome: (outcome) => outcomes.push(outcome),
76
- nodeVersion: "22.14.0",
77
- nowMs: 1_000,
78
- projectProbe: () => ({ kind: "uninitialized" }),
79
- deps: {
80
- ensureGitignored: () => true,
81
- ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
82
- prepareWorkspace: () => ({
83
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
84
- dataRoot: join(homeDir, ".omo/codegraph"),
85
- linked: true,
86
- mode: "global-linked",
87
- projectLink: join(workspace, ".codegraph"),
88
- }),
89
- resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
90
- runCommand: () => Promise.resolve({ exitCode: 0, stdout: "", timedOut: false }),
91
- },
92
- });
93
- const cooldown = readSessionStartCooldown({
94
- baseCooldownMs: 60_000,
95
- homeDir,
96
- nowMs: 2_000,
97
- projectRoot: workspace,
98
- });
99
-
100
- // then
101
- expect(result).toEqual({ action: "failed" });
102
- expect(outcomes).toEqual([{
103
- action: "failed",
104
- error: "codegraph init completed without creating an exact project database",
105
- exitCode: 0,
106
- projectRoot: workspace,
107
- source: "path",
108
- timedOut: false,
109
- }]);
110
- expect(cooldown).toEqual({ cooldownUntil: 61_000, failureCount: 1, kind: "active" });
111
- } finally {
112
- rmSync(homeDir, { recursive: true, force: true });
113
- rmSync(workspace, { recursive: true, force: true });
114
- }
115
- });
116
- });
@@ -1,258 +0,0 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { join } from "node:path";
5
-
6
- import { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
7
- import { resolveCodegraphCommandInvocation, runCodegraphSessionStartWorker } from "../src/hook.ts";
8
-
9
- function writeProjectDatabase(workspace: string): void {
10
- mkdirSync(join(workspace, ".codegraph"), { recursive: true });
11
- writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
12
- }
13
-
14
- describe("CodeGraph SessionStart worker flow", () => {
15
- it("#given install_dir has the pinned platform binary #when worker resolves provisioned CodeGraph #then it uses that launcher", async () => {
16
- // given
17
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-platform-"));
18
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-platform-home-"));
19
- const installDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-platform-install-"));
20
- const binPath = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
21
- const calls: { readonly args: readonly string[]; readonly command: string; readonly env: Record<string, string> }[] = [];
22
- const outcomes: unknown[] = [];
23
- try {
24
- mkdirSync(join(installDir, "bin"), { recursive: true });
25
- mkdirSync(join(installDir, ".provisioned"), { recursive: true });
26
- writeFileSync(binPath, "");
27
- writeFileSync(
28
- join(installDir, ".provisioned", `codegraph-${CODEGRAPH_PINNED_VERSION}.json`),
29
- `${JSON.stringify({ binPath, version: CODEGRAPH_PINNED_VERSION })}\n`,
30
- );
31
-
32
- // when
33
- const result = await runCodegraphSessionStartWorker({
34
- config: { codegraph: { enabled: true, install_dir: installDir }, sources: [], trustedCodegraphInstallDir: installDir, warnings: [] },
35
- nodeVersion: "22.14.0",
36
- cwd: workspace,
37
- env: { HOME: homeDir },
38
- logOutcome: (outcome) => outcomes.push(outcome),
39
- deps: {
40
- ensureGitignored: () => true,
41
- ensureProvisioned: () => {
42
- throw new Error("provisioning should not run when install_dir binary exists");
43
- },
44
- prepareWorkspace: () => ({
45
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
46
- dataRoot: join(homeDir, ".omo/codegraph"),
47
- linked: true,
48
- mode: "global-linked",
49
- projectLink: join(workspace, ".codegraph"),
50
- }),
51
- resolveCommand: (options) => {
52
- const provisioned = options?.provisioned?.() ?? null;
53
- return { argsPrefix: [], command: provisioned ?? "missing-codegraph", exists: provisioned !== null, source: provisioned === null ? "path" : "provisioned" };
54
- },
55
- resolveManagedBin: () => binPath,
56
- runCommand: (_projectRoot, command, args, options) => {
57
- calls.push({ args, command, env: options.env });
58
- writeProjectDatabase(workspace);
59
- return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
60
- },
61
- },
62
- });
63
-
64
- // then
65
- expect(result).toEqual({ action: "initialized" });
66
- expect(calls.map((call) => ({ args: [...call.args], command: call.command }))).toEqual([
67
- { args: ["init"], command: binPath },
68
- ]);
69
- expect(calls[0]?.env["CODEGRAPH_INSTALL_DIR"]).toBe(installDir);
70
- expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "provisioned", timedOut: false }]);
71
- } finally {
72
- rmSync(workspace, { recursive: true, force: true });
73
- rmSync(homeDir, { recursive: true, force: true });
74
- rmSync(installDir, { recursive: true, force: true });
75
- }
76
- });
77
-
78
- it("#given Windows codegraph.cmd #when default worker runner builds invocation #then it runs through cmd.exe", () => {
79
- // given
80
- const command = "C:\\Users\\test\\.omo\\codegraph\\bin\\codegraph.cmd";
81
-
82
- // when
83
- const invocation = resolveCodegraphCommandInvocation(command, ["init"], "win32");
84
-
85
- // then
86
- expect(invocation).toEqual({
87
- args: ["/d", "/s", "/c", command, "init"],
88
- command: "cmd.exe",
89
- });
90
- });
91
-
92
- it("#given Windows CodeGraph resolves to a Node script #when default worker runner builds invocation #then Node executes it", () => {
93
- // given
94
- const command = "C:\\Users\\test\\.omo\\codegraph\\bin\\codegraph.cjs";
95
-
96
- // when
97
- const invocation = resolveCodegraphCommandInvocation(command, ["init"], "win32");
98
-
99
- // then
100
- expect(invocation).toEqual({
101
- args: [command, "init"],
102
- command: process.execPath,
103
- });
104
- });
105
-
106
- it("#given non-Windows codegraph command #when default worker runner builds invocation #then it executes directly", () => {
107
- // given
108
- const command = "/home/test/.omo/codegraph/bin/codegraph";
109
-
110
- // when
111
- const invocation = resolveCodegraphCommandInvocation(command, ["sync"], "linux");
112
-
113
- // then
114
- expect(invocation).toEqual({ args: ["sync"], command });
115
- });
116
-
117
- it("#given an uninitialized exact project #when worker runs #then it invokes init directly without a status command", async () => {
118
- // given
119
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-init-direct-"));
120
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-init-direct-home-"));
121
- const calls: { readonly args: readonly string[]; readonly env: Record<string, string> }[] = [];
122
- const outcomes: unknown[] = [];
123
- try {
124
- // when
125
- const result = await runCodegraphSessionStartWorker({
126
- config: { codegraph: { enabled: true, install_dir: "/tmp/codegraph-install" }, sources: [], trustedCodegraphInstallDir: "/tmp/codegraph-install", warnings: [] },
127
- nodeVersion: "22.14.0",
128
- cwd: workspace,
129
- env: { HOME: homeDir },
130
- logOutcome: (outcome) => outcomes.push(outcome),
131
- deps: {
132
- ensureGitignored: () => true,
133
- ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
134
- prepareWorkspace: () => ({
135
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
136
- dataRoot: join(homeDir, ".omo/codegraph"),
137
- linked: true,
138
- mode: "global-linked",
139
- projectLink: join(workspace, ".codegraph"),
140
- }),
141
- resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
142
- runCommand: (_projectRoot, _command, args, options) => {
143
- calls.push({ args, env: options.env });
144
- writeProjectDatabase(workspace);
145
- return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
146
- },
147
- },
148
- });
149
-
150
- // then
151
- expect(result).toEqual({ action: "initialized" });
152
- expect(calls.map((call) => [...call.args])).toEqual([["init"]]);
153
- expect(calls[0]?.env["CODEGRAPH_INSTALL_DIR"]).toBe("/tmp/codegraph-install");
154
- expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "path", timedOut: false }]);
155
- } finally {
156
- rmSync(workspace, { recursive: true, force: true });
157
- rmSync(homeDir, { recursive: true, force: true });
158
- }
159
- });
160
-
161
- it("#given codegraph.daemon=true #when the indexing worker runs #then its env stays daemon-less with CODEGRAPH_NO_DAEMON=1", async () => {
162
- // given
163
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-daemon-"));
164
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-daemon-home-"));
165
- const calls: { readonly args: readonly string[]; readonly command: string; readonly env: Record<string, string> }[] = [];
166
- try {
167
- // when
168
- const result = await runCodegraphSessionStartWorker({
169
- config: { codegraph: { daemon: true, enabled: true, install_dir: "/tmp/codegraph-install" }, sources: [], trustedCodegraphInstallDir: "/tmp/codegraph-install", warnings: [] },
170
- nodeVersion: "22.14.0",
171
- cwd: workspace,
172
- env: { HOME: homeDir },
173
- logOutcome: () => undefined,
174
- deps: {
175
- ensureGitignored: () => true,
176
- ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
177
- prepareWorkspace: () => ({
178
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
179
- dataRoot: join(homeDir, ".omo/codegraph"),
180
- linked: true,
181
- mode: "global-linked",
182
- projectLink: join(workspace, ".codegraph"),
183
- }),
184
- resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
185
- runCommand: (_projectRoot, command, args, options) => {
186
- calls.push({ args, command, env: options.env });
187
- writeProjectDatabase(workspace);
188
- return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
189
- },
190
- },
191
- });
192
-
193
- // then
194
- expect(result).toEqual({ action: "initialized" });
195
- expect(calls.length).toBeGreaterThan(0);
196
- for (const call of calls) {
197
- expect(call.env["CODEGRAPH_NO_DAEMON"]).toBe("1");
198
- }
199
- } finally {
200
- rmSync(workspace, { recursive: true, force: true });
201
- rmSync(homeDir, { recursive: true, force: true });
202
- }
203
- });
204
-
205
- it("#given ambient provider tokens #when default worker runner spawns CodeGraph #then child env only gets safe and controlled variables", async () => {
206
- // given
207
- const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-env-"));
208
- const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-env-home-"));
209
- const logPath = join(homeDir, "child-env.jsonl");
210
- const originalOpenAiKey = process.env["OPENAI_API_KEY"];
211
- process.env["OPENAI_API_KEY"] = "sk-test-secret";
212
-
213
- try {
214
- const fakeCodegraphScript = [
215
- "const fs = require('node:fs');",
216
- `fs.appendFileSync(${JSON.stringify(logPath)}, JSON.stringify({install:process.env.CODEGRAPH_INSTALL_DIR,openai:process.env.OPENAI_API_KEY}) + '\\n');`,
217
- "fs.mkdirSync('.codegraph', { recursive: true });",
218
- "fs.writeFileSync('.codegraph/codegraph.db', 'fixture');",
219
- ].join("");
220
-
221
- // when
222
- const result = await runCodegraphSessionStartWorker({
223
- config: { codegraph: { enabled: true }, sources: [], warnings: [] },
224
- cwd: workspace,
225
- env: { HOME: homeDir },
226
- logOutcome: () => undefined,
227
- nodeVersion: "22.14.0",
228
- deps: {
229
- ensureGitignored: () => true,
230
- ensureProvisioned: () => {
231
- throw new Error("provisioning should not run when command is resolved");
232
- },
233
- prepareWorkspace: () => ({
234
- dataDir: join(homeDir, ".omo/codegraph/projects/test"),
235
- dataRoot: join(homeDir, ".omo/codegraph"),
236
- linked: true,
237
- mode: "global-linked",
238
- projectLink: join(workspace, ".codegraph"),
239
- }),
240
- resolveCommand: () => ({ argsPrefix: ["-e", fakeCodegraphScript], command: process.execPath, exists: true, source: "bundled" }),
241
- },
242
- });
243
-
244
- // then
245
- expect(result).toEqual({ action: "initialized" });
246
- const captured = readFileSync(logPath, "utf8")
247
- .trim()
248
- .split("\n")
249
- .map((line) => JSON.parse(line));
250
- expect(captured).toEqual([{ install: join(homeDir, ".omo", "codegraph") }]);
251
- } finally {
252
- if (originalOpenAiKey === undefined) delete process.env["OPENAI_API_KEY"];
253
- else process.env["OPENAI_API_KEY"] = originalOpenAiKey;
254
- rmSync(workspace, { recursive: true, force: true });
255
- rmSync(homeDir, { recursive: true, force: true });
256
- }
257
- });
258
- });