fix: preserve AGENTS boundary behavior
- 🛠️ Keep home-level context when no repository root exists.\n- ✅ Exclude home context only for nested repositories.\n- 🧪 Cover repositories whose root is above home.
This commit is contained in:
@@ -65,7 +65,7 @@ Put broad, durable project background in `AGENTS.md`. Reserve `RULES.md` for sho
|
||||
| `opencode` | `.config/opencode/AGENTS.md` | User | User file `~/.config/opencode/AGENTS.md` only. |
|
||||
| `github` | `.github/copilot-instructions.md` | User + project | Project file `<cwd>/.github/copilot-instructions.md` only (no ancestor walk-up), plus a user-global `~/.copilot/copilot-instructions.md` (relocate with `COPILOT_HOME`). `AGENTS.md` candidates from `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` are also considered at user scope, where normal one-user-file deduplication applies. |
|
||||
| `agents` | `.agent/AGENTS.md`, `.agents/AGENTS.md` | User + project | User files from `~/.agent/` and `~/.agents/`; project files discovered while walking up from the current directory to the repository root. |
|
||||
| `agents-md` | `AGENTS.md` | Project | Standalone (non-config-directory) `AGENTS.md` files, discovered by walking up from the current directory to the repository root and, when that repository is nested under the user's home directory, through enclosing workspace directories up to but not including the home directory. With no repository root, discovery uses the home directory as the boundary for sessions under home. Files whose parent directory name starts with `.` are ignored — those belong to a config-directory provider instead. |
|
||||
| `agents-md` | `AGENTS.md` | Project | Standalone (non-config-directory) `AGENTS.md` files, discovered by walking up from the current directory to the repository root and, when that repository is nested under the user's home directory, through enclosing workspace directories up to but not including the home directory. With no repository root, discovery uses the home directory as the boundary for sessions under home and includes that boundary file. Files whose parent directory name starts with `.` are ignored — those belong to a config-directory provider instead. |
|
||||
| `github` | `.github/instructions/**/*.instructions.md` | Project rules | GitHub Copilot / VS Code instruction files become rules. `applyTo: '*'`, `applyTo: '**'`, or `applyTo: '**/*'` is injected as always-apply content; other `applyTo` globs are listed in the rulebook with a generated description when needed and are readable as `rule://<name>`. Missing `applyTo` also produces a rulebook entry and a discovery warning. |
|
||||
|
||||
Providers marked "(no ancestor walk-up)" only look in the current working directory's config directory. If you need ancestor walk-up behavior, prefer the native `.omp/AGENTS.md` format or a standalone `AGENTS.md` (the `agents-md` provider), or launch `omp` from the directory that holds the config directory.
|
||||
|
||||
+1
-1
@@ -202,7 +202,7 @@ No fallback search is performed for missing assets.
|
||||
- **Skills**: named, optional capability packs selected by task context or explicitly requested
|
||||
- **AGENTS.md/context files**: persistent instruction files loaded as context-file capability and merged by level/depth rules
|
||||
|
||||
`src/discovery/agents-md.ts` walks ancestor directories from `cwd` to discover standalone `AGENTS.md` files. For repositories nested under the user's home directory, it continues through enclosing workspace directories up to but not including the home directory. Otherwise it stops at the repository root, or at the filesystem root when no repository root is known outside home. Files in hidden owner directories are skipped.
|
||||
`src/discovery/agents-md.ts` walks ancestor directories from `cwd` to discover standalone `AGENTS.md` files. For repositories nested under the user's home directory, it continues through enclosing workspace directories up to but not including the home directory. With no repository root under home, the home boundary remains included. Otherwise it stops at the repository root, or at the filesystem root when no repository root is known outside home. Files in hidden owner directories are skipped.
|
||||
|
||||
### Skills vs slash commands
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed standalone `AGENTS.md` discovery stopping at nested Git repository roots, so enclosing workspace instructions are loaded while home-level instructions remain scoped correctly.
|
||||
|
||||
## [17.2.9] - 2026-08-05
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
@@ -55,15 +55,16 @@ export async function loadAgentsMd(ctx: LoadContext): Promise<LoadResult<Context
|
||||
const filesystemRoot = path.parse(cwd).root;
|
||||
const cwdIsUnderHome = isWithin(home, cwd);
|
||||
const repoIsUnderHome = repoRoot !== null && isWithin(home, repoRoot);
|
||||
const scanToHome = cwdIsUnderHome && (repoRoot === null || repoIsUnderHome);
|
||||
const boundary = scanToHome ? home : (repoRoot ?? filesystemRoot);
|
||||
const includeBoundary = !samePath(boundary, home) && !(repoRoot === null && !cwdIsUnderHome);
|
||||
const scanToHome = repoRoot !== null && cwdIsUnderHome && repoIsUnderHome;
|
||||
const boundary = scanToHome ? home : (repoRoot ?? (cwdIsUnderHome ? home : filesystemRoot));
|
||||
const includeBoundary = repoRoot === null ? cwdIsUnderHome : !samePath(boundary, home);
|
||||
const excludeHome = repoRoot !== null && cwdIsUnderHome;
|
||||
|
||||
let current = cwd;
|
||||
while (true) {
|
||||
const atBoundary = samePath(current, boundary);
|
||||
const atHome = samePath(current, home);
|
||||
if (!atHome && !(atBoundary && !includeBoundary)) {
|
||||
const atHome = excludeHome && samePath(current, home);
|
||||
if (!(atHome || (atBoundary && !includeBoundary))) {
|
||||
const candidate = path.join(current, "AGENTS.md");
|
||||
const content = await readFile(candidate);
|
||||
|
||||
|
||||
@@ -59,7 +59,25 @@ describe("standalone AGENTS.md discovery", () => {
|
||||
const context: LoadContext = { cwd, home, repoRoot: null };
|
||||
const result = await loadAgentsMd(context);
|
||||
|
||||
expect(result.items.map(file => file.path)).toEqual([cwdAgents, intermediateAgents]);
|
||||
expect(result.items.map(file => file.path)).toEqual([cwdAgents, intermediateAgents, homeAgents]);
|
||||
});
|
||||
|
||||
test("excludes home context when the repository root is above home", async () => {
|
||||
const workspaceRoot = path.join(tempDir, "workspace");
|
||||
const home = path.join(workspaceRoot, "user");
|
||||
const repoRoot = workspaceRoot;
|
||||
const cwd = path.join(home, "project");
|
||||
fs.mkdirSync(cwd, { recursive: true });
|
||||
|
||||
const repoAgents = path.join(repoRoot, "AGENTS.md");
|
||||
const homeAgents = path.join(home, "AGENTS.md");
|
||||
writeAgents(repoAgents, "repo context");
|
||||
writeAgents(homeAgents, "home context");
|
||||
|
||||
const context: LoadContext = { cwd, home, repoRoot };
|
||||
const result = await loadAgentsMd(context);
|
||||
|
||||
expect(result.items.map(file => file.path)).toEqual([repoAgents]);
|
||||
});
|
||||
|
||||
test("keeps the repository root boundary when the repository is outside home", async () => {
|
||||
|
||||
Reference in New Issue
Block a user