SKILL.md
Update Target Projects
Discover and sync all toolkit-using projects, the Codex CLI skill pack, and global Conductor skill symlinks with the latest skills. Skill policy is global-only: local/mixed project skill copies are treated as legacy states to migrate.
Trigger
Use this skill when:
- The post-commit hook reminds you to sync after skill changes
- You want to batch-sync multiple projects at once
- You need to check which projects are out of date
- You want to update the Codex CLI skill pack
- You want to verify global skill symlinks for Conductor autocomplete
- You want to sync curated skills to the public skills repo
Configuration
Codex skill pack location:
$CODEXHOME/skillsifCODEXHOMEis set~/.codex/skills(default)
Project search paths:
$TOOLKITSEARCHPATHenvironment variable (colon-separated paths)~/Projects(default)
Search depth: 4 levels (finds ~/Projects//, ~/Projects///, and ~/Projects////)
Global skills location: ~/.claude/skills/ (symlinks for Conductor autocomplete)
Public skills repo (optional, .claude/public-skills-config.json):
{
"enabled": true,
"path": "/path/to/awesome-claude-skills"
}
Public skills manifest: .claude/public-skills-manifest.json (lists curated skills to publish)
Workflow
Copy this checklist and track progress:
Update Target Projects Progress:
- [ ] Phase 1: Discover projects with toolkit-version.json
- [ ] Phase 1b: Check Codex CLI skill pack status
- [ ] Phase 1c: Check global skill symlinks (Conductor autocomplete)
- [ ] Phase 1d: Detect orphaned skills (removed from toolkit)
- [ ] Phase 1e: Check workstream scripts status
- [ ] Phase 1f: Check skill resolution mode for each project
- [ ] Phase 1g: Check public skills repo status (if configured)
- [ ] Phase 2: Detect activity status for each project
- [ ] Phase 3: Check sync status (OUTDATED vs CURRENT)
- [ ] Phase 4: Display status report (including orphans, global status, and resolution)
- [ ] Phase 5: User selection (what to sync)
- [ ] Phase 6a: Sync Codex skill pack (if selected) — includes deletions
- [ ] Phase 6b: Sync global skill symlinks (if selected)
- [ ] Phase 6c: Sync target projects (if selected) — includes deletions
- [ ] Phase 6d: Sync workstream scripts (if selected)
- [ ] Phase 6g: Sync Codex App setup wrapper (if selected)
- [ ] Phase 6e: Migrate legacy local/mixed projects to global skills (if selected)
- [ ] Phase 6h: Sync public skills repo (if selected)
- [ ] Phase 7: Generate summary report
Phase 1: Discover Projects
See [PROJECTSYNC.md](PROJECTSYNC.md) for detailed discovery and sync logic.
- Find all
toolkit-version.jsonfiles in search paths - Read each file and verify
toolkit_locationmatches - Extract
toolkitcommitandlastsynctimestamps
Phase 1b: Check Codex CLI Skill Pack
See [CODEXSYNC.md](CODEXSYNC.md) for detailed Codex sync logic.
- Discover skills dynamically from toolkit
- Classify each skill: MISSING, SYMLINKCURRENT, COPYOUTDATED, etc.
- Determine overall Codex status
Phase 1c: Check Global Skill Symlinks
See [GLOBALSYNC.md](GLOBALSYNC.md) for detailed global sync logic.
- Scan
~/.claude/skills/for existing entries - Classify each: SYMLINKCURRENT, MISSING, SYMLINKOTHER, REAL_DIR
- Detect orphaned symlinks (pointing to deleted toolkit skills)
- Determine overall global status
Phase 1e: Check Workstream Scripts Status
Detect .workstream/ scripts in target projects and compare file hashes with toolkit:
- Check if target has
.workstream/directory - For each script (
lib.sh,setup.sh,dev.sh,verify.sh,README.md):
- Compare SHA256 hash with toolkit version - Classify: MISSING, CURRENT, OUTDATED
- Check
workstream.json.exampleseparately (it's a reference, not a project file) - Track status in
toolkit-version.jsonunder a"workstream"key
Status determination:
MISSING— no.workstream/directory in targetCURRENT— all script hashes match toolkitOUTDATED— one or more scripts differ from toolkit
Phase 1f: Check Skill Resolution Mode
For each target project, determine current skill resolution state:
See [GLOBALSYNC.md](GLOBALSYNC.md) for the full checkprojectresolution() implementation.
Summary: reads skillresolution and forcelocalskills from toolkit-version.json, counts local skill directories, checks global symlink health via allskillsgloballyusable(), and returns one of the resolution states below.
| Resolution State | Meaning | Available Actions |
|---|---|---|
GLOBAL |
Using global symlinks (healthy) | Keep current state |
LEGACY_LOCAL |
Local/mixed copies shadow globals | Migrate to global (option 8) |
MISSING |
No healthy global symlink state | ⚠️ Repair global symlinks first |
Phase 1g: Check Public Skills Repo
See [PUBLICREPOSYNC.md](PUBLICREPOSYNC.md) for detailed public repo sync logic.
- Read config from
.claude/public-skills-config.json - If not configured or
enabledis false, skip with statusNOT CONFIGURED - Run pre-flight checks (path exists, is git repo, clean working tree)
- Read
.claude/public-skills-manifest.jsonfor the list of curated skills - Validate all skill names match
^[a-z0-9-]+$ - Classify each skill: MISSING, CURRENT, OUTDATED, LOCALMODIFIED, UNMANAGEDPRESENT
Phase 1d: Detect Orphaned Skills
Identify skills that exist in targets but have been removed from toolkit:
- Compare installed skills against current toolkit skills
- Mark as ORPHANED if skill directory no longer exists in toolkit
- Check if orphaned skills have local modifications
See [CODEXSYNC.md](CODEXSYNC.md) and [PROJECTSYNC.md](PROJECTSYNC.md) for orphan detection logic.
Phase 2-3: Activity and Sync Status
For each project:
- Classify activity: ACTIVE (uncommitted), RECENT (modified <24h), DORMANT
- Check if sync needed by comparing commits
Phase 4: Display Status Report
TOOLKIT SYNC STATUS
===================
Toolkit: /path/to/toolkit
Current: abc1234 (2026-01-23)
GLOBAL SKILLS (Conductor Autocomplete)
───────────────────────────────────────
Location: ~/.claude/skills
Status: CURRENT (30 symlinks active)
CODEX CLI SKILL PACK
────────────────────
Location: ~/.codex/skills
Status: {status summary}
PUBLIC SKILLS REPO
──────────────────
Location: {path or "NOT CONFIGURED"}
Status: {READY|NOT CONFIGURED|DIRTY|NOT A GIT REPO}
{If READY, show per-skill status table}
TARGET PROJECTS
───────────────
# Project Sync Status Resolution Migration Activity
─────────────────────────────────────────────────────────────────────
1 ~/Projects/app OUTDATED legacy-local ✓ (30 dirs) DORMANT
2 ~/Projects/api CURRENT global — RECENT
3 ~/Projects/lib CURRENT legacy-local ⚠️ 2 modified ACTIVE
Resolution column values:
global— Skills resolve via~/.claude/skills/symlinkslegacy-local— Project still has local shadow copies that should be removed
Migration column values:
✓ (N dirs)— Can adopt global resolution (N skill directories to remove)⚠️ N modified— Can adopt, but N skills have local modifications—— Already using global resolution (or not applicable)
Phase 5: User Selection
Prompt with options:
- Sync everything (Recommended) — includes global migration for legacy local/mixed projects and public skills repo if configured
- Global skill symlinks only
- Codex skill pack only
- Target projects only
- Select specific items
- Include ACTIVE projects too
- Skip for now
- Migrate legacy local/mixed projects to global skills
- Public skills repo only (visible only if enabled in
.claude/public-skills-config.json)
Option 8 visibility: Only show if at least one project is LEGACY_LOCAL (has local copies and global symlinks are healthy).
Phase 6: Execute Sync
6a: Codex Sync — See [CODEXSYNC.md](CODEXSYNC.md) 6b: Global Skills Sync — See [GLOBALSYNC.md](GLOBALSYNC.md) 6c: Project Sync — See [PROJECTSYNC.md](PROJECTSYNC.md)
Global-only default: When running option 1, treat LEGACY_LOCAL projects as "sync + migrate to global" unless the user explicitly opts out. This prevents local shadow copies from persisting indefinitely.
6d: Workstream Scripts Sync — Copy .workstream/*.sh, README.md, and workstream.json.example to target projects:
- For each target project selected for sync:
- Create .workstream/ directory if missing - Copy scripts: lib.sh, setup.sh, dev.sh, verify.sh - Copy documentation: README.md, workstream.json.example - Run chmod +x .workstream/.sh - Verify with ls -la .workstream/.sh that scripts exist and have executable permissions.
- Compare hashes before copying — skip if CURRENT
- Update
toolkit-version.json"workstream"key with new hashes. Read back the file to confirm valid JSON. - Do NOT copy or overwrite
workstream.json(project-owned config)
6g: Codex App Setup Wrapper Sync — Copy .codex/setup.sh to target projects:
- For each target project selected for sync:
- Create .codex/ directory if missing - Copy setup.sh from toolkit .codex/setup.sh - Run chmod +x .codex/setup.sh - Verify with ls -la .codex/setup.sh that the file exists and is executable.
- Compare hashes before copying — skip if CURRENT
- Do NOT overwrite
.codex/environments/or other Codex App config (project-owned)
6e: Migrate Legacy Local Skills — Migrate from local/mixed to global resolution:
See [GLOBALSYNC.md](GLOBALSYNC.md) for state model and helper definitions.
Pre-flight checks:
- Verify global health:
allskillsglobally_usable()must return true - If unhealthy: abort with message "Global symlinks not healthy. Run sync first (option 1)."
For each selected project:
- Detect modified local skills — skills where current hash != stored hash.
See [GLOBALSYNC.md](GLOBALSYNC.md) for the full findmodifiedskills() implementation. It compares each skill's current SHA-256 hash against the stored hash in toolkit-version.json and returns the list of skill names that differ.
- Show migration preview:
``` ADOPT GLOBAL SKILLS: ~/Projects/app ──────────────────────────────────── Will remove: 30 skill directories Modified skills: 2 (will be backed up) After migration: Skills resolve via ~/.claude/skills/
⚠️ This project will no longer contain .claude/skills/. Collaborators without ~/.claude/skills/ will lose access.
Proceed? [y/N] ```
- If user confirms:
- Back up modified skills to .claude/skills.bak/{skill}/ (if any) - Verify with ls .claude/skills.bak/ that backups were created before proceeding with deletion. - Delete local skill directories: ``bash # Note: glob must be OUTSIDE quotes to expand if [[ -d "$projectpath/.claude/skills" ]]; then rm -rf "$projectpath/.claude/skills/"*/ fi ` - Verify with ls "$projectpath/.claude/skills/" that skill directories were removed. - Update toolkit-version.json: - Set "skillresolution": "global" - Set each file's "resolution": "global" - Read back toolkit-version.json to confirm valid JSON and that skill_resolution is "global". - DO NOT use git rm` — let user review and commit
- Report:
`` ✓ Migrated ~/Projects/app to global skill resolution Removed: 30 skill directories Backed up: 2 modified skills → .claude/skills.bak/ Skills now resolve via: ~/.claude/skills/ ``
6f: Legacy Local Reversion (Deprecated)
Do not offer or execute a "revert to local" flow in normal operation. If a user explicitly demands local copies, treat it as a one-off exception and warn that it diverges from toolkit global-only policy.
Phase 6h: Sync Public Skills Repo
See [PUBLICREPOSYNC.md](PUBLICREPOSYNC.md) for detailed sync logic.
- Read manifest from
.claude/public-skills-manifest.json - For each skill in the manifest:
- If MISSING or OUTDATED: wipe destination, cp -r from toolkit, remove .DSStore files - If LOCALMODIFIED or UNMANAGED_PRESENT: warn and prompt before overwriting - If CURRENT: skip
- Detect orphaned skills (tracked in
toolkit-version.jsonbut removed from manifest) - Update
toolkit-version.jsonin public repo with new hashes - Stage managed paths:
git -C "$path" add skills/ toolkit-version.json - Commit with sync summary
- Prompt before push — never auto-push
Phase 7: Summary Report
SYNC COMPLETE
=============
Global Skills (Conductor Autocomplete):
Symlinks created: 2
Symlinks removed: 1 (orphaned)
Symlinks repaired: 0
Already current: 28
Codex CLI Skill Pack:
Skills updated: 3
Skills deleted: 1 (orphaned)
Already current: 12
Target Projects:
Projects processed: 4
Synced: 2
Skipped: 1 (active)
Current: 1
Skills deleted: 1 (orphaned)
Public Skills Repo:
Skills synced: 3 (2 updated, 1 added)
Skills removed: 0
Already current: 6
Skipped: 0 (local modifications)
Committed: yes
Pushed: no (user declined)
Resolution Changes:
Migrated to global: 1 project (30 local dirs removed)
Modified backed up: 2 skills → .claude/skills.bak/
Deleted Skills (removed from toolkit):
- multi-model-verify
All synced items are now at toolkit commit abc1234
If projects were migrated:
MIGRATION SUMMARY
─────────────────
Projects migrated to global resolution:
✓ ~/Projects/app (30 skills)
✓ ~/Projects/api (30 skills)
These projects now use ~/.claude/skills/ symlinks.
Local skill copies have been removed.
Note: Collaborators need ~/.claude/skills/ symlinks to access skills.
Run this from their toolkit clone: /update-target-projects → option 2
Error Handling
| Situation | Action |
|---|---|
No toolkit-version.json files found in search paths |
Report "No toolkit-using projects found in {search paths}" and list the paths searched; suggest running /setup first |
toolkit_location in a project's toolkit-version.json points to a different toolkit |
Skip that project with a warning; do not sync skills from a mismatched toolkit |
cp -r or symlink creation fails during sync |
Report the specific failure, continue syncing remaining items, include failures in the summary report |
rm -rf fails during global migration (option 8) |
STOP migration for that project, report permission error, do not update toolkit-version.json to "global" |
gh or git commands fail during discovery |
Report the error, skip affected projects, continue with remaining projects |
| Public skills repo path missing or not a git repo | Report specific pre-flight failure, skip public repo sync, continue with other sync operations |
| Public skills repo has dirty working tree | Report "public repo has uncommitted changes", skip public repo sync |
Manifest skill name fails ^[a-z0-9-]+$ validation |
Abort public repo sync entirely (path traversal risk) |
| Skill has local modifications in public repo | Warn and prompt before overwriting — never silently replace |
Edge Cases
See [EDGECASES.md](EDGECASES.md) for handling:
- Codex directory doesn't exist
- No projects found
- Project uses different toolkit
- Git not available
- Public skills repo not configured / missing path / dirty / local modifications
- Sync conflicts
REMINDER: Toolkit-managed projects should use global resolution. Local skill copies are legacy migration debt: back up modified local skills, remove local shadow copies, and keep toolkit-version.json aligned to "skill_resolution": "global".