gh skill: lock file ignores XDG_STATE_HOME, so it splits from the Vercel skills CLI lock it is meant to share

Open Beginner friendly
#14,895 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
62/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
go
Domain
cli

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

needs-triage
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
  1. export XDG_STATE_HOME=$HOME/.local/state
  2. Install a skill with the Vercel CLI: npx skills add obra/superpowers -g. It is recorded in ~/.local/state/skills/.skill-lock.json.
  3. Install a skill with gh: gh skill install cloudflare/skills wrangler --scope user --agent opencode. It is recorded in ~/.agents/.skill-lock.json.
  4. 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

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cli/cli

All issues in cli/cli

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.