Skip to content

feat(plugins): fall back to user-level ~/.claude settings for Claude Code hook config#924

Open
samuellawerentz wants to merge 7 commits into
basicmachines-co:mainfrom
samuellawerentz:global-settings-fallback
Open

feat(plugins): fall back to user-level ~/.claude settings for Claude Code hook config#924
samuellawerentz wants to merge 7 commits into
basicmachines-co:mainfrom
samuellawerentz:global-settings-fallback

Conversation

@samuellawerentz

@samuellawerentz samuellawerentz commented Jun 9, 2026

Copy link
Copy Markdown

Problem

The Claude Code plugin's SessionStart and PreCompact hooks read the basicMemory block only from <cwd>/.claude/settings.json. Every project therefore needs its own config block (or a bm-setup run) before the brief resolves a pinned project — and the PreCompact checkpoint is a silent no-op everywhere until then. Users with a single primary knowledge graph end up repeating the same block in every repo.

Change

load_settings in both hooks now merges the user-level ~/.claude/settings.json and settings.local.json as the base, with the project's .claude files overriding per key — the same layering Claude Code itself uses for settings:

user settings.json → user settings.local.json → project settings.json → project settings.local.json

One user-level basicMemory block covers every project; a project that pins its own primaryProject still wins. When cwd is the home directory the user level is read once, not twice.

Also documents the user-level option in the plugin README.

Testing

  • bash -n on both hooks.
  • Manually invoked session-start.sh with a payload cwd of a repo with no .claude/settings.json: brief resolves the project from the user-level block (previously: "default project" + setup nudge).
  • Same with a project-level block present: project value wins.
  • pre-compact.sh resolves primaryProject from the user level the same way (previously exited silently).

🤖 Generated with Claude Code

Reviewed SHA: 868d2094c77aae23d1de92c72be3708ea8c3b293
Verdict: needs_human
Status: failure - BM Bossbot review did not finish

Summary:
BM Bossbot intentionally did not run Codex because this PR was not opened by an owner, member, or collaborator.

Blocking findings:

  • BM Bossbot does not run for outside contributors: This PR author association is NONE. BM Bossbot only runs for OWNER, MEMBER, and COLLABORATOR pull requests, so this PR requires a maintainer path outside the automatic merge gate.

Non-blocking findings:

  • None

…nfig

The SessionStart and PreCompact hooks read basicMemory config only from
<cwd>/.claude/settings.json, so every project needs its own block (or a
bm-setup run) before briefs resolve a pinned project and checkpoints write
at all. Users with one primary knowledge graph end up repeating the same
config in every repo.

Make load_settings in both hooks merge user-level ~/.claude/settings.json
and settings.local.json as the base, with the project's .claude files
overriding per key — same layering Claude Code itself uses for settings.
A single user-level basicMemory block now covers every project, while any
project can still pin its own mapping, which wins. Documented in the
plugin README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@phernandez

Copy link
Copy Markdown
Member

thanks @samuellawerentz. I had not gotten around to adding the user level settings. Thats much needed.

Do you mind signing off on your commits? and signing the cla? We need that before we can merge this.

In your local branch, run: git rebase HEAD~1 --signoff

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dc6fc776f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/claude-code/README.md Outdated
Comment on lines +83 to +84
The block can also live in your **user-level** `~/.claude/settings.json` (or
`settings.local.json`) — one block there covers every project, no per-repo setup.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align user-level config across plugin commands

