agent-customization
LLM-powered injection of project context into installed agent templates via `aspens customize agents`
git clone --depth 1 https://github.com/aspenkit/aspens /tmp/agent-customization && cp -r /tmp/agent-customization/.claude/skills/agent-customization ~/.claude/skills/agent-customizationskill.md
You are working on **agent customization** — the feature that reads a project's skills and CLAUDE.md, then uses Claude CLI to inject project-specific context into generic agent files in `.claude/agents/`.
## Domain purpose
`aspens customize agents` makes generic, bundled agent templates project-aware. It pulls the repo's skills + CLAUDE.md as ground truth and asks Claude to add a tech-stack line, 3-5 project conventions, and real commands into each agent — without touching the agent's core logic.
## Business rules / invariants
- **Claude-only feature.** Throws `CliError` for Codex-only repos (`config.targets === ['codex']`). Codex CLI has no agent concept.
- **Base skill is required.** Pre-flight throws `CliError("Run 'aspens doc init' first — base skill is required for agent context.")` if `.claude/skills/base/skill.md` is missing.
- **Skills (`.claude/skills/**`) are the single source of truth** for project context. The prompt must not invent other context directories.
- **Read-only tools only.** Claude is invoked with `allowedTools: ['Read', 'Glob', 'Grep']` — no edits/writes from the LLM itself.
- **Output paths restricted to `.claude/`.** `parseFileOutput()` rejects anything else; `writeSkillFiles(..., { force: true })` does the actual write.
## Non-obvious behaviors
- **Frontmatter preservation is split across LLM + code.** The prompt instructs Claude to preserve YAML frontmatter verbatim (including NOT adding a `skills:` line). Then `maybeInjectBaseSkill()` post-processes each returned file to add `skills: [base]` into the frontmatter — this keeps agents valid even when installed via `aspens add agent` without a prior `doc init`.
- **`--reset` semantics:** without `--reset`, agents that already declare `skills:` are left alone; with `--reset`, any existing `skills:` line is overwritten to `skills: [base]`. Used to roll out v0.8 upgrades to previously-customized agents.
- **`## Project context` block is verbatim-preserved** by the prompt — it carries conditional read instructions for code-map / domain skills.
- **CLAUDE.md is truncated at 3000 chars** in `gatherProjectContext()`; skills are passed in full.
- **Agent discovery:** `findAgents()` recursively walks `.claude/agents/`, extracts `name:` via regex, falls back to filename if missing.
- **Default timeout 300s** via `resolveTimeout(options.timeout, 300)`; `ASPENS_TIMEOUT` env var honored with warning on invalid value.
## Critical files (purpose, not inventory)
- `src/commands/customize.js` — orchestrator: preflight, agent discovery, context gathering, per-agent Claude calls, post-LLM `skills: [base]` injection, write.
- `src/prompts/customize-agents.md` — system prompt; enforces frontmatter + `## Project context` preservation and bans file-inventory / hub-ranking output.
## Critical Rules
- **Never let the LLM emit a `skills:` line** — the prompt forbids it and the code adds it. If you change one, change both.
- **Never weaken path sanitization** — only `.claude/` paths may be written.
- **Never duplicate file-inventory or hub-ranking output** in customized agents — the graph hook supplies that dynamically.
- **Do not bypass the base-skill preflight** — agents without base context regress to generic behavior.
---
**Last Updated:** 2026-05-11>
Core conventions, tech stack, and project structure for aspens
Claude/Codex CLI execution layer — prompt loading, stream-json parsing, file output extraction, path sanitization, skill file writing, and skill rule generation
Top-level Commander wiring, welcome screen, missing-hook warning, CliError exit handling, and the public programmatic API surface
Multi-target output system — target abstraction, backend routing, content transforms for Codex CLI and future targets
Context health analysis — freshness, domain coverage, hub surfacing, drift detection, LLM-powered interpretation, and auto-repair for generated agent context
Incremental skill updater that maps git diffs to affected skills and optionally auto-syncs via a post-commit hook
Static import analysis that builds dependency graphs, domain clusters, hub files, git churn hotspots, and file priority rankings