feat: honor ZCODE_HOME for the config and lazy-session store paths - #187
Conversation
Both the credentials/provider config and the lazy-session alias store were pinned to `~/.zcode`, so a bridge could not be pointed at an isolated ZCode install (a second account, a container mount, a test fixture) without moving the user's real home. `zcodeHomeDir()` in utils.ts is now the single place that resolves the data root: `ZCODE_HOME` when set, else `<home>/.zcode`. `ZCODE_CREDS_PATH` and the lazy store's `storePath()` both build on it. Default behaviour is unchanged when the variable is unset. `ZCODE_CREDS_PATH` stays a module-level const, so `ZCODE_HOME` must be set before the process starts; the store path is resolved per call as before. The hermetic test setup deletes `ZCODE_HOME` for the same reason it redirects HOME: an exported value would point the suite at a real store. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DLQ3W2owia4SJBvzxSqvVc
william0wang
left a comment
There was a problem hiding this comment.
Reviewed (typecheck pass; targeted tests pass; the lazy store still goes through persist() and the hermetic setup clears ZCODE_HOME — both good).
Requesting one change before merge: the override is partial. zcodeHomeDir() is documented as the single data-root resolver, but these readers still build the real ~/.zcode from module-level homedir()/HOME constants:
src/config/skill-discovery.ts:45,48,170(CLI config, plugin cache, user skills scan)src/config/mcp-discovery.ts:48,49src/config/plugin-commands.ts:19,27src/i18n.ts:57(settings.json locale detection)src/tasks-index.ts:355(the App's tasks-index.sqlite backing the remote session list)
With ZCODE_HOME pointed at an isolated install, credentials and lazy sessions follow the override while plugins/skills/MCP servers/locale/session-listing still read the real home — a silently split brain for exactly the second-account/container case the README promises. Either route them through zcodeHomeDir() (preferred) or narrow the README claim to "credentials and the lazy-session store".
Review follow-up on the ZCODE_HOME override: the discovery modules still built the real ~/.zcode from module-level homedir() constants, so an isolated data root split the bridge in two — credentials and lazy sessions followed ZCODE_HOME while plugins, skills, MCP servers, locale detection and the workspace list kept reading the user's real home. zcodeHomeDir() is now the single resolver everywhere it claims to be: - skill-discovery / mcp-discovery / plugin-commands: the CLI-config and plugin-cache path constants become per-call zcodeCliConfigPath() / zcodePluginCacheDir() helpers in utils.ts (deduplicating the three identical copies); the user-skills scan reads <zcode-home>/skills - i18n: the desktop-app settings read follows the override - tasks-index: the workspace exclusion rejects the override root, not the real ~/.zcode, when ZCODE_HOME is set ~/.agents/skills stays on the real home — it is a cross-agent convention, not part of the ZCode data root. README's ZCODE_HOME row now lists every follower. Per-call resolution (not module snapshots) means tests can stub the env per case; each affected module gains a ZCODE_HOME test that proves the real home is ignored while the override is honored.
|
Thanks! Addressed in a8ac07a — went with the preferred option: every flagged reader now goes through The three identical CLI-config/plugin-cache path constants became shared per-call helpers ( Each affected module gained a ZCODE_HOME test that proves the real home is ignored while the override is honored (the i18n one required tightening that suite's fs mock from suffix-match to exact-match so it can actually discriminate the two roots). |
🤖 I have created a release *beep* *boop* --- ## [0.39.0](v0.38.0...v0.39.0) (2026-09-16) ### Features * choose the initial session mode with ZCODE_ACP_MODE ([#189](#189)) ([a1aa2e0](a1aa2e0)) * honor ZCODE_HOME for the config and lazy-session store paths ([#187](#187)) ([0593488](0593488)) * pin the provider and model with ZCODE_PROVIDER and ZCODE_MODEL ([#188](#188)) ([6aa8999](6aa8999)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Problem
The credentials config path and the lazy-session alias store are pinned to
~/.zcode. A bridge cannot be pointed at an isolated ZCode install (a second account, a container mount, a test fixture) without moving the user's real home directory.Change
zcodeHomeDir()inutils.tsis the single place that resolves the data root:ZCODE_HOMEwhen set, else<home>/.zcode.ZCODE_CREDS_PATHand the lazy store'sstorePath()build on it. Default behaviour is unchanged when the variable is unset. The README documents the variable.The hermetic test setup now clears
ZCODE_HOMEfor the same reason it redirectsHOME.Tests
tests/utils.test.tsandtests/lazy-sessions.test.tscover the variable set and unset.🤖 Generated with Claude Code
https://claude.ai/code/session_01DLQ3W2owia4SJBvzxSqvVc