Maps .agents/skills (global and per project) into .claude/skills so every skill is active, without duplicating existing ones

Supercharge Claude Code and Codex with security hooks, reusable skills, a lightweight statusline, and workflow automation.
📚 Full Documentation | 🎯 Premium Features
# Run setup (no installation required)
npx aiblueprint-cli@latest agents setup
/plugin marketplace add melvynx/aiblueprint
/plugin install aibp-base@AIBlueprint
# Run without installation
npx aiblueprint-cli@latest agents setup
# Interactive setup
npx aiblueprint-cli@latest agents setup
# Install all features (no prompts)
npx aiblueprint-cli@latest agents setup --skip
# Custom location
npx aiblueprint-cli@latest agents setup --folder ~/.my-claude
Install a lightweight Claude Code statusline:
npx aiblueprint-cli@latest agents setup
# Add specific hooks
npx aiblueprint-cli@latest agents add hook post-edit-typescript
# Create symlinks between tools
npx aiblueprint-cli@latest agents symlink
# Centralize global skills and agents in ~/.agents
npx aiblueprint-cli@latest agents unify
# Choose what to centralize interactively
npx aiblueprint-cli@latest agents unify -i
# Unify project-local .claude/.cursor config into .agents
npx aiblueprint-cli@latest agents unify projects
# Unify only selected project categories
npx aiblueprint-cli@latest agents unify projects --agents-md --skills --rules
# Recover sessions from saved configs and backups
npx aiblueprint-cli@latest agents config unify sessions
rm -rf, privilege escalation, remote execution~/.claude/security.logThe free configuration ships the skills listed in the catalog below. The CLI installs every directory under agents-config/skills/.
Installed into ~/.claude/mods/ and enabled through CLAUDE_CODE_PLUGIN_DIRS:
.agents/skills skill (global and per project) into .claude/skillscc - Claude Code with permissions skippedccc - Claude Code with continue modecx - Codexcxc - Codex continue mode for the current directoryInstall skills directly into ~/.claude/skills/:
# Install all skills
npx skills@latest add melvynx/aiblueprint
# Install a single skill
npx skills add Melvynx/aiblueprint --skill app-icon
# Install multiple skills
npx skills add Melvynx/aiblueprint --skill rules-manager
npx skills add Melvynx/aiblueprint --skill skill-manager
Available skills:
| Skill | Description |
|---|---|
agents-manager | Create and orchestrate Claude Code agents |
apex | Structured implementation workflow |
app-icon | Generate and prepare app icons |
appstore-connect | Manage App Store Connect workflows |
audit-memories | Manually audit and clean project agent documentation |
audit-skills | Manually audit skill usage, invocation controls, duplicates, and scope |
grill-me | Stress-test a plan with focused questions |
hooks-manager | Create and debug Claude Code hooks |
environments-manager | Set up per-worktree agent environments |
rules-manager | Create and maintain agent rule files |
skill-manager | Manage skills and rules across Claude Code, Codex, and Cursor |
test-audit | Gate new tests and prune low-value, implementation-coupled ones |
use-style | Apply named UI style guides before implementation |
Install the latest complete skill bundle from the private assistant-pro-skills repository:
npx aiblueprint-cli@latest assistants pro setup
The command asks for the Assistant Pro access key when needed, installs the versioned all bundle into ~/.agents/skills, creates Claude Code and Codex skill symlinks, adds the shared directory to Hermes, and exposes the same skills to OpenClaw through its native ~/.agents/skills discovery.
Unlock advanced features at mlv.sh/claude-cli
# Setup premium configs (prompts for your token if needed)
npx aiblueprint-cli@latest agents pro setup
# Or activate first if you prefer
npx aiblueprint-cli@latest agents pro activate YOUR_TOKEN
# Clone and setup
git clone <repository>
cd aiblueprint-cli
bun install
# Development mode
bun run dev agents setup
bun run dev agents statusline --list
# Run tests
bun run test:run
# Build and test locally
bun run build
bun run test-local
bun, gh CLIassistants pro setupbun run test:runMIT License - see LICENSE file for details.
Created by AIBlueprint - mlv.sh/claude-cli
Need help? Open an issue | Documentation
hooks/register.ts 97 lines1import type { Register } from 'claude-code'
2
3// `$` as a hook receives it.
4type Engine = Parameters<Parameters<Parameters<Register>[0]>[2]>[0]
5
6type Linked = { root: string; name: string }
7
8const SKILL_FILES = ['SKILL.md', 'skill.md']
9
10const realPath = async ($: Engine, path: string) =>
11 (await $.fs.stat(path, { resolve: true }).catch(() => undefined))?.realPath
12
13const homeDir = async ($: Engine) =>
14 (await $.process.run(['printenv', 'HOME'])).stdout.trim()
15
16// The session's cwd and every ancestor below $HOME, then $HOME itself (global).
17const rootsFor = (cwd: string, home: string) => {
18 const roots: string[] = []
19 let dir = cwd.replace(/\/+$/, '')
20 while (dir.startsWith(`${home}/`)) {
21 roots.push(dir)
22 dir = dir.slice(0, dir.lastIndexOf('/'))
23 }
24 if (!cwd.startsWith(`${home}/`) && cwd !== home) roots.push(cwd)
25 roots.push(home)
26 return roots
27}
28
29const isSkillDir = async ($: Engine, dir: string) => {
30 const stat = await $.fs.stat(dir).catch(() => undefined)
31 if (stat?.kind !== 'dir') return false
32 for (const file of SKILL_FILES) {
33 if (await $.fs.exists(`${dir}/${file}`)) return true
34 }
35 return false
36}
37
38// Links each <root>/.agents/skills/<name> missing from <root>/.claude/skills.
39const syncRoot = async ($: Engine, root: string): Promise<Linked[]> => {
40 const source = `${root}/.agents/skills`
41 const target = `${root}/.claude/skills`
42 if (!(await $.fs.exists(source))) return []
43
44 // .claude/skills already is .agents/skills (a symlinked folder): nothing to map.
45 const sourceReal = await realPath($, source)
46 if (sourceReal !== undefined && sourceReal === (await realPath($, target))) return []
47
48 // Every name already in .claude/skills, dangling links included, case-insensitive.
49 const existing = new Set(
50 (await $.fs.list(target).catch(() => [])).map(entry => entry.name.toLowerCase()),
51 )
52
53 const linked: Linked[] = []
54 for (const entry of await $.fs.list(source)) {
55 const { name } = entry
56 if (name.startsWith('.') || name.startsWith('__')) continue
57 if (existing.has(name.toLowerCase())) continue
58 if (!(await isSkillDir($, `${source}/${name}`))) continue
59
60 if (linked.length === 0) await $.process.run(['mkdir', '-p', target])
61 const ran = await $.process.run(['ln', '-s', `../../.agents/skills/${name}`, `${target}/${name}`])
62 if (ran.exitCode === 0) linked.push({ root, name })
63 else $.ui.log(`agent4everything: ln failed for ${name}: ${ran.stderr.trim()}`, { to: 'debug' })
64 }
65 return linked
66}
67
68const syncAll = async ($: Engine, cwd: string) => {
69 const home = await homeDir($)
70 const linked: Linked[] = []
71 for (const root of rootsFor(cwd, home)) linked.push(...(await syncRoot($, root)))
72 if (linked.length > 0) {
73 $.ui.toast(`agent4everything: linked ${linked.map(l => l.name).join(', ')}`)
74 }
75 return linked
76}
77
78export const register: Register = on => {
79 // Awaited before the first prompt: links exist before the session reads skills again.
80 on('session.start', async ($, e, next) => {
81 await syncAll($, e.cwd).catch(error => $.ui.log(`agent4everything: ${error}`, { to: 'debug' }))
82 return next(e)
83 })
84
85 // Startup, resume, /clear, compact: sync again and have the engine re-read skills.
86 on('classic.SessionStart', async ($, e, next) => {
87 await syncAll($, e.cwd).catch(() => [])
88 const result = await next(e)
89 return { ...result, reloadSkills: true }
90 })
91
92 on('classic.CwdChanged', async ($, e, next) => {
93 await syncAll($, e.new_cwd).catch(() => [])
94 return next(e)
95 })
96}
97