Back in February I wrote about agent-skills — a repo of SKILL.md files that taught Claude Code my Laravel conventions so I’d stop re-explaining Pest, Action classes and Livewire 4 every session.
It worked. But after a few months of daily use, I hit a ceiling that skills alone couldn’t fix.
Today I rewrote the repo. New name, new structure, three layers instead of one: nasrulhazim/claude.
And because most of my projects are scaffolded from Kickoff, the same roster now ships into every generated app via Kickoff 1.36.0.
This post is the upgrade guide.
TLDR
Before (agent-skills)
After (claude)
Repo
nasrulhazim/agent-skills
nasrulhazim/claude
Content
14 skills
29 skills, 20 agents, 10 commands
Installs to
~/.claude/skills/
~/.claude/{skills,agents,commands}/
Install methods
curl script
curl script or plugin marketplace
Renames
manual cleanup
automatic via migrations.txt
Project-level
copy skills by hand
bundled by Kickoff 1.36.0
Upgrade in one line:
curl -fsSL https://raw.githubusercontent.com/nasrulhazim/claude/main/install.sh | bash
Enter fullscreen mode Exit fullscreen mode
The installer detects your old skills, removes the renamed ones, and tells you what changed. Read on for what to watch out for.
The Ceiling I Hit
A skill answers “how should this be done?” It carries knowledge and method — Pest patterns, PHPStan workflow, Livewire component structure.
What it doesn’t answer is “who is doing it, and what are they allowed to touch?”
That distinction turned out to matter a lot. Concretely:
Problem 1 — reviewers that write code. I’d ask for a code review, and Claude would helpfully “fix” things mid-review. A review should produce findings, not commits. A skill can say “don’t edit files”; it can’t enforce it.
Problem 2 — no fan-out. I maintain 20+ packages. Bumping a dependency across all of them is the same role repeated 20 times in parallel. Skills are loaded into one session; there’s no unit to delegate and multiply.
Problem 3 — skills doing two jobs. self-update was maintaining CLAUDE.md. api-lifecycle covered design through governance. Fine names in isolation, but they didn’t compose into a system I could reason about.
So the rewrite split one concept into three.
The Three Layers
Layer Answers Loaded Example Skill How is this done? On demand, by trigger phrase or/name
pest-testing, code-quality
Agent
Who does it, with what tools?
By delegation, explicit or automatic
code-reviewer, qa-engineer
Command
Run this workflow now
/name
/upgrade-laravel, /docs
The key design rule: agents are thin. An agent is a 25–75 line role persona that loads skills as its playbook. It does not duplicate skill content. Knowledge lives in exactly one place — the skill — and agents are just personas pointing at it.
Here’s the agent frontmatter:
---
name: code-reviewer
color: orange # red=security, orange=quality, green=build/ship,
# pink=docs/business, blue=design, cyan=audit, yellow=support
description: Use this agent when... # third-person, trigger-oriented
tools: Read, Grep, Glob, Bash, Skill # optional allowlist; omit for all tools
---
Enter fullscreen mode Exit fullscreen mode
That tools line is the fix for Problem 1. Reviewer, auditor and security roles ship with a read-only allowlist — no Write, no Edit. The reviewer can’t rewrite your code while reviewing it. That’s not a prompt asking nicely, that’s a tool boundary.
The description field is the routing key. Claude matches your natural request against agent descriptions, which is why they’re written in third person and trigger-oriented rather than as instructions to the agent.
Upgrading Your Setup
One command. It installs everything and cleans up the old names:
curl -fsSL https://raw.githubusercontent.com/nasrulhazim/claude/main/install.sh | bash
Enter fullscreen mode Exit fullscreen mode
Prefer the plugin? Same result, from inside Claude Code:
/plugin marketplace add nasrulhazim/claude
Enter fullscreen mode Exit fullscreen mode
Pick one — installing both duplicates everything.
Four skills got renamed
The installer handles this for you: it finds the old directories in ~/.claude/skills/, removes them, and prints the mapping at the end of the run. Nothing orphaned, nothing competing for the same trigger phrases.
api-lifecycle
project-api
faq-generator
project-faq
roadmap-generator
project-roadmap
self-update
project-conventions
Only thing left for you: update any notes or scripts still calling the old names.
One gotcha, if you cloned the repo
The repo was renamed, so an old local clone needs a nudge before bash install.sh will work:
git remote set-url origin https://github.com/nasrulhazim/claude.git
git pull
Enter fullscreen mode Exit fullscreen mode
The curl install always fetches the latest installer, so it’s never affected.
What You Get: The Roster
29 skills, up from 14. The new ones worth knowing:
Skill What it doesproject-laravel
Kickoff conventions enforcer and code scaffolder
kickoff-patch
Patch an existing project to the latest Kickoff baseline via category-grouped 3-way merge
project-ddd
Pragmatic DDD — domain discovery, migration planning, boundary enforcement
project-sync
Sync CLAUDE.md conventions across multiple Kickoff projects
project-inventory
Discover and inventory all Claude Code projects, with an HTML dashboard
git-workflow / gh-workflow
Conventional commits, releases, hooks / GitHub CLI automation
log-monitor
Production log analysis, error triage, GitHub issue creation
soc-analyst
Security triage, investigation, remediation, hardening
repo-research
Deep codebase analysis with structured research docs and diagrams
dev-summary
Multi-repo development stats, timelines, contributor analytics
20 agents covering every SDLC phase. Rather than listing all of them, here’s the mental model — the chains:
Scenario Chain Feature project-manager → business-analyst → software-architect + database-engineer → laravel-developer / api-engineer → code-reviewer + qa-engineer → devops-engineer Incident support-analyst (triage) → security-analyst or performance-engineer (diagnose) → laravel-developer (fix) → tech-writer (post-mortem) Security assurance security-analyst (defensive audit) → penetration-tester (scoped, local/staging) → laravel-developer (fix) → security-analyst (re-verify) Release qa-engineer (suite green) → devops-engineer (changelog, tag, deploy) → tech-writer (release notes)Two agents are built specifically to fan out in parallel: package-maintainer (across ~/Packages) and fleet-auditor (read-only sweeps for drift and inventory across many repos). That’s Problem 2 solved — “fan out package-maintainer across these 10 packages” is now a single instruction.
When to reach for which:
Use a… When Skill You need knowledge/method in the current session Agent You want to delegate a role-shaped task, or fan out Command You want a repeatable workflow entry point (/name)
The Kickoff Half: Project-Level Assets
Everything above installs globally to ~/.claude/. That’s great for me and useless for my team — a teammate cloning the repo gets none of it.
Kickoff 1.36.0 fixes that by committing a curated roster into the project itself.
The mechanism is delightfully boring: Kickoff already mirrors stubs/ recursively into every scaffolded app. Drop the assets into stubs/.claude/ and they land in every new project with zero installer changes.
What ships into generated projects:
Type Count Contents Agents 12 api-engineer, code-reviewer, database-engineer, devops-engineer, laravel-developer, performance-engineer, qa-engineer, security-analyst, software-architect, tech-writer, ui-designer, upgrade-specialist Skills 17 project-laravel, livewire-flux, pest-testing, code-quality, php-best-practices, design-patterns, project-api, project-ddd, git-workflow, gh-workflow, ci-cd-pipeline, kickoff-patch, log-monitor, project-conventions, project-docs, project-roadmap, project-faq Commands 3 upgrade-laravel, upgrade-livewire, docsNote the curation. The global toolkit has 20 agents and 29 skills; the project bundle has 12 and 17. sales-planner, svg-logo-system, business-card, courseware-builder — those are my business tools, not something a Laravel app repo needs. Kickoff itself also carries its own .claude/ (5 agents, 8 skills) tuned for package development.
Refreshing the bundle:
# Defaults to ~/Packages/claude, or pass a path
bin/sync-claude-assets
bin/sync-claude-assets /path/to/claude
Enter fullscreen mode Exit fullscreen mode
Idempotent, with the curated lists at the top of the script so you can edit what’s included. The bundle is a snapshot — it doesn’t auto-track the toolkit. Re-run the sync each Kickoff release.
Two gotchas from the release notes:
-
boost:install --skillsstill runs during scaffolding and writes package-named skills alongside these. If a name ever collides, re-runbin/sync-claude-assets. - Read-only roles (code-reviewer, security-analyst) keep their restricted tool allowlist in the project bundle too. The boundary travels with the file.
Global vs Project: How to Think About It
Layer Lives in Good for Global~/.claude/
Your personal roster — business skills, brand tools, multi-repo agents
Project
.claude/ (committed)
Team-shared conventions that must apply to this codebase
My rule: if a teammate needs it to work on this repo, it goes in the project. If it’s how I personally work, it stays global.
A code reviewer that knows the project’s Kickoff conventions belongs in the repo — committed, versioned, reviewed like any other code. My logo designer does not.
This is also why project-conventions (the renamed self-update) matters more than it looks. It maintains CLAUDE.md as you correct Claude during a session. Committed to the repo, that file becomes shared institutional memory — gotchas one developer discovered on Tuesday are available to everyone on Wednesday.
If You’re Building Your Own
The contributing rules encode the lessons above:
- Follow the existing frontmatter format per content type
- Skills: include
metadatawithcompatible_agentsandtags; put templates and patterns inreferences/ - Agents: 25–75 lines, thin personas that load skills — no duplicated skill content
- Trigger phrases in both English and Bahasa Malaysia where appropriate
- Run
bash generate-manifest.shbefore committing; record renames inmigrations.txt
Rules 3 and 5 are the ones I’d steal even if you never touch my repo.
Rule 3 keeps knowledge single-sourced. The moment an agent starts explaining how to write a Pest test instead of delegating to pest-testing, you have two copies of that knowledge drifting apart.
Rule 5 is what makes renaming survivable. Without a migration file, every rename leaves a landmine in every user’s ~/.claude/ — a stale skill with overlapping triggers, silently competing with its replacement. Four lines of old:new text turn a breaking change into a clean, self-announcing upgrade.
The installer stays Bash 3.2-compatible, incidentally, so macOS’s stock /bin/bash works without anyone installing anything.
Wrapping Up
The February version of this idea was: give Claude a reusable module of expertise instead of a long prompt. That still holds.
What I got wrong was assuming expertise was the only missing piece. A skill tells Claude how to review code. It doesn’t stop Claude from writing code while reviewing. It doesn’t let you say “do this role across twenty repos.” It doesn’t survive a rename.
Skills carry knowledge. Agents carry role and permission. Commands carry workflow. Three layers, one repo, one installer that knows how to upgrade itself.
curl -fsSL https://raw.githubusercontent.com/nasrulhazim/claude/main/install.sh | bash
Enter fullscreen mode Exit fullscreen mode
Toolkit: github.com/nasrulhazim/claude
Kickoff: github.com/cleaniquecoders/kickoff
PRs open — especially agents. If you’ve found a role boundary worth encoding, I want to see it.
답글 남기기