fix(setup): make gstack skills discoverable by Factory Droid#659
Closed
morluto wants to merge 3 commits intogarrytan:mainfrom
Closed
fix(setup): make gstack skills discoverable by Factory Droid#659morluto wants to merge 3 commits intogarrytan:mainfrom
morluto wants to merge 3 commits intogarrytan:mainfrom
Conversation
…roid
## Problem
Droid scans ~/.factory/skills/ for skill directories. It follows *relative*
symlinks pointing to ../../.agents/skills/{skill}, but ignores absolute paths.
When setup ran with --host factory, it created absolute symlinks:
ln -snf /Users/will/gstack/.factory/skills/gstack-qa ~/.factory/skills/gstack-qa
Droid ignored these entirely — no skills appeared in the '/' menu.
## Root Cause
Droid's filesystem scanner only resolves relative symlinks. Absolute symlinks
pointing to paths outside ~/.agents/skills/ are silently skipped.
## Reproduction
1. Clone gstack: git clone https://github.com/garrytan/gstack.git ~/gstack
2. Run setup: cd ~/gstack && ./setup --host factory
3. Check symlinks: ls -la ~/.factory/skills/ | grep gstack
4. Observe: gstack symlinks are absolute paths — WRONG
5. In Droid, type '/' — no gstack skills visible
## Fix
Change symlink creation from absolute to relative paths:
ln -snf "../../.agents/skills/$skill_name" "$target"
Also removes the 'gstack' skip that prevented linking the root skill.
## Validation
After fix:
- ls ~/.factory/skills/gstack-qa points to '../../.agents/skills/gstack-qa'
- Droid '/' menu shows gstack skills after restart
- Verified all working skills (debug, fix, test) use same relative pattern
## Problem
Skills were installed to ~/gstack/.factory/skills/ (a project subdirectory).
Droid never scans this location — it only scans ~/.factory/skills/ and reads
skill files from ~/.agents/skills/.
Even with correct relative symlinks in ~/.factory/skills/, Droid could not load
skills because the actual skill files didn't exist in ~/.agents/skills/.
## Root Cause
Droid's skill loading requires skill files to exist in ~/.agents/skills/.
Symlinks in ~/.factory/skills/ point to skill locations, but the files must
actually be present at the target.
## Reproduction
1. Run: cd ~/gstack && ./setup --host factory
2. Check: ls ~/.agents/skills/ | grep gstack
3. Observe: no gstack directories — SKILL.md files are in ~/gstack/.factory/skills/
4. Droid reports skills as unavailable
## Fix
Copy skills as real directories into ~/.agents/skills/:
mkdir -p "$HOME/.agents/skills"
for skill_dir in "$factory_dir"/gstack*/; do
cp -r "$skill_dir" "$HOME/.agents/skills/"
done
This ensures Droid can read the actual SKILL.md files.
## Validation
After fix:
- ls ~/.agents/skills/ shows all 31 gstack skill directories
- Each directory contains SKILL.md and supporting files
- Droid can read skill metadata from ~/.agents/skills/
…=github
## Problem
Droid maintains a skill registry at ~/.agents/.skill-lock.json. It ONLY loads
entries where sourceType=github. Entries with sourceType=local are silently ignored.
The old setup registered skills with sourceType=local — producing dead lockfile
entries that Droid never read.
## Root Cause
Droid's lockfile reader checks 'sourceType' to determine if a skill should be
loaded. No working Droid skill uses sourceType=local — it's a no-op.
## Reproduction
1. Run: cd ~/gstack && ./setup --host factory
2. Check lockfile: python3 -c "import json; l=json.load(open('/Users/will/.agents/.skill-lock.json')); print({k:v['sourceType'] for k,v in l['skills'].items() if 'gstack' in k})"
3. Observe: all gstack entries have sourceType=local — NOT LOADED
4. Compare: working skills (debug, fix, test) have sourceType=github
## Fix
Register skills with sourceType=github in ~/.agents/.skill-lock.json:
lock['skills'][entry] = {
'source': 'gstack/' + entry,
'sourceType': 'github',
'sourceUrl': 'file://' + os.path.join(agents_skills, entry),
...
}
This matches the format of all working Droid skills.
## Validation
After fix:
- python3 -c "import json; l=json.load(open('/Users/will/.agents/.skill-lock.json')); print(sum(1 for v in l['skills'].values() if v.get('sourceType')=='github'))"
- Shows count of github-sourced skills includes gstack
- Droid '/' menu shows gstack skills (e.g. /qa)
- Skill name comes from 'name:' field in SKILL.md, not directory name
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Skills installed via
cd ~/gstack && ./setup --host factorydid not appear in Droid's/menu. The skills existed on disk but were invisible to Droid's discovery system.Reproduction
/— no gstack skills appear (debug, fix, test, qa, etc. are missing)Root Cause: Three Bugs in
link_factory_skill_dirs()Bug 1: Wrong target for installed skill contents
The original install did create entries in
~/.factory/skills/, but they pointed to the wrong place for discovery. gstack generated Factory skills in~/gstack/.factory/skills/and then linked~/.factory/skills/entries back into that project directory, while Droid expects the canonical skill contents to live under~/.agents/skills/.Bug 2: Absolute symlinks
gstack created absolute symlinks in
~/.factory/skills/:ln -snf /Users/will/gstack/.factory/skills/gstack-qa ~/.factory/skills/gstack-qaDroid follows only relative symlinks (
../../.agents/skills/{skill}). Absolute paths are ignored.Bug 3: Wrong
sourceTypein lockfilegstack registered entries with
sourceType: "local":{ "sourceType": "local", "sourceUrl": "file:///Users/will/gstack/.factory/skills/gstack-qa" }Droid's lockfile reader ignores
sourceType: "local"entirely. Zero of the 57 working skills use this value — all usesourceType: "github".How Droid Discovers Skills (Two-Tier System)
A skill appears in
/when both conditions are met:~/.factory/skills/pointing to~/.agents/skills/{skill}sourceType: "github"in~/.agents/.skill-lock.jsonThe Fix (3 commits)
Commit 1: Use relative symlinks in
~/.factory/skills/Changed from absolute paths to the pattern all working skills use:
This commit also removes the old skip for the root
gstackskill, so that directory can now be linked like the rest of the skill set.Commit 2: Copy skills to
~/.agents/skills/Droid reads skill files from
~/.agents/skills/. Symlinks pointing into~/gstack/.factory/skills/do not work — must be real directories.This means Factory now reads a copied snapshot from
~/.agents/skills/, not directly from the repo checkout. If you edit a skill in~/gstack, rerun./setup --host factoryto refresh Droid's copy.Commit 3: Register with
sourceType: "github"Updated the Python lockfile registration script to use the only
sourceTypeDroid actually loads:{ "source": "gstack/gstack-qa", "sourceType": "github", "sourceUrl": "file:///Users/will/.agents/skills/gstack-qa" }Validation
After applying the fix: