code-yeongyu / code-yeongyu/lazycodex
Windows: OMO helper node processes accumulate far beyond active conversation count
- Dominant language
- TypeScript
- Stars
- 3.5k
- Forks
- 216
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
On Windows, OMO helper Node processes accumulate far beyond the number of active conversations when running Codex Desktop with the bundled OMO plugin. With only 3 active conversations, I observed 27 repeated helper bundles (`codegraph`, `git-bash-mcp`, `lsp-daemon`) still resident for hours, causing heavy memory usage and UI lag.
## Environment
- LazyCodex / OMO plugin version: `sisyphuslabs/omo 4.19.0` from the local Codex plugin cache
- Codex version: `codex-cli 0.145.0`
- OS: Windows
- Install method: Codex Desktop with marketplace/plugin cache under `C:\Users\Rusz\.codex\plugins\cache\sisyphuslabs\omo\4.19.0`
- Relevant config: OMO enabled; only 3 active conversations during observation
## Repository Decision
- Target repository: `code-yeongyu/lazycodex`
- Why this belongs there: the repeated helper trees originate from OMO plugin components, not only from generic Codex processes.
- LazyCodex evidence (runtime + local installed source):
- Repeated command lines all point into `C:\Users\Rusz\.codex\plugins\cache\sisyphuslabs\omo\4.19.0\...`
- Observed repeats:
- `27 x components/codegraph/dist/serve.js`
- `27 x components/git-bash-mcp/dist/cli.js mcp`
- `27 x components/lsp-daemon/dist/cli.js mcp`
- `27 x codegraph npm-shim`
- `27 x codegraph-win32-x64 ... serve --mcp`
- `components/codegraph/src/hook.ts` spawns a detached background worker on every eligible `SessionStart`.
- `components/bootstrap/src/hook.ts` also spawns a detached background worker.
- `components/lsp-daemon/dist/ensure-daemon.js` / `dist/cli.js` spawn a detached daemon process.
- Upstream Codex evidence:
- `openai/codex` already has similar Windows MCP leak issues open, including #28361, #30408, #31499, #32797, #34614, #34704.
- That suggests a nearby ownership boundary, but this specific helper bundle is OMO-owned because the repeated commands and paths are all under the OMO plugin cache.
## Reproduction
1. Run Codex Desktop on Windows with the bundled OMO plugin enabled.
2. Open and use a few conversations over time. In my case there were only 3 active conversations.
3. Inspect running processes in Task Manager or with `Get-CimInstance Win32_Process`.
4. Group by command line and observe repeated OMO helper bundles remaining resident long after the conversations that likely spawned them.
## Expected Behavior
Helper processes should be shared where possible and should be reaped when the owning conversation or session ends. Process count should stay roughly proportional to active work.
## Actual Behavior
Helper bundles accumulate over time and remain resident well beyond the active conversation count. The machine becomes noticeably laggy, and dozens of `node.exe` processes remain alive.
## Evidence
- Runtime grouping from `Get-CimInstance Win32_Process | Group-Object CommandLine`:
- `27 x codegraph/dist/serve.js`
- `27 x git-bash-mcp/dist/cli.js mcp`
- `27 x lsp-daemon/dist/cli.js mcp`
- Old roots still resident:
- `opencode.exe pid=25024` started `2026-07-25 16:16:43`
- `opencode.exe pid=35736` started `2026-07-25 16:18:43`
- Codex root also retained many historical children under `codex.exe pid=22096`, with child start times spanning `2026-07-24 23:55` to `2026-07-25 17:42`
- Repeated helper chain shape:
- `node.exe codegraph/dist/serve.js`
- `npm-shim.js serve --mcp`
- `codegraph-win32-x64 ... serve --mcp`
- `watchdog node.exe -e "..."`
- sibling `git-bash-mcp`
- sibling `lsp-daemon`
- Listener footprint was small, which suggests these are mostly lingering stdio/helper workers rather than legitimate long-lived listening services:
- only one obvious node listener was observed: `127.0.0.1:19825` from `opencli daemon.js`
## Root Cause
The strongest current evidence is a lifecycle gap in OMO-managed helper processes on Windows:
- `components/codegraph/src/hook.ts` uses `spawn(..., { detached: true, stdio: "ignore" })` plus `child.unref()` for the `SessionStart` worker.
- `components/bootstrap/src/hook.ts` does the same for bootstrap work.
- `lsp-daemon` also uses detached daemon spawning.
That pattern is valid for background work, but with only 3 active conversations it should not leave 27 repeated helper bundles alive for hours. The observed process trees suggest one of these is happening:
- helper trees are not being reaped after the owning session ends
- helper suites are started per historical session instead of being reused/shared
- Windows termination does not reach the full helper subtree consistently
## Proposed Fix
- Audit helper lifecycle ownership for:
- `components/codegraph/src/hook.ts`
- `components/bootstrap/src/hook.ts`
- `components/lsp-daemon/*`
- Add explicit ownership and teardown for Windows helper trees, instead of relying on detached background workers to disappear naturally.
- Consider a shared process model for `git-bash-mcp`, `lsp-daemon`, and CodeGraph MCP helpers so they are reused across sessions instead of spawned per session.
- Add regression coverage that opens multiple sessions sequentially and asserts helper count remains bounded after session close.
## Verification Plan
- Reproduce on Windows with 3 active conversations and record helper counts by command line before the fix.
- Apply the lifecycle fix and repeat the same workflow.
- Confirm that historical helper bundles are reaped after session end or reused instead of duplicated.
- Confirm that CodeGraph, `git-bash-mcp`, and `lsp-daemon` still function normally in active conversations.
---
This issue or PR was generated by LazyCodex.
Tag: lazycodex-generated
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reproducing the Windows process accumulation with Get-CimInstance Win32_Process, then read components/codegraph/src/hook.ts, components/bootstrap/src/hook.ts, and components/lsp-daemon/ spawning paths. Compare helper counts across sequential sessions and verify that teardown or reuse keeps counts bounded while CodeGraph, git-bash-mcp, and lsp-daemon still work in active conversations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- cli, devtools, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100