Skip to content

/skills UI ignores --config-dir (reads ~/.copilot/settings.json directly) #2926

@steveisok

Description

@steveisok

Summary

When launching with copilot --config-dir <alt>, the core skill loader correctly reads <alt>/settings.json — the <available_skills> block in the session's system prompt matches the alt settings. However, the interactive /skills slash-command UI appears to read ~/.copilot/settings.json via a hardcoded path, so the "checked/unchecked" state it displays does not reflect the active session's effective configuration when --config-dir is used.

Version / environment

  • GitHub Copilot CLI 1.0.35-6
  • macOS Darwin 25.4.0 arm64

Impact

Two surfaces of the same setting disagree within one session:

  • Loader (authoritative, drives what the model can invoke): respects --config-dir.
  • /skills UI: ignores --config-dir.

This breaks workflows that use --config-dir for per-session skill/plugin overrides (e.g. ephemeral wrapper scripts that copy the real config dir to a temp location, mutate settings.json, and launch). The skill is genuinely on/off as intended, but the user's primary visibility tool (/skills) doesn't reflect it.

Reproduction

# 1. Pick any user skill currently enabled (not in disabledSkills), e.g. skill-builder.
#    Assume ~/.copilot/settings.json has disabledSkills = [].

# 2. Build an alt config dir with skill-builder disabled.
ALT=$(mktemp -d)
for e in ~/.copilot/*; do
  b=$(basename "$e")
  [[ $b == config.json || $b == settings.json ]] && continue
  ln -s "$e" "$ALT/$b"
done
sed 's|^[[:space:]]*//.*$||' ~/.copilot/config.json | jq . > "$ALT/config.json"
jq '.disabledSkills = ["skill-builder"]' ~/.copilot/settings.json > "$ALT/settings.json"

# 3. Non-interactive check — loader respects alt:
copilot --config-dir "$ALT" -p "List skill names in your <available_skills>."
# → skill-builder is ABSENT ✅

# 4. Interactive check — /skills UI does NOT respect alt:
copilot --config-dir "$ALT"
# > /skills
# → skill-builder is shown as CHECKED ❌ (expected: unchecked)

Additional evidence

  • After step 4, stat on $ALT/settings.json shows mtime unchanged since creation — /skills neither wrote through to it nor invalidated it.
  • ~/.copilot/settings.json mtime is also unchanged — so /skills reads it but doesn't need to write on a pure view.
  • In an earlier test where settings.json in the alt dir was a symlink back to the real file, toggling /skills inside a --config-dir session leaked the change straight into ~/.copilot/settings.json. Further suggests the UI path is resolved against $HOME rather than the config-dir argument.

Expected

/skills UI should read (and write) <config-dir>/settings.json when --config-dir is passed, consistent with the loader and with how other config files under the dir are handled. Same likely applies to /plugin and /model views if they share this code path.

Workaround

None external to the CLI. A wrapper can make --config-dir affect actual skill-availability behavior, but cannot make /skills UI agree with it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:configurationConfig files, instruction files, settings, and environment variablesarea:pluginsPlugin system, marketplace, hooks, skills, extensions, and custom agents

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions