Codex CLI doesn't follow symlinks in .agents/skills/ — skills not discovered
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
## Problem
`create_agents_sidecar()` in `setup` creates symlinks in `.agents/skills/` for each gstack skill:
```
.agents/skills/gstack-qa -> /path/to/.claude/skills/gstack/.agents/skills/gstack-qa/
```
Codex CLI (v0.116.0) does not follow symlinks when scanning `.agents/skills/` for skill directories. Only real directories (like `supabase-postgres-best-practices`) are discovered. This means gstack skills are invisible to Codex's automatic skill discovery.
## Evidence
When asked to list available skills, Codex reports:
> "The repo-local .agents/skills only contains the Supabase skill"
It then manually explores `.claude/skills/gstack/.agents/skills/` to find them — proving the SKILL.md files are correct, just not discovered via the symlink path.
## Root cause
In `setup`, the `create_agents_sidecar()` function uses `ln -snf` for skill directories:
```bash
ln -snf "$skill_dir" "$root_skill_dir/$skill_name"
```
Codex likely uses a directory listing method that filters out symlinks (e.g., checking `d_type` or using `stat` instead of following links).
## Workaround
Replace symlinks with real directory copies:
```bash
for link in .agents/skills/gstack-*; do
if [ -L "$link" ]; then
target=$(readlink "$link")
rm "$link"
cp -r "$target" "$link"
fi
done
```
## Suggested fix
In `create_agents_sidecar()`, use `cp -r` instead of `ln -snf` when `--host codex` is specified. This duplicates ~30KB of SKILL.md files per skill but ensures automatic discovery works. The root `gstack` sidecar (which has runtime assets like `bin/` and `browse/`) should remain symlinked to avoid duplicating large binaries — or alternatively, copy SKILL.md and symlink only the heavy directories.
## Environment
- Codex CLI: v0.116.0
- gstack: v0.10.2.0
- macOS Darwin 25.3.0
## Additional issue: global ~/.codex/skills/gstack/ missing runtime assets
The `link_codex_skill_dirs()` function points `~/.codex/skills/gstack` at `.agents/skills/gstack/` in the gstack source tree, which only contains `SKILL.md`. The workspace sidecar version (created by `create_agents_sidecar()`) includes `bin/`, `browse/`, `qa/`, `review/`, and `ETHOS.md` symlinks. The SKILL.md preamble runs `~/.codex/skills/gstack/bin/gstack-update-check` which fails because `bin/` doesn't exist at that path.
Fix: `link_codex_skill_dirs()` should point `~/.codex/skills/gstack` at the workspace sidecar, not the generated skeleton.
Contributor guide
Research direction
Start by reading setup's create_agents_sidecar() and link_codex_skill_dirs() paths. Reproduce Codex v0.116.0 discovery with symlinked and copied skills, then verify both workspace discovery and the global ~/.codex/skills/gstack/ runtime assets. Done means gstack skills are automatically discovered and the update-check path has the required bin/ assets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100