Skip to content

fix(cli): client detection for OpenCode, Hermes, Claude (#1167, #1180) - #2468

Open
DeusData wants to merge 3 commits into
mainfrom
fix/issue-1167-1180-client-detect
Open

DeusData wants to merge 3 commits into
mainfrom
fix/issue-1167-1180-client-detect

Conversation

@DeusData

@DeusData DeusData commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Three detection defects kept codebase-memory-mcp install from
configuring agents people run, and made it configure one they never
installed.

OpenCode without a config file or a CLI on PATH (#1167, #1180).
OpenCode was detected only from its global config file or directory,
OPENCODE_CONFIG_DIR, or an opencode found on PATH. It now also counts
as installed when its data directory exists: ~/.local/share/opencode on
every OS, %USERPROFILE%.local\share\opencode on Windows
(opencode.ai/docs/troubleshooting, "Storage"; the same page names it as
the global config location of older installs). The OpenCode CLI and the
Desktop app both create it -- the Desktop's bundled opencode-cli server
uses the same XDG paths (anomalyco/opencode packages/core/src/global.ts
creates the config and data dirs at startup;
packages/desktop/src/main/sidecar.ts only redirects XDG_STATE_HOME) --
so detection no longer depends on PATH. The install target
~/.config/opencode/opencode.json(c) -- %USERPROFILE%.config\opencode
on Windows per the same docs page -- is unchanged and right for CLI and
Desktop alike. A PATH longer than 4 KB, which hides every CLI from
find_in_path(), is handled separately by PR #2381.

Hermes home on Windows (#1180). Native Windows Hermes -- the install.ps1
CLI, the MSIX package and the Desktop app -- defaults HERMES_HOME to
%LOCALAPPDATA%\hermes and falls back to a legacy ~/.hermes only while
that directory is absent (NousResearch/hermes-agent
website/docs/user-guide/windows-native.md, "Data layout";
apps/desktop/electron/data-paths.mjs, resolveDesktopHermesHome). cbm
probed and wrote ~/.hermes only, so a Desktop install was never detected
and a Hermes found on PATH got its config.yaml and skill in a home it
never reads. On Windows the home now resolves to
/AppData/Local/hermes unless only ~/.hermes exists, using the
home-derived AppData convention of the existing Zed, goose, Kilo and VS
Code probes; detection, install and uninstall all follow it. HERMES_HOME
still wins, and macOS/Linux keep ~/.hermes.

Claude Code from a bare ~/.claude (#1180). Any ~/.claude directory
counted as a Claude Code install, so a user who only had the folder got
hooks, skills and MCP entries for a client they never installed.
Detection now needs what Claude Code itself leaves behind: settings.json
in the config dir, .claude.json in the home (in CLAUDE_CONFIG_DIR when
set), or the claude CLI.

Proof on macOS against synthetic HOME/cache/runtime dirs with a minimal
PATH (install --dry-run --skip-binary, then a config-only install):
bare ~/.claude main: Claude-Code fix: none
~/.local/share/opencode only main: none fix: OpenCode
In the OpenCode case the fixed install writes the codebase-memory-mcp
entry to ~/.config/opencode/opencode.json; main writes nothing. Controls
(a launched Desktop layout, a real Claude user) are detected by both.
The Windows Hermes home is covered by a platform-parameterised resolver
test that runs on every host plus a _WIN32-bound end-to-end detection
and plan test.

Tests (cli suite, 335 passed): seven new tests; five fail on main three
times out of three (the _WIN32-bound Hermes test and the look-alike
control are green on macOS by design). Reverting the Claude+Hermes half
and the OpenCode data-dir probe separately turns exactly their own tests
red. Nine existing Claude fixtures that used a bare ~/.claude as the
install marker now write .claude.json; two Hermes tests and smoke-test
8x expect %LOCALAPPDATA%\hermes on Windows.

Refs #1167
Fixes #1180

Three detection defects kept `codebase-memory-mcp install` from
configuring agents people run, and made it configure one they never
installed.

OpenCode without a config file or a CLI on PATH (#1167, #1180).
OpenCode was detected only from its global config file or directory,
OPENCODE_CONFIG_DIR, or an `opencode` found on PATH. It now also counts
as installed when its data directory exists: ~/.local/share/opencode on
every OS, %USERPROFILE%\.local\share\opencode on Windows
(opencode.ai/docs/troubleshooting, "Storage"; the same page names it as
the global config location of older installs). The OpenCode CLI and the
Desktop app both create it -- the Desktop's bundled opencode-cli server
uses the same XDG paths (anomalyco/opencode packages/core/src/global.ts
creates the config and data dirs at startup;
packages/desktop/src/main/sidecar.ts only redirects XDG_STATE_HOME) --
so detection no longer depends on PATH. The install target
~/.config/opencode/opencode.json(c) -- %USERPROFILE%\.config\opencode
on Windows per the same docs page -- is unchanged and right for CLI and
Desktop alike. A PATH longer than 4 KB, which hides every CLI from
find_in_path(), is handled separately by PR #2381.

Hermes home on Windows (#1180). Native Windows Hermes -- the install.ps1
CLI, the MSIX package and the Desktop app -- defaults HERMES_HOME to
%LOCALAPPDATA%\hermes and falls back to a legacy ~/.hermes only while
that directory is absent (NousResearch/hermes-agent
website/docs/user-guide/windows-native.md, "Data layout";
apps/desktop/electron/data-paths.mjs, resolveDesktopHermesHome). cbm
probed and wrote ~/.hermes only, so a Desktop install was never detected
and a Hermes found on PATH got its config.yaml and skill in a home it
never reads. On Windows the home now resolves to
<home>/AppData/Local/hermes unless only ~/.hermes exists, using the
home-derived AppData convention of the existing Zed, goose, Kilo and VS
Code probes; detection, install and uninstall all follow it. HERMES_HOME
still wins, and macOS/Linux keep ~/.hermes.

Claude Code from a bare ~/.claude (#1180). Any ~/.claude directory
counted as a Claude Code install, so a user who only had the folder got
hooks, skills and MCP entries for a client they never installed.
Detection now needs what Claude Code itself leaves behind: settings.json
in the config dir, .claude.json in the home (in CLAUDE_CONFIG_DIR when
set), or the claude CLI.

Proof on macOS against synthetic HOME/cache/runtime dirs with a minimal
PATH (`install --dry-run --skip-binary`, then a config-only install):
  bare ~/.claude                        main: Claude-Code  fix: none
  ~/.local/share/opencode only          main: none         fix: OpenCode
In the OpenCode case the fixed install writes the codebase-memory-mcp
entry to ~/.config/opencode/opencode.json; main writes nothing. Controls
(a launched Desktop layout, a real Claude user) are detected by both.
The Windows Hermes home is covered by a platform-parameterised resolver
test that runs on every host plus a _WIN32-bound end-to-end detection
and plan test.

Tests (cli suite, 335 passed): seven new tests; five fail on main three
times out of three (the _WIN32-bound Hermes test and the look-alike
control are green on macOS by design). Reverting the Claude+Hermes half
and the OpenCode data-dir probe separately turns exactly their own tests
red. Nine existing Claude fixtures that used a bare ~/.claude as the
install marker now write .claude.json; two Hermes tests and smoke-test
8x expect %LOCALAPPDATA%\hermes on Windows.

Refs #1167
Fixes #1180
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The client-detection fix moved the Windows Hermes home to
%LOCALAPPDATA%\hermes and stopped counting a bare ~/.claude directory as a
Claude Code install. The smoke script followed only part of the way.

Hermes: 8x and 8x-i read the new HERMES_HOME_DIR, but 8x-ii still looked
for the pre_llm_call hook in ~/.hermes/config.yaml, and the uninstall
absence checks 9m and 9n still named ~/.hermes. On Linux and macOS
HERMES_HOME_DIR is ~/.hermes, so the stale paths pointed at the right
directory and nothing showed. Only on Windows do the two differ: 8x-ii
failed on a hook that install had written to the new home, and 9m and 9n
passed without looking at any file install had produced. All three now use
HERMES_HOME_DIR. The assertions are unchanged.

Claude Code: the fixtures of 9b-2, 9b-3, 9b-8 and both Phase 13 legs
created only an empty ~/.claude, which is no longer a Claude Code home.
Wherever no claude executable is installed, 9b-2 then finds no .claude.json
entry and 13e finds no agent config, and 9b-3, 9b-8 and the install.ps1 leg
stop exercising the Claude paths without saying so. The Linux test
container reproduces both failures. The Windows job never got that far,
because 8x-ii stops it in Phase 8. The fixtures now seed the .claude.json
user config through one helper, the same seed the unit tests use.

9b-1b pins the new rule end to end: where the empty-home control shows no
Claude Code, a home with only a bare ~/.claude gets no Claude config. A
venue that has a claude executable skips it, with the reason at the case.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The install script failed to detect Hermes(Desktop) and OpenCode(Desktop) on Windows

1 participant