When a user follows this new user-level setup, only the hooks read ~/.claude; the command skills still instruct Claude to read project-local settings only (plugins/claude-code/skills/bm-remember/SKILL.md:13, plugins/claude-code/skills/bm-share/SKILL.md:13, plugins/claude-code/skills/bm-status/SKILL.md:18). That means /basic-memory:bm-remember can write to the default project instead of the user-level primaryProject, /bm-share can report no team targets, and /bm-status can show no pinned project even though this README says one user-level block covers every project. Please update those command instructions to use the same settings precedence or narrow this claim to the two hooks.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 868d2094c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +90 to +93
dirs = [home] if os.path.abspath(directory) == home else [home, directory]
for d in dirs:
for name in ("settings.json", "settings.local.json"):
path = os.path.join(d, ".claude", name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict user-level settings to Claude's real source

When d is the home directory, this loop now reads ~/.claude/settings.local.json, but Claude Code's documented settings sources list user settings as ~/.claude/settings.json and local settings as only project-local .claude/settings.local.json. In environments where a stale or experimental global settings.local.json exists, the hook can silently use a basicMemory.primaryProject that Claude Code itself does not load or show in /status, so session briefs and checkpoints can route to a different project than the visible Claude settings. Please only read settings.json for the user-level pass, or clearly make this a plugin-only config path rather than matching Claude precedence.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a853652c4b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

found = True
merged.update(block)
home = os.path.expanduser("~")
dirs = [home] if os.path.abspath(directory) == home else [home, directory]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Search up to the project settings before falling back

When Claude is started from a repo subdirectory, the hook payload cwd is that working directory, but this only reads ~/.claude and cwd/.claude. If the repo has its Basic Memory mapping in the project root (for example repo/.claude/settings.json) and the user also has a global ~/.claude/settings.json, the project override is skipped and both the brief and PreCompact checkpoint route to the global project instead of the repo's pinned project. Please resolve the actual project settings directory (or walk ancestors to the first .claude config) before applying the user fallback.

Useful? React with 👍 / 👎.

@samuellawerentz

Copy link
Copy Markdown
Author

Sure, I'll get these fixed and signed as well. This is a good plugin and a good tool that I use, which has solved my memory problems across the different harnesses. Thank you.

samuellawerentz and others added 3 commits June 10, 2026 09:02
- User-level pass reads only ~/.claude/settings.json (no user-level
  settings.local.json — it isn't a real Claude Code source), so a stale
  global local file can't silently reroute the brief/checkpoint.
- Resolve project settings from the nearest .claude dir at or above cwd,
  so a repo-root mapping wins when Claude starts in a subdirectory.
- bm-remember / bm-share / bm-status skills now read the same precedence
  (user-level base, project overrides), matching the README claim that one
  user-level block covers every command.
- README: drop user-level settings.local.json from the precedence note and
  document the ancestor-walk behaviour.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Samuel Lawrentz <samuel.lawerence@plivo.com>
- Drop redundant except FileNotFoundError in _read_block (subclass of
  Exception, already caught).
- Drop redundant os.path.abspath in load_settings; _project_dir already
  returns an absolute path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Samuel Lawrentz <samuel.lawerence@plivo.com>
@phernandez phernandez added the needs-review Maintainer decision needed before merge label Jun 10, 2026
@phernandez

Copy link
Copy Markdown
Member

Labeling needs-review: there are unresolved review threads on the hook fallback behavior that need a decision before this merges (merge precedence between project and user-level settings, and the skill doc updates). No action needed from the author yet — maintainers will follow up on the threads.

@phernandez phernandez added dco needed The contributor needs to submit a DCO and removed needs-review Maintainer decision needed before merge labels Jun 10, 2026
@phernandez

Copy link
Copy Markdown
Member

@samuellawerentz Thanks for the contribution — the user-level settings fallback is a direction we're interested in, and your follow-up commits addressing the review were appreciated.

One mechanical blocker before we can take this further: the DCO check requires every commit to carry a Signed-off-by trailer, and the first commit on the branch (f94ae316) doesn't have one. The easiest fix signs everything and tidies the merge commits away in one go — from your local clone of the branch:

git fetch origin main
git rebase origin/main --signoff
git push --force-with-lease origin global-settings-fallback

(If your fork's remote is named differently, swap origin accordingly in the push. --signoff adds the trailer to each replayed commit using your configured git identity, which certifies the Developer Certificate of Origin.)

Once DCO is green we'll pick the review threads back up. Thanks again!

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

Labels

dco needed The contributor needs to submit a DCO

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants