# Extending SoMi SoMi is opinionated, but it's a starting point — your team will want to add workflows, agents, skills, hooks, and project-specific rules. This guide shows how. ## Mental model for extension Pick the right layer for what you want to do: | You want to… | Add a… | |-------------------------------------------------------------|---------------------------------| | Encode a universal team standard | Rule (in your `99-overrides.md`)| | Capture domain expertise for on-demand use | Skill | | Give Claude a new specialised way of thinking | Agent | | Expose a new user-facing entrypoint | Command | | Add a deterministic guardrail | Hook | | Compose existing pieces into a new flow | Command (orchestrating agents) | When in doubt: lower-level → higher-level. Try a rule first; promote to a skill if it grows; promote to an agent if it needs its own thinking process. ## Adding a new workflow A workflow is a **named, durable flow** with a clear input and a clear artifact. Adding one is a multi-piece change: 1. **Decide if it earns its own workflow.** Not everything does. The three SoMi workflows track the three fundamentally different shapes of engineering work. New workflows should also map to a distinct problem shape (e.g., **debugging** has a different shape than coding — diagnose, isolate, fix, regression-test). 2. **Define the artifact.** What durable output does the workflow produce? Write a template under `templates/.md.tmpl`. 3. **Define the agent.** Add `agents/.md` with frontmatter and a full system prompt following the pattern of existing agents (when to invoke, operating procedure, quality bar, output shape, failure modes, escalation). 4. **Define the command.** Add `commands/.md` orchestrating the agent and writing the artifact. 5. **Document it** in [WORKFLOWS.md](./WORKFLOWS.md) and [AGENTS.md](./AGENTS.md). 6. **Validate**: open a PR — CI checks frontmatter, TypeScript compilation, and hook scripts. > **Worked example:** the **discovery** workflow (`/discover` → `discovery-analyst` → > `.somi/rd//`) was added exactly this way — a distinct problem shape (requirements > engineering + competitive research, deciding *what* to build) upstream of the build trio, with its > own artifact set (`templates/RD-README`, `RESEARCH`, `BRD`, `SRS`, `FRD`, `SDD`, `TDD`), two > supporting skills (`market-research`, `requirements-engineering`), and a clean handoff into `/plan`. ## Adding an agent `agents/.md` with this frontmatter: ```markdown --- name: description: When to invoke this agent (concrete trigger conditions, not topic). The model uses this to decide whether to call it. model: opus --- # ``` Rules of thumb: - **`description`** is the single most important field. Get it right. - **`model`** follows the [MAX/ECO tiers](./AGENTS.md#economic-tiering-maxeco): `opus` for **MAX** agents that front-load reasoning into a `brief.md` or do fresh-eyes review; `sonnet` for **ECO** agents that execute against the brief. A new agent that compiles context is MAX; one that executes it is ECO. - Omit `tools:` — leave it unrestricted so the agent works across Claude Code and GitHub Copilot. If the underlying runtime enforces restrictions, it does so at its own layer. ## Adding a skill `skills//SKILL.md`: ```markdown --- name: description: Use when ... (trigger conditions in plain language). --- # Skill body ``` Skills should include: when to invoke, first principles / operating procedure, per-domain checklists or examples, anti-patterns, when *not* to apply, when to escalate. See existing skills for the shape. ## Adding a command `commands/.md`: ```markdown --- description: One-liner for / autocomplete. argument-hint: allowed-tools: Task, Read, ... model: opus --- # / — Title (Command body — a prompt template. Reference $ARGUMENTS. Typically: validate input, invoke agents via Task, write artifact, summarise.) ``` Keep commands thin; agents do the heavy lifting. ## Adding a hook 1. Write a script under `hooks//.sh`: ```bash #!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../lib/common.sh" somi::read_payload # Pick the right helper for the event: # # PreToolUse → somi::deny_pretool "reason" # (emits hookSpecificOutput.permissionDecision="deny") # # PostToolUse → somi::context "PostToolUse" "..." # (emits hookSpecificOutput.additionalContext) # # UserPromptSubmit → somi::context "UserPromptSubmit" "..." # # Stop → has no additionalContext channel. Use {decision:"block",reason} # only when you genuinely want to refuse the stop (rare). Otherwise # move your nudge to PostToolUse or UserPromptSubmit. # # Audit everything you decide via somi::audit (the helpers already do this for denials). exit 0 ``` 2. `chmod +x` it. 3. Wire it in **two** places so both install paths work: - **Plugin install**: add to [`hooks/hooks.json`](../hooks/hooks.json) using `${CLAUDE_PLUGIN_ROOT}`. - **Vendored install reference**: add to [`.claude/settings.json`](../.claude/settings.json) using `${SOMI_VENDOR_ROOT}`. Plugin example: ```json { "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ {"type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre-tool/your-script.sh"} ] } ] } } ``` 4. Open a PR — CI validates the hook script syntax and JSON wiring. Hooks should encode **non-negotiables** — things you want to be deterministic, not subject to model judgment. For judgment-heavy work, write an agent or skill instead. ## Adding a project-specific override In `rules/99-overrides.md` (which SoMi never touches): ```markdown ## Override: **Rule overridden:** rules/.md — "" **Override:** **Reason:** **Removal condition:** ``` Or add a brand-new project convention that doesn't conflict with SoMi: ```markdown ## Convention: ``` ## Versioning your extensions If you're extending SoMi for your team, treat your extensions like the upstream repo: SemVer, change log, validate-on-CI. See [VERSIONING.md](./VERSIONING.md) for the policy SoMi itself follows. ## Contributing back If your extension is generic enough to help other teams, consider upstreaming it: 1. Open an issue on the SoMi repo describing the gap and the proposed addition. 2. Submit a PR with the new file, doc updates, profile updates, and validator passing. 3. SoMi maintainers review against the same quality bar as core SoMi components. ## What to avoid - **Don't fork the agent system prompts unless you have to.** Compose, override, or wrap them instead. Forks drift. - **Don't put feature-specific logic in `rules/`**. Rules are universal. Project-specific guidance goes in `99-overrides.md` or in skills. - **Don't add hooks for things that need judgment.** A hook can't reason. If you find yourself writing a hook with nuanced conditions, you probably want a rule or skill. - **Don't add agents whose `description` overlaps with an existing agent.** Overlapping descriptions confuse the model's decision about which agent to invoke.