hub

SKILL.md

Hub

Manage current directory as a hub. Shell hubs shows all; this skill manages one.

Registry

~/.claude/hubs/registry.json - single source of truth:

{
  "hubs": [
    {
      "name": "security",
      "path": "/Users/brew/learning/cyber",
      "status": "active",
      "last_accessed": 1737785000,
      "progress": "24/100",
      "next_action": "Complete CSRF exercise",
      "note": "working through OWASP top 10",
      "current_level": 2,
      "levels_completed": [0, 1]
    },
    {
      "name": "mountain",
      "path": "/Users/brew/projects/mountain",
      "status": "active",
      "last_accessed": 1737780000,
      "progress": "",
      "next_action": "Fix auth bug",
      "note": ""
    }
  ]
}

All fields live here. No separate hub.json files. Shell reads this, Claude writes this.

Commands

/hub (no args)

Check if current directory is a hub.

  • If yes: show status, offer to update
  • If no: offer to add it

/hub add [name]

Add current directory as hub. Name defaults to directory name.

/hub progress

Set progress (e.g., "30/100", "3/10 chapters", or "" to clear).

/hub next

Set next action.

/hub note

Set note.

/hub done

Update last_accessed to now. Run this after meaningful work, or Claude runs it automatically after commits.

/hub archive

Set status to "archived". Hidden from shell hubs output.

/hub unarchive

Set status to "active".

/hub remove

Remove from registry entirely.

Implementation

Use jq via Bash. Registry path: ~/.claude/hubs/registry.json

# Check if current dir is a hub
jq --arg p "$(pwd)" '.hubs[] | select(.path == $p)' ~/.claude/hubs/registry.json

# Add hub
jq --arg name "foo" --arg path "$(pwd)" --arg now "$(date +%s)" \
  '.hubs += [{"name": $name, "path": $path, "status": "active", "last_accessed": ($now | tonumber), "progress": "", "next_action": "", "note": ""}]' \
  ~/.claude/hubs/registry.json > /tmp/reg.json && mv /tmp/reg.json ~/.claude/hubs/registry.json

# Update field
jq --arg p "$(pwd)" --arg val "new value" \
  '(.hubs[] | select(.path == $p) | .next_action) = $val' \
  ~/.claude/hubs/registry.json > /tmp/reg.json && mv /tmp/reg.json ~/.claude/hubs/registry.json

# Update last_accessed
jq --arg p "$(pwd)" --arg now "$(date +%s)" \
  '(.hubs[] | select(.path == $p) | .last_accessed) = ($now | tonumber)' \
  ~/.claude/hubs/registry.json > /tmp/reg.json && mv /tmp/reg.json ~/.claude/hubs/registry.json

Auto-update

After commits in a hub directory, Claude should run /hub done to update last_accessed.

Weekly Installs
9
Repository
cerico/macfair
First Seen
Feb 24, 2026
Installed on
trae9
claude-code9
github-copilot9
codex9
windsurf9
kiro-cli9