<objective>Note:
disable-model-invocation: true—/manageuser-invoked only, noSkill()chaining from orchestrators. When suggesting/manageas follow-up, invoking skill must present as user-run command, not auto step.
Manage lifecycle of agents, skills, rules, hooks in .claude/. Handles creation with rich domain content, atomic renames with cross-ref propagation, content editing (trivial edits inline; .md files → foundry:curator; code files *.js/*.py/*.ts → foundry:sw-engineer; rule edits inline), clean deletion with broken-ref cleanup. Keeps MEMORY.md inventory in sync with disk.
-
$ARGUMENTS: required, one of:
create agent <name> "description"— create new agent with generated domain contentcreate skill <name> "description"— create new skill with workflow scaffoldcreate rule <name> "description"— create new rule file with frontmatter and sectionsupdate <name> <new-name>— rename; type auto-detected from diskupdate <name> "change description"— content-edit; trivial → inline,.md→ foundry:curator, code → foundry:sw-engineer, rule → inlineupdate <name> <spec-file.md>— content-edit from spec file; trivial → inline,.md→ foundry:curator, code → foundry:sw-engineer, rule → inlinedelete <name>— delete; type auto-detected from disk (agents, skills, rules, hooks); asks user if ambiguousadd perm <rule> "description" "use case"— add permission to settings.json allow list and permissions-guide.mdremove perm <rule>— remove permission from settings.json allow list and permissions-guide.md
-
Names must be kebab-case (lowercase, hyphens only)
-
Descriptions must be quoted when containing spaces
-
Permission rules use Claude Code format:
WebSearch,Bash(cmd:*),WebFetch(domain:example.com) -
--skip-audit— optional flag: skip Step 9/auditvalidation (use insideaudit fixloop to avoid recursion)
Update/delete mode — name looked up across agents, skills, rules automatically:
- One match on disk → proceed with that type
- Multiple matches →
AskUserQuestion: (a) agent, (b) skill, (c) rule - No match → report error and stop
Update second-argument discrimination:
- Two bare kebab-case args (second arg no spaces, no
.mdextension) → rename mode - One name + quoted string → content-edit mode (trivial → inline;
.md: foundry:curator; code*.js/*.py/*.ts: foundry:sw-engineer; rule: inline) - One name + path ending in
.md→ content-edit mode (trivial → inline;.md: foundry:curator; code*.js/*.py/*.ts: foundry:sw-engineer; rule: inline)
Examples:
/foundry:manage create agent task-planner "Planning specialist for decomposing epics into actionable tasks"/foundry:manage update my-agent "add a section on error handling patterns"/foundry:manage update optimize docs/specs/YYYY-MM-DD-<spec-name>.md/foundry:manage delete old-agent-name/foundry:manage add perm "Bash(jq:*)" "Parse and filter JSON" "Extract fields from REST API responses"
- AGENTS_DIR:
.claude/agents - SKILLS_DIR:
.claude/skills - RULES_DIR:
.claude/rules - HOOKS_DIR:
.claude/hooks - USED_COLORS: blue, cyan, green, orange, pink, purple, yellow
- AVAILABLE_COLORS: indigo, lime, magenta, teal, violet
- MONITOR_INTERVAL: 300 (5 minutes between polls)
- HARD_CUTOFF: 900 (15 minutes of no file activity → declare timed out)
- EXTENSION: 300 (one +5 min extension if output file tail explains delay)
Bash equivalent (paste at the start of any health-monitoring block):
MONITOR_INTERVAL=300
HARD_CUTOFF=900
EXTENSION=300
Maintain colors manually — add new agent colors here when creating agents; static list advisory only — live Grep in Step 3 authoritative for colors in use.
</constants> <workflow>Task hygiene: call TaskList first; close orphaned tasks. Task tracking: create tasks for each major phase; mark in_progress/completed throughout.
Step 1: Parse and validate
Extract operation, type, name, optional arguments from $ARGUMENTS.
# Parse --skip-audit flag before other argument processing
SKIP_AUDIT=false
[[ "$ARGUMENTS" == *"--skip-audit"* ]] && SKIP_AUDIT=true
ARGUMENTS=$(echo "$ARGUMENTS" | sed 's/\(^\|[[:space:]]\)--skip-audit\([[:space:]]\|$\)/ /g' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
echo "$SKIP_AUDIT" > "${TMPDIR:-/tmp}/manage-skip-audit" # persist (Check 41)
Unsupported flag check — after all supported flags extracted (--skip-audit), scan $ARGUMENTS for remaining --<token> tokens. If found: print ! Unknown flag(s): \--<token>`. Supported: `--skip-audit`.then invokeAskUserQuestion` — (a) Abort (stop, re-invoke with correct flags) · (b) Continue ignoring (skip unknown flags, proceed). On Abort: stop.
Validation rules:
- Name must match
^[a-z][a-z0-9-]*$(kebab-case) - For
create: name must NOT already exist on disk; description required - For
update/delete: name MUST already exist on disk - For
updaterename: new-name must NOT already exist on disk - For
add perm: rule must NOT already exist in settings.json allow list; description and use case required - For
remove perm: rule MUST already exist in settings.json allow list
Type auto-detection (for update and delete): run all four Glob checks in parallel:
- Agent: pattern
agents/<name>.md, path.claude/ - Skill: pattern
skills/<name>/SKILL.md, path.claude/ - Rule: pattern
rules/<name>.md, path.claude/ - Hook: pattern
hooks/<name>.js, path.claude/
Results:
- One non-empty result → resolved type; proceed
- Multiple non-empty results →
AskUserQuestion: "Multiple entities named<name>found. Which one? (a) agent (b) skill (c) rule (d) hook" — note: (d) hook valid forupdateanddeleteonly;create hooknot yet implemented (use Edit tool onhooks/<name>.jsdirectly until create-hook mode added) - All empty → report "No agent, skill, rule, or hook named
<name>found" and stop
For create, check only relevant type's path.
Delete confirmation gate — when $MODE is delete, immediately after type resolution invoke AskUserQuestion: "Delete <name> (<type>)? This cannot be undone. (a) Confirm · (b) Abort". On Abort: stop. On Confirm: proceed to Step 4.
# Check permission existence (for add perm / remove perm)
jq -e --arg rule '<rule>' '.permissions.allow | index($rule) != null' .claude/settings.json >/dev/null 2>&1 # timeout: 5000
Update second-argument discrimination — apply after type resolved. Set the shell variable MODE from the parsed operation; it is consumed by the delete confirmation gate above, the edit-complexity classifier below, and the per-mode workflow branches in Step 4. Recognised values: create, rename, content-edit, delete, add-perm, remove-perm.
| Argument shape | MODE |
|---|---|
create <type> <name> "..." | create |
update <name> <new-name> (two bare kebab-case args; second has no spaces, no .md) | rename (validate new-name does NOT already exist) |
update <name> "<change>" (one name + quoted string) | content-edit (validate spec non-empty; set DIRECTIVE = the quoted string) |
update <name> <spec>.md (one name + path ending in .md) | content-edit (validate spec file exists on disk; set DIRECTIVE = contents of the spec file via Read tool) |
delete <name> | delete |
add perm <rule> "..." "..." | add-perm |
remove perm <rule> | remove-perm |
Assign MODE in shell before the edit-complexity classification below so the [[ "$MODE" == "content-edit" ]] guard fires correctly:
# Set MODE from the operation parsed above. Example for an update invocation:
# MODE="content-edit" # or "rename" / "create" / "delete" / "add-perm" / "remove-perm"