Individual skill

create-mod

Scaffold a Claude Code mod (a plugin with a function-hooks module) from ruflo's governed template, then validate and test it. Use when the user asks for a mod, a function hook, or wants Claude Code to modify itself.

plugins/ruflo-plugin-creator/skills/create-mod/SKILL.md

Read pinned source

Source commit 722232566ad1fc4e73ba4fefc46d77d380ce61ba

What was checked

Matches the observed repository HEAD
Yes
Scanner rules are current
Yes
Repository scan complete
No
Skill scan complete
No
Observed behavior
Network or broad shell
Last checked
Nov 9, 2026

These are observations at the recorded commit, not a guarantee of safety. Review the source before running it.

Install this skill

Choose an agent in your Stack or copy a command below. Commands fetch the pinned commit and copy only this skill directory. Existing destinations are refused. Copying a command does not install anything.

An install command is unavailable: current rules, complete repository and skill scans, an eligible behavior level and a permitted license are required.

Repository context

Repository stars (not skill ratings)
81,352
Repository last updated
Nov 9, 2026
License
MIT

Observed agent integration: No specific integration evidence. Standard SKILL.md installation does not imply verified compatibility.

Files and excerpt

File metadata and permitted, redacted excerpts come from the recorded scan. Source links are pinned to that commit.

Browse files
Read excerpt

# Create Mod

Scaffold a mod the governed way, instead of an ad-hoc one: the template already follows the rules ruflo's own mod (ADR-404) was reviewed against.

## Steps

1. **Name it.** kebab-case `<name>`. Commands it registers are namespaced `<name>-<verb>`; never register a built-in's name (`/diff`, `/help`) or another plugin's (`/ruos*`, `ruflo-*`).
2. **Scaffold from the template** with `node plugins/ruflo-plugin-creator/scripts/scaffold-mod.mjs <name> <target-dir>`. It copies `templates/mod/`, turns the manifest template `plugin.json.tmpl` into `.claude-plugin/plugin.json` (the template keeps it under a non-manifest name so plugin validators do not mistake `templates/mod` for a second plugin), and replaces `my-mod` everywhere (plugin.json `name`, the command, `MY_MOD_ACTIVE` → `<NAME>_ACTIVE` in both `hooks/register.ts` and `hooks/classic.cjs`, the status folder). Doing it by hand: copy the folder, move `plugin.json.tmpl` to `.claude-plugin/plugin.json`, and make the same replacements.
3. **Keep the status contract.** `hooks/status.ts` writes `.claude-flow/<name>-mod/status.json`, the file the console's Mods section reads. The folder must be `<name>-mod` (lowercase, digits, hyphens, at most 41 characters): the scaffold script already sets `STATUS_PATH` to `<name>-mod`. Fields: `version: 1` (required, anything else is ignored), `summary` (one line), `modVersion`, `guard` (boolean), `calls` (a **number**, not a per-tool object), `blocked` (number), `lastDenied` (a short reason, only once the mod has refused something), plus `updatedMs`/`startedMs`. Other fields are not shown. `tests/status.test.ts` asserts the shape.
4. **Write the behaviour** in pure functions taking the `Host` (see `hooks/host.ts`). In `register.ts`, build the host from literal `$.noun.method(...)` calls only — the engine reads a module's `$` uses off its source, and `claude plugin validate` refuses `$` passed around, computed (`$[noun]`), or deeper than `$.noun.method(input)`.
5. **Keep the rules:**
   - Observe with `const r = await next(e); …; return r`; rewrite with `next({ ...e, … })`; answer (`{ deny }`) only when you mean to stop the chain.
   - On `tool.check`, only ever tighten (the stricter of `await next(e)` and yours); never answer `allow` of your own.
   - Wrap every `$` call so a refusal degrades instead of failing the turn (admins can withhold any `$` affordance).
Back to top