Skip to content

feat: read global AGENTS.md from ~/.agents/ as vendor-neutral fallback#2236

Open
mvanhorn wants to merge 1 commit into
Hmbown:mainfrom
mvanhorn:fix/2156-codewhale-global-agents-md-fallback
Open

feat: read global AGENTS.md from ~/.agents/ as vendor-neutral fallback#2236
mvanhorn wants to merge 1 commit into
Hmbown:mainfrom
mvanhorn:fix/2156-codewhale-global-agents-md-fallback

Conversation

@mvanhorn
Copy link
Copy Markdown

@mvanhorn mvanhorn commented May 27, 2026

Summary

  • Reads global agent instructions from ~/.agents/AGENTS.md as a vendor-neutral fallback when ~/.claude/CLAUDE.md is absent.
  • Follows the harvest precedent set by PR feat(project-context): merge global AGENTS.md with project AGENTS.md (#1157) #1399 (linzhiqin2003) for global AGENTS.md handling, extended to cover the home-dir fallback path.
  • Single-file change in crates/tui/src/project_context.rs; default behavior unchanged for users who already have ~/.claude/CLAUDE.md.

Closes #2156.

AI was used for assistance.

Greptile Summary

This PR inserts ~/.agents/ as a new vendor-neutral fallback tier (priority 3–4) between the existing ~/.codewhale/ (priority 1–2) and ~/.deepseek/ (priority 5–6) global instruction directories, with two new tests covering the AGENTS.md case and priority ordering.

  • GLOBAL_AGENTS_VENDOR_NEUTRAL_PATH (~/.agents/AGENTS.md) and GLOBAL_WHALE_VENDOR_NEUTRAL_PATH (~/.agents/WHALE.md) are added to the candidate list in load_global_agents_context; the first matching file wins and the rest are skipped.
  • Two tests are added: one verifying ~/.agents/AGENTS.md is loaded when no codewhale-specific file exists, and one confirming ~/.codewhale/AGENTS.md takes priority over ~/.agents/AGENTS.md.
  • The ~/.agents/WHALE.md path (priority 3) has no corresponding test and sits above ~/.agents/AGENTS.md (priority 4) in the same directory, which could silently shadow a user's vendor-neutral config.

Confidence Score: 4/5

Safe to merge with minor cleanup; default behavior for existing users is unchanged.

The fallback logic is additive and only activates when neither ~/.codewhale/ nor ~/.agents/ files exist for current users, so there is no regression risk for anyone with an existing setup. The main gap is that ~/.agents/WHALE.md (priority 3) is added without a test and can silently shadow ~/.agents/AGENTS.md in the same directory — a user who relies on the vendor-neutral path could be surprised if they also have a WHALE.md there. The WHALE.md addition also sits oddly in a directory marketed as vendor-neutral.

crates/tui/src/project_context.rs — specifically the untested GLOBAL_WHALE_VENDOR_NEUTRAL_PATH constant and its interaction with GLOBAL_AGENTS_VENDOR_NEUTRAL_PATH.

Important Files Changed

Filename Overview
crates/tui/src/project_context.rs Adds ~/.agents/ as a vendor-neutral fallback tier between ~/.codewhale/ and ~/.deepseek/; introduces WHALE.md support in that directory which has no test coverage and is conceptually inconsistent with "vendor-neutral".

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[load_global_agents_context] --> B{~/.codewhale/WHALE.md?}
    B -- exists --> Z[return context]
    B -- missing --> C{~/.codewhale/AGENTS.md?}
    C -- exists --> Z
    C -- missing --> D{~/.agents/WHALE.md?}
    D -- exists --> Z
    D -- missing --> E{~/.agents/AGENTS.md?}
    E -- exists --> Z
    E -- missing --> F{~/.deepseek/WHALE.md?}
    F -- exists --> Z
    F -- missing --> G{~/.deepseek/AGENTS.md?}
    G -- exists --> Z
    G -- missing --> H[return None]

    style D fill:#ffe0b2,stroke:#f57c00
    style E fill:#ffe0b2,stroke:#f57c00
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Reviews (1): Last reviewed commit: "feat: read global AGENTS.md from ~/.agen..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Comment on lines 35 to +41

/// User-level project instructions loaded as a fallback when the workspace and
/// its parents do not define project context. `.codewhale/` takes priority
/// over `.deepseek/` for both WHALE.md and AGENTS.md.
/// over vendor-neutral `.agents/`, which takes priority over legacy
/// `.deepseek/`, for both WHALE.md and AGENTS.md.
const GLOBAL_AGENTS_RELATIVE_PATH: &[&str] = &[".codewhale", "AGENTS.md"];
const GLOBAL_AGENTS_VENDOR_NEUTRAL_PATH: &[&str] = &[".agents", "AGENTS.md"];
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 WHALE.md in a vendor-neutral directory is self-contradictory

~/.agents/ is introduced as a vendor-neutral location, but GLOBAL_WHALE_VENDOR_NEUTRAL_PATH adds ~/.agents/WHALE.md at priority 3, ahead of ~/.agents/AGENTS.md at priority 4. A user who creates ~/.agents/AGENTS.md to share config across multiple tools could have it silently shadowed if they also happen to have ~/.agents/WHALE.md, without any warning. Lookups of WHALE.md there also only benefit codewhale, which undermines the vendor-neutral intent. Consider restricting ~/.agents/ to AGENTS.md only, or document the WHALE.md precedence explicitly.

Fix in Codex Fix in Claude Code Fix in Cursor

Comment on lines +1052 to +1102
#[test]
fn test_load_global_agents_falls_back_to_vendor_neutral_path() {
let workspace = tempdir().expect("workspace tempdir");
let home = tempdir().expect("home tempdir");
let global_dir = home.path().join(".agents");
fs::create_dir(&global_dir).expect("mkdir .agents");
let global_agents = global_dir.join("AGENTS.md");
fs::write(&global_agents, "Vendor-neutral instructions").expect("write global agents");

let ctx = load_project_context_with_parents_and_home(workspace.path(), Some(home.path()));

assert!(ctx.has_instructions());
assert!(
ctx.instructions
.as_ref()
.unwrap()
.contains("Vendor-neutral instructions")
);
assert_eq!(ctx.source_path, Some(global_agents));
}

#[test]
fn test_codewhale_specific_path_wins_over_agents_path() {
let workspace = tempdir().expect("workspace tempdir");
let home = tempdir().expect("home tempdir");

let codewhale_dir = home.path().join(".codewhale");
fs::create_dir(&codewhale_dir).expect("mkdir .codewhale");
let codewhale_agents = codewhale_dir.join("AGENTS.md");
fs::write(&codewhale_agents, "CodeWhale-specific instructions")
.expect("write codewhale agents");

let agents_dir = home.path().join(".agents");
fs::create_dir(&agents_dir).expect("mkdir .agents");
fs::write(agents_dir.join("AGENTS.md"), "Vendor-neutral instructions")
.expect("write vendor-neutral agents");

let ctx = load_project_context_with_parents_and_home(workspace.path(), Some(home.path()));

assert!(ctx.has_instructions());
let instructions = ctx.instructions.as_ref().unwrap();
assert!(
instructions.contains("CodeWhale-specific instructions"),
"CodeWhale-specific global file should win:\n{instructions}"
);
assert!(
!instructions.contains("Vendor-neutral instructions"),
"lower-priority .agents file should be skipped:\n{instructions}"
);
assert_eq!(ctx.source_path, Some(codewhale_agents));
}
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 ~/.agents/WHALE.md path has no test coverage

GLOBAL_WHALE_VENDOR_NEUTRAL_PATH (~/.agents/WHALE.md) is a new constant added at priority 3, but neither new test exercises it. Both new tests only write to ~/.agents/AGENTS.md. If the path-building loop for WHALE.md had a typo or the constant were mis-ordered, nothing would catch it. A test confirming ~/.agents/WHALE.md is found when that file exists (and wins over ~/.agents/AGENTS.md in the same directory) would close this gap.

Fix in Codex Fix in Claude Code Fix in Cursor

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for vendor-neutral global configuration paths (.agents/WHALE.md and .agents/AGENTS.md) as fallback options. The resolution priority has been updated so that .codewhale/ takes priority over .agents/, which in turn takes priority over the legacy .deepseek/ paths. Additionally, unit tests have been added to verify the fallback behavior and priority resolution. There are no review comments, and I have no additional feedback to provide.

Hmbown added a commit that referenced this pull request May 27, 2026
- Workspace version: 0.8.46 → 0.8.47
- All inter-crate dependency versions updated
- Merged PR #2236: global AGENTS.md from ~/.agents/
Copy link
Copy Markdown
Owner

@Hmbown Hmbown left a comment

Choose a reason for hiding this comment

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

The core idea of reading as a vendor-neutral fallback is good. But the PR also introduces at priority 3, above at priority 4 — which contradicts the vendor-neutral intent and creates a silent shadowing hazard.

Requested changes:

  1. Remove from the candidate list entirely. If CodeWhale-specific global config is needed, it should go in (which is already higher priority at tier 1-2).
  2. Keep only in the vendor-neutral tier.
  3. Add a test verifying that is read but is NOT (to prevent regression).

The two new tests writing to are well-structured — those are fine to keep.

Copy link
Copy Markdown
Owner

@Hmbown Hmbown left a comment

Choose a reason for hiding this comment

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

The core idea of reading ~/.agents/AGENTS.md as a vendor-neutral fallback is good. But the PR also introduces ~/.agents/WHALE.md at priority 3, above ~/.agents/AGENTS.md at priority 4 — which contradicts the vendor-neutral intent and creates a silent shadowing hazard.

Requested changes:

  1. Remove ~/.agents/WHALE.md from the candidate list. If CodeWhale-specific global config is needed, use ~/.codewhale/ (already higher priority at tiers 1-2).
  2. Keep only ~/.agents/AGENTS.md in the vendor-neutral tier.
  3. Add a test verifying that ~/.agents/AGENTS.md is read but ~/.agents/WHALE.md is NOT.

The two new tests writing to ~/.agents/AGENTS.md are well-structured — those are fine to keep.

@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 27, 2026

Independent review: no objections to the core change. Skipping the WHALE.md/test gaps already covered by @Hmbown and greptile.

Net-new notes:

  1. v0.8.48 (refactor: consolidate workspace crates — 14→11 (delete tui-core, merge hooks+agent) #2256) overlap — this PR may be obsolete. The v0.8.48 branch already merged the exact maintainer fix in commit f2b0292b1 ("remove WHALE.md from vendor-neutral ~/.agents/ directory") and ships the same test_load_global_agents_falls_back_to_vendor_neutral_path + test_codewhale_specific_path_wins_over_agents_path tests. If refactor: consolidate workspace crates — 14→11 (delete tui-core, merge hooks+agent) #2256 lands first, this PR becomes a no-op merge or a conflict to resolve manually on project_context.rs. Worth confirming with @Hmbown whether to (a) close this in favor of refactor: consolidate workspace crates — 14→11 (delete tui-core, merge hooks+agent) #2256 with attribution, or (b) land this first and let refactor: consolidate workspace crates — 14→11 (delete tui-core, merge hooks+agent) #2256 rebase.

  2. Priority-comment drift after the fix. Once GLOBAL_WHALE_VENDOR_NEUTRAL_PATH is removed, the doc-comment block (lines 515–521) needs to drop the "3. ~/.agents/WHALE.md" line and renumber, or it will mislead future readers. refactor: consolidate workspace crates — 14→11 (delete tui-core, merge hooks+agent) #2256 already did this — mirror that wording.

  3. Pre-existing gap, not introduced here: ~/.codewhale/AGENTS.md (priority 2) has no dedicated positive test on main either. The new test_codewhale_specific_path_wins_over_agents_path (kept after the WHALE removal) does cover it indirectly, which is a nice incidental win.

Merge with main is clean today; the real coordination cost is with #2256.

@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 27, 2026

@mvanhorn — short status update: your ~/.agents/AGENTS.md vendor-neutral fallback idea is good and already landed. v0.8.48 (#2256) ships the same path independently in commit f2b0292b1 (which also addresses the maintainer's earlier ask about removing ~/.agents/WHALE.md).

That means the productive path here is one of two:

  1. Close this PR with credit — v0.8.48's implementation is functionally equivalent to what you wanted, your filing is what surfaced the gap
  2. Push the WHALE.md removal fix the maintainer asked for, then this can land before refactor: consolidate workspace crates — 14→11 (delete tui-core, merge hooks+agent) #2256 and the v0.8.48 work would rebase

Either way your work was valuable in getting ~/.agents/AGENTS.md recognized as a real path. Your call on the direction.

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.

Feat: Support global ~/.agents/AGENTS.md rules

2 participants