create-plugin
Skill144 starsChanged 15 months agoMITView on GitHub
Use when building an Aegis Stack plugin, a separate package (aegis-stack-<name>) that renders files into a project through `aegis add <name>`. Covers the scaffold, the plugin spec, the file conventions a project finds on disk, testing inside a generated project, and publishing.
- Installs packages
We split this skill into the rules it gives an agent
5 rules. 0 are common, 2 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 12 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 16
Use when the work is a new optional capability shipped outside this repo: an integration (a source for the research service, a scraper), or …
- Very specific: line 20
Do NOT use for a capability that ships with the framework itself (use the add-service or add-component skill), or for changing the plugin …
- Very specific: line 63
Write the template's failing tests first (against the fixtures, with an httpx.MockTransport or a module-level _transport seam, never the …
- Very specific: line 66
Write the template modules and declare every owned path in files=FileManifest(primary=[...]).
- Distinctive: line 73
Run the plugin for real against the live service once, through the project's CLI or API.
“Common” is measured: kept by at least 6 in 10 of the 12 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Create plugin
A plugin is a separate Python package whose get_spec() returns a PluginSpec
(the same declaration built-in services use) and whose templates render into a
project on aegis add <name>. Much of what a plugin contributes needs no
wiring: the project finds a module of a known name in every service package on
disk.
When to use
Use when the work is a new optional capability shipped outside this repo: an integration (a source for the research service, a scraper), or a service a project opts into by installing a package.
Do NOT use for a capability that ships with the framework itself (use the
add-service or add-component skill), or for changing the plugin system in
this repo (that is ordinary work in aegis/core/plugins/).
Files that change
In the plugin repository (created by aegis plugins create <name>):
pyproject.toml: theaegis.pluginsentry point, keywords (aegis-stack-pluginlists it in the directory), theaegis-stackfloor.src/aegis_stack_<name>/plugin.py:get_spec():required_services/required_components,files=FileManifest(primary=[...]),wiring=only for what a convention module does not cover,migrations=only if it owns tables.src/aegis_stack_<name>/templates/{{ project_slug }}/: the files a project receives. Convention modules inapp/services/<service>/:__init__.py:CATEGORY = Category.<X>(app.core.parts), the service's concern in the system model (app.core.ontology); App when left out. First-party parts declare it on their spec instead.models.py(ormodels/): tables, picked up by the model registry.change_types.py: changes a model proposes and a user approves.scheduled_jobs.py:JOBS, a tuple ofServiceJob(app.core.schedule).tools.py:register_tool(...)calls (app.core.tools), for agents and MCP clients.sources.py:register_source(...)(app.services.research.registry), for a research source.
src/aegis_stack_<name>/templates/{{ project_slug }}/tests/: the template's tests, which run inside a generated project.tests/test_plugin.py: tests that pin the spec.README.md,LICENSE.
In this repo, only when a plugin needs a hook no convention covers: the
convention's discovery in the template (app/core/discovery.py
import_modules_named) and docs/plugins/creating.md's convention table.
Procedure
- Scaffold:
aegis plugins create <name> -d <parent> --author "..." --description "...". - Pick the convention modules the plugin needs; prefer them over
wiring=, which a project only honours for the hooksPluginWiringdeclares. - Record real third-party responses as fixtures under the template's
tests/fixtures/<name>/before writing any mapping code; build the model from what the API actually returns. - Write the template's failing tests first (against the fixtures, with an
httpx.MockTransportor a module-level_transportseam, never the network). - Write the template modules and declare every owned path in
files=FileManifest(primary=[...]). - Install the plugin into the aegis environment that renders it:
uv pip install -e <plugin>; confirm withaegis plugins list. - Generate a project without the plugin's dependencies, run
aegis add <name>, and run the template's tests there under the project's gate:uv run pytest <tests> --queryspy-strict --queryspy-baseline .queryspy-baseline.json. - Run the plugin for real against the live service once, through the project's CLI or API.
- Copy back anything the project's
make fixreformatted in the rendered files, so the template matches what a project receives. - In the plugin repo,
make check; then create the repository with theaegis-stack-plugintopic and push. Publishing to PyPI is the separate step indocs/plugins/publishing.md.
Gates
make checkin the plugin repository (ruff and the spec tests).- The template's tests passing inside a generated project after
aegis add <name>, under the queryspy strict gate. make lintandmake typecheckin that generated project.
Pitfalls
- Template files that are plain
.py(not.jinja) are seen by the plugin repo's own ruff and pytest; the scaffold'sextend-excludeandtestpathskeep them out, because their import order is the project's and their tests importapp. - A path rendered by the template but missing from
FileManifest.primarystays behind afteraegis remove <name>, because removal walks only the manifest. required_servicesis the real version guard for a plugin that builds on a service: an older aegis-stack without that service refuses the add, while anaegis_versionfloor set ahead of a release blocks local development on the unreleased version.- A timestamp a third-party API returns is often timezone-aware; the
project's columns are naive UTC (
app.core.time.as_stored), and Postgres refuses an aware value where SQLite accepts it, so test the mapping, not only the SQLite suite. - A rendered test that hits the network makes the project's suite flaky and slow; every template test runs on recorded fixtures.
Other versions14 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 14
- ToolJet/ToolJet★ 41ksame name
- rundeck/rundeck★ 6.3ksame name
- mistralai/mistral-vibe★ 5.3ksame name
- datavane/tis★ 1.4ksame name
- marcus/sidecar★ 1.1ksame name
- alexsmedile/hormozi-skills★ 208same name
- bitovi/ai-enablement-prompts★ 121same name
- npow/oh-my-claude★ 4same name
- rzx007/openharness-ts★ 3same name
- rzx007/Vykor★ 3same name
4 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository14 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- docs/CLAUDE.mdCLAUDE.md
- tests/CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- llms.txtllms.txt
- add-cli-commandSkill
- add-componentSkill
- add-serviceSkill
- example-skillSkill
- execute-issueSkill
- i18nSkill
- releaseSkill
- squash-branchSkill
- template-devSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

