| name | update-target-projects |
| description | Discover and sync all toolkit-using projects with the latest skills. Use when skills are modified, after the post-commit hook reminds you, or to batch-sync multiple projects. |
| toolkit-only | true |
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:
$CODEX_HOME/skills if CODEX_HOME is set
~/.codex/skills (default)
Project search paths:
$TOOLKIT_SEARCH_PATH environment 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 PROJECT_SYNC.md for detailed discovery and sync logic.
- Find all
toolkit-version.json files in search paths
- Read each file and verify
toolkit_location matches
- Extract
toolkit_commit and last_sync timestamps
Phase 1b: Check Codex CLI Skill Pack
See CODEX_SYNC.md for detailed Codex sync logic.
- Discover skills dynamically from toolkit
- Classify each skill: MISSING, SYMLINK_CURRENT, COPY_OUTDATED, etc.
- Determine overall Codex status
Phase 1c: Check Global Skill Symlinks
See GLOBAL_SYNC.md for detailed global sync logic.
- Scan
~/.claude/skills/ for existing entries
- Classify each: SYMLINK_CURRENT, MISSING, SYMLINK_OTHER, 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.example separately (it's a reference, not a project file)
- Track status in
toolkit-version.json under a "workstream" key
Status determination:
MISSING — no .workstream/ directory in target
CURRENT — all script hashes match toolkit
OUTDATED — one or more scripts differ from toolkit
Phase 1f: Check Skill Resolution Mode
For each target project, determine current skill resolution state:
See GLOBAL_SYNC.md for the full check_project_resolution() implementation.
Summary: reads skill_resolution and force_local_skills from toolkit-version.json,
counts local skill directories, checks global symlink health via all_skills_globally_usable(),
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 PUBLIC_REPO_SYNC.md for detailed public repo sync logic.
- Read config from
.claude/public-skills-config.json
- If not configured or
enabled is false, skip with status NOT CONFIGURED
- Run pre-flight checks (path exists, is git repo, clean working tree)
- Read
.claude/public-skills-manifest.json for the list of curated skills
- Validate all skill names match
^[a-z0-9-]+$
- Classify each skill: MISSING, CURRENT, OUTDATED, LOCAL_MODIFIED, UNMANAGED_PRESENT
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 CODEX_SYNC.md and PROJECT_SYNC.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/ symlinks
legacy-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 CODEX_SYNC.md
6b: Global Skills Sync — See GLOBAL_SYNC.md
6c: Project Sync — See PROJECT_SYNC.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 GLOBAL_SYNC.md for state model and helper definitions.
Pre-flight checks:
- Verify global health:
all_skills_globally_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 GLOBAL_SYNC.md for the full find_modified_skills() 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:
-
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 PUBLIC_REPO_SYNC.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 .DS_Store files
- If LOCAL_MODIFIED or UNMANAGED_PRESENT: warn and prompt before overwriting
- If CURRENT: skip
- Detect orphaned skills (tracked in
toolkit-version.json but removed from manifest)
- Update
toolkit-version.json in 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 EDGE_CASES.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".