claude-add
Add one Claude Code automation to the project's .claude/ directory. Ground it in the actual stack and writing conventions adam already established (read CLAUDE.md and spec/ first so the new artifact fits in).
Modes
| Argument shape | Behavior |
|---|---|
agent <description> |
Create one sub-agent in .claude/agents/. |
skill <description> |
Create one skill in .claude/skills/<name>/SKILL.md. |
hook <event> <description> |
Write .claude/hooks/<name>.sh and add an entry to .claude/settings.json that references it (merged, not overwritten). |
| (no args / unclear) | Ask via AskUserQuestion: which kind, then what it should do. |
Process
Resolve the kind. If the user's prompt clearly says
agent/skill/hook(or matches a phrase like "sub-agent that…"), use that. Otherwise call:AskUserQuestion({ questions: [{ question: "What do you want to add?", header: "Kind", multiSelect: false, options: [ { label: "Sub-agent", description: "A specialized agent Claude can spawn for a focused task. Lives in .claude/agents/<name>.md." }, { label: "Skill", description: "A natural-language-triggered procedure with its own instructions. Lives in .claude/skills/<name>/SKILL.md." }, { label: "Hook", description: "Event handler that runs a command (e.g. lint on file write). Writes a script to .claude/hooks/<name>.sh and references it from .claude/settings.json." } ] }] })Resolve the spec. Read
CLAUDE.md+spec/INDEX.md+ the relevantspec/*.mdso the new artifact references real paths and conventions. IfCLAUDE.mdlacks a spec index, tell the user to run/adam:setupfirst and stop.Resolve missing details. If the user gave a description like
"reviews routes"but you need to know which routes / which framework, ask one focusedAskUserQuestion. Cap follow-ups at 2 questions total — if you still don't have what you need, ask the user to be more specific rather than guessing.Delegate writing to the
adamsub-agent. Pass the kind + description + the spec context you collected. Tell the agent exactly which file to write and what frontmatter shape to use:Sub-agent (
.claude/agents/<kebab-name>.md):--- name: <kebab-name> description: <one-line + several explicit trigger phrases> model: sonnet --- <substantive instructions, code-grounded>Skill (
.claude/skills/<kebab-name>/SKILL.md):--- name: <kebab-name> description: <one-line + explicit trigger phrases — e.g. "Use when the user runs /<name>, asks to ..."> --- <substantive instructions>Hook — write the executable script to
.claude/hooks/<kebab-name>.sh, then merge a reference to it into.claude/settings.json. The script holds the actual command body;settings.jsononly points at it.Script (
.claude/hooks/ruff-format.sh,chmod +x):#!/usr/bin/env bash set -euo pipefail ruff format "$CLAUDE_FILE_PATH"Settings entry (merged into
.claude/settings.json):{ "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [{ "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/ruff-format.sh" }] } ] } }Read the existing
.claude/settings.jsonfirst; preserve every key that's not part of this new entry; pretty-print the result. Never inline the command body intosettings.json— always route through a script in.claude/hooks/.
Verify. After writing:
- For agents/skills: re-read the file you just wrote, confirm frontmatter parses, confirm the description includes trigger phrases.
- For hooks: re-read
.claude/settings.json, confirm valid JSON; confirm.claude/hooks/<name>.shexists, is executable (chmod +x), and thecommandin settings points at it.
Report. One line per artifact created, plus a usage hint:
Created
.claude/agents/fastapi-route-reviewer.md. Trigger by asking "review my routes" or auto-invoked when Claude needs route-review expertise.
Guardrails
- One artifact per invocation. If the user asks for multiple, do them sequentially with one report each, or politely point them at
/adam:setup --forcefor a batch. - Never overwrite an existing
.claude/agents/<name>.mdor.claude/skills/<name>/SKILL.mdwithout explicit confirmation. If a name collides, append a suffix (-v2) or ask viaAskUserQuestion. - Always merge
.claude/settings.json— never overwrite. Use a JSON parser (e.g. read with Read, parse, mutate, stringify, Write). - The hook command body always lives in
.claude/hooks/<name>.sh(executable, with shebang).settings.jsononly holds the matcher + acommandthat invokes that script. Never inline a multi-token command directly intosettings.json. - Hooks must use
${CLAUDE_PLUGIN_ROOT}substitutions only if the script actually lives in a plugin — for project-local hooks, use$CLAUDE_PROJECT_DIR/.claude/hooks/<name>.sh(and$CLAUDE_FILE_PATHinside the script). - Sub-agent
toolsfield should be omitted unless you have a strong reason to restrict — agents inherit all tools by default. - Do not commit.
Source: lkzppm/adam — distributed by TomeVault.