COPILOT_CUSTOM_INSTRUCTIONS_DIRS only half-honored by instruction loader (1.0.54)
- Lenguaje dominante
- Shell
- Estrellas
- 11.2k
- Forks
- 1.9k
- Merge medio
- 14 h 16 min
- PR fusionados (30 d)
- 6
Descripción
# Bug: `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` only honored for AGENTS.md + `.github/instructions/**`, not for `.github/copilot-instructions.md` / `CLAUDE.md` / `GEMINI.md`
**CLI version:** 1.0.54 (Windows, win32-x64)
**Platform:** Windows 11 / PowerShell
**Sentiment:** frown
## Summary
`COPILOT_CUSTOM_INSTRUCTIONS_DIRS` is documented in `/help` and in
`copilot --help` as a way to add **additional directories** to the
search list for custom instruction files:
> `COPILOT_CUSTOM_INSTRUCTIONS_DIRS`: comma-separated list of additional
> directories to search for custom instructions files (in addition to git
> root and current working directory).
In practice the env var is only honored for **two** of the discoverable
filenames. The other documented filenames in those same directories are
silently skipped, so users who point the env var at a sibling repo with
their canonical `.github/copilot-instructions.md` (or a `CLAUDE.md`) get
none of that content loaded.
## Repro
1. Have a directory (not cwd, not git root) containing the standard
instruction files, e.g.:
```
D:\UserRepos\zahen\
AGENTS.md (stub: "see canonical file")
CLAUDE.md (stub)
.github\copilot-instructions.md (canonical, real content)
.copilot\copilot-instructions.md (stub)
.ai\index.md
```
2. From a different cwd / different git repo, launch the CLI with:
```powershell
$env:COPILOT_CUSTOM_INSTRUCTIONS_DIRS = "D:\UserRepos\zahen"
copilot
```
3. Observe in `/env` (or in the agent system prompt) which instruction
files were discovered.
## Expected
All of these files in `D:\UserRepos\zahen\` should be loaded
(equivalent to having those dirs treated as additional git root /
cwd locations):
- `AGENTS.md`
- `CLAUDE.md`
- `GEMINI.md`
- `.github/copilot-instructions.md`
- `.github/instructions/**/*.instructions.md`
## Actual
Only `AGENTS.md` and `.github/instructions/**/*.instructions.md` are
loaded from the env-var dir. `CLAUDE.md`, `GEMINI.md`, and
`.github/copilot-instructions.md` from the same directory are **not**
loaded, even though they exist and are well-formed.
This is especially painful because in many setups (including the
official-looking convention shown in `/help`),
`.github/copilot-instructions.md` is the **canonical** file and the
sibling `AGENTS.md` / `CLAUDE.md` are pointer stubs. Loading only the
stubs leaves the agent with effectively no instructions.
## Root cause (reading `app.js` from 1.0.54)
In `async function B0i(t, e, r, n, o)` (the central instruction loader):
```js
let s = process.env.COPILOT_CUSTOM_INSTRUCTIONS_DIRS?.split(",")... ?? [];
let a = (o?.additionalDirs ?? [])...;
let l = [...new Set([...s, ...a])]; // merged extra dirs
```
`l` is then passed to exactly two collectors:
- `V0i(t, r, l)` -- scans `.github/instructions/**/*.instructions.md`
inside each dir in `l`. [ok]
- `X0i(t, l)` -- scans nested `AGENTS.md` inside each dir in `l`. [ok]
But all of the following are computed only from `t` (cwd) and `r` (git
root); `l` is never threaded through:
- `m = MYr(t)`, `_ = MYr(r)` -- `.github/copilot-instructions.md`
- `h = RYr(t)`, `S = RYr(r)` -- `AGENTS.md` (top-of-dir)
- `g = PYr(t)`, `C = PYr(r)` -- `CLAUDE.md`
- `A = NYr(t)`, `I = NYr(r)` -- `GEMINI.md`
- `f = H0i(n)` -- `$HOME/.copilot/copilot-instructions.md`
So the env-var dirs are effectively second-class: they participate in
two filename searches but not in the main `MYr/PYr/NYr/RYr` searches
that pick up the most commonly used instruction filenames.
## Suggested fix
Treat each entry in `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` as an additional
"root" alongside `t` and `r` for **all** filename searches (i.e., run
`MYr/RYr/PYr/NYr` over each dir in `l` and merge the results into the
existing `Z` / `se` arrays). Behavior should match what users get if
they simply launch the CLI from that directory.
Alternatively (less surprising for users): document explicitly that the
env var only adds dirs to the `AGENTS.md` + `.github/instructions/**`
search, and recommend an `AGENTS.md`-only layout in those dirs. But the
current `/help` text reads as a general "additional directories" hint,
which is what set the wrong expectation here.
## Workarounds users currently need
- Duplicate the canonical content into `AGENTS.md` in the env-var dir
(defeats the "single source of truth" stub layout).
- Move/symlink the canonical content into `.github/instructions/...`
(requires renaming and reorganization of an existing repo).
- Launch the CLI with `-C ` so it's treated as cwd.
## Diagnostic info from my repro
- `COPILOT_CUSTOM_INSTRUCTIONS_DIRS = D:\UserRepos\zahen`
- Files present and well-formed in that dir:
`AGENTS.md`, `CLAUDE.md`, `.github\copilot-instructions.md`,
`.copilot\copilot-instructions.md`, `.ai\index.md`, `README.md`.
- Result: the agent system prompt enumerates
`D:\UserRepos\zahen\AGENTS.md` (loaded), but the much richer
`D:\UserRepos\zahen\.github\copilot-instructions.md` is not loaded.
Thanks!
Guía de contribución
Línea de trabajo
Start in app.js at async function B0i and trace how the merged extra directories are passed to V0i and X0i but not the MYr, RYr, PYr, and NYr searches. Update the loading behavior so each directory in COPILOT_CUSTOM_INSTRUCTIONS_DIRS is treated as an additional root for all listed instruction filenames, then verify the files appear in /env or the agent system prompt.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- javascript, powershell
- Área
- cli
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Tranquilo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 55/100