gh skill: lock file ignores XDG_STATE_HOME, so it splits from the Vercel skills CLI lock it is meant to share
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 62/100
Research direction
The path is built in lockfilePath() in internal/skills/lockfile/lockfile.go, which joins os.UserHomeDir() with .agents/.skill-lock.json. Read that function and the lock-file tests next to it, then check whether the team wants to match Vercel's $XDG_STATE_HOME/skills/ path before changing it. Done means the function honors XDG_STATE_HOME and falls back to ~/.agents when it is unset, with a test covering both cases.
Written by the indexing model from the issue text.
Description
Describe the bug
internal/skills/lockfile/lockfile.go says the skill lock file is shared with the Vercel skills CLI on purpose:
// lockVersion must match Vercel's CURRENT_LOCK_VERSION for interop.
But the two tools do not resolve the same path when XDG_STATE_HOME is set:
| Tool | Lock path when XDG_STATE_HOME is set |
|---|---|
Vercel skills (getSkillLockPath in src/skill-lock.ts) |
$XDG_STATE_HOME/skills/.skill-lock.json |
gh skill (lockfilePath()) |
$HOME/.agents/.skill-lock.json (always) |
So with XDG_STATE_HOME set, each tool writes its own lock file and neither sees the other's installs. The shared format does not help because the files are different.
There is also no way to move the gh lock file out of $HOME/.agents (no env var or flag), which matters for users who keep $HOME clean with XDG directories.
Affected version
gh version 2.102.1 (2026-10-21)
Also checked against trunk: lockfilePath() still joins os.UserHomeDir() with .agents/.skill-lock.json.
Steps to reproduce the behavior
export XDG_STATE_HOME=$HOME/.local/state- Install a skill with the Vercel CLI:
npx skills add obra/superpowers -g. It is recorded in~/.local/state/skills/.skill-lock.json. - Install a skill with gh:
gh skill install cloudflare/skills wrangler --scope user --agent opencode. It is recorded in~/.agents/.skill-lock.json. - Each lock file lists only its own tool's skills.
Expected vs actual behavior
Expected: gh skill resolves the lock path the same way as the Vercel CLI, so both tools share one lock file:
func lockfilePath() (string, error) {
if state := os.Getenv("XDG_STATE_HOME"); state != "" {
return filepath.Join(state, "skills", lockFile), nil
}
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, agentsDir, lockFile), nil
}
This keeps the current default for users without XDG_STATE_HOME.
Actual: gh always writes $HOME/.agents/.skill-lock.json, and the two tools keep separate lock files.
Related: #14118 / #14260 added PI_CODING_AGENT_DIR support for the same kind of hardcoded path. vercel-labs/skills#2144 (open) proposes AGENTS_HOME for the same shared store; if it merges, gh would need to follow it too to keep the interop.
Logs
$ echo $XDG_STATE_HOME
/home/<user>/.local/state
$ ls -l ~/.local/state/skills/.skill-lock.json ~/.agents/.skill-lock.json
-rw-r--r-- 1 <user> <user> 456 Oct 30 18:29 /home/<user>/.agents/.skill-lock.json
-rw-r--r-- 1 <user> <user> 677 Aug 21 10:06 /home/<user>/.local/state/skills/.skill-lock.json
The first file has only the skill installed with gh skill install. The second has only the skill installed with npx skills add.
- Dominant language
- Go
- Stars
- 46.8k
- Forks
- 9.2k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 60
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from cli/cli
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
docs: cover gh api mutation pitfalls in the gh skillMay be free again A pull request for this issue was closed without being merged. Openenhancement
Difficulty 2/5 Half a day Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
`gh skill update` help incorrectly promises to preserve locally added filesPossibly taken @rajpreetcodes claimed this 18 days ago. Openbug gh-skill priority-3
Difficulty 1/5 Under an hour Newbie friendliness 82/100
cli/cli#14647 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
`gh` skill description does not tell agents when to use it, so it is skipped for tasks it coversPossibly taken @littfed claimed this 23 days ago. Openenhancement
Difficulty 1/5 Under an hour Newbie friendliness 85/100
cli/cli#14621 · 2 comments · 1 reaction ·
Maintainers usually reply within 1 day
-
gh pr close --comment silently discards the comment when PR is already closed or mergedMay be free again @bunnysayzz claimed this 55 days ago, and no pull request is open. Openbug gh-pr priority-2 stale
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
kagent-dev/kagent#3462 ·
Maintainers usually reply within 1 day
-
netrc credential source accepts a password with an embedded CR/LF that every other source rejectsOpenagent-butler-finding bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
jordansmall/spindrift#6268 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 7 days
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/opentelemetry-go-compile-instrumentation#1666 ·
Maintainers usually reply within 2 days