When working within any module under `modules.root_paths` from `.agent-project-settings.yml` — Laravel HMVC, Symfony DDD-lite, Node monorepo, Python src/, Go internal/, or a custom path.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add event4u-app/agent-config --skill module-management --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Module Management?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/event4u-app-module-management-agent-config)More formats (shields.io, HTML) on the badges page.
---
model_tier: medium
name: module-management
description: "When working within any module under `modules.root_paths` from `.agent-project-settings.yml` — Laravel HMVC, Symfony DDD-lite, Node monorepo, Python src/, Go internal/, or a custom path."
domain: process
workspaces:
- agent-config-maintainer
packs:
- meta
---
# module
## When to use
Use this skill when creating, exploring, or working within a module under
any directory listed in `modules.root_paths` (team setting in
`.agent-project-settings.yml`). The skill is stack-agnostic — Laravel
HMVC, Symfony DDD-lite, Node monorepo, Python src layout, Go internal/,
or a custom path all flow through the same procedure with a
stack-specific carve-out at the bottom.
When `modules.enabled` is `false` (the default) the skill is a no-op —
the project does not opt into module-aware behavior.
## Understand the current layout before editing
Before creating, renaming, or modifying anything inside a module:
1. Read the `modules:` block from `.agent-project-settings.yml` —
never assume a specific module root.
2. List the existing modules under each `modules.root_paths` entry and
review the target module's `README.md` (or `package.json` /
`pyproject.toml` description) to understand its purpose.
3. Read any module-scoped agent docs under
`{module_root}/{ModuleName}/{modules.agent_folder}/contexts/`.
4. Match the stack carve-out below by `modules.namespace_template`
shape and confirm the conventions before generating files.
Skip this step → risk creating files in the wrong root, breaking
stack-native auto-loading, or duplicating existing modules.
## Procedure: Work with modules
1. Read `modules:` block from `.agent-project-settings.yml` via the
loader (`get_modules_config()` in `scripts/_lib/agent_settings.ts`).
2. For each path in `modules.root_paths`, read the module's `README.md`
(or `package.json` / `pyproject.toml` description) for purpose.
3. If module-level agent docs exist under
`{module_root}/{modules.agent_folder}/` (default `agents/`), read them.
4. Match the stack carve-out below by `modules.namespace_template` shape
or root-path heuristic — apply stack-specific conventions on top of
the generic procedure.
## Detection (fallback when `modules:` block is empty)
When `modules.enabled` is unset / false, the skill consults the
auto-detection table in
[`/module explore` Step 1](../../commands/module/explore.md) — same six
stack shapes, fallback only. The skill never writes the `modules:`
block automatically; that is `propose_modules_config.ts` plus user
confirmation per
[`/agents init`](../../commands/agents/init.md) Step 7.
## Generic module structure
```
{module_root}/{ModuleName}/
├── <stack-native source layout> # see carve-out below
├── tests/ # module-specific tests
├── README.md # module description
└── {modules.agent_folder}/ # default: agents/
├── features/ # module-scoped feature plans
├── roadmaps/ # module-scoped roadmaps
└── contexts/ # module-scoped context docs
```
The agent-folder name comes from `modules.agent_folder` (default
`agents`). Skip directories listed in `modules.skip_dirs` (default
`.module-template`, `.example`).
## Stack carve-outs
Apply the section that matches the project's
`modules.namespace_template` and root-path layout.
### Laravel HMVC carve-out
**Triggers when:** `modules.namespace_template` starts with
`App\Modules\` or root path is `app/Modules`.
```
app/Modules/{ModuleName}/
├── App/ # PSR-4 source (capitalized)
│ ├── Console/Commands/ # auto-registered
│ ├── Http/{Controllers,Middleware,Requests}/
│ ├── Jobs/ Models/ Services/ Rules/ Enums/
├── Routes/ # auto-loaded
│ ├── api.php web.php console.php
├── Tests/{Unit,Integration,Component}/
└── agents/
```
**Namespace:** `App\Modules\{ModuleName}\App\{Layer}\{Class}` — note the
extra `App` segment.
**Auto-loading:** `app/Providers/ModuleServiceProvider.php` scans
`app/Modules/` and registers routes (`Routes/api.php` → `/api` prefix +
`api` middleware; `Routes/web.php` → `web` middleware) plus Artisan
commands under `App/Console/Commands/`.
**Route conventions:**
```php
// Routes/api.php — auto-prefixed /api
Route::name('v1.')->prefix('v1/{module-prefix}')->group(function(): void {
Route::get('/', [Controller::class, 'index'])->name('{module-prefix}.index');
});
```
Module name = PascalCase. Route prefix = kebab-case. Route names = dot
notation.
### Symfony DDD-lite carve-out
**Triggers when:** `modules.namespace_template` starts with `App\` (no
`Modules` segment) or root path is `src/` with `<Domain>/` subdirs.
```
src/{Domain}/
├── Application/ # use cases, command handlers
├── Domain/ # entities, value objects
├── Infrastructure/ # adapters, repositories
├── UserInterface/ # controllers, console
└── Tests/
```
**Namespace:** `App\{Domain}\{Layer}\{Class}` — no extra segment.
**Auto-loading:** Symfony service container auto-wires each
`{Domain}/` subtree per `services.yaml` resource imports.
### Node monorepo carve-out
**Triggers when:** root path is `packages/` and each child has
`package.json`.
```
packages/{pkg-name}/
├── package.json
├── src/ # entry points re-exported via "main"
├── tests/ __tests__/
└── README.md
```
**Module identity** comes from `package.json#name`, not the directory
name. The agent folder still lives at
`packages/{pkg-name}/{modules.agent_folder}/`.
### Python src-layout carve-out
**Triggers when:** root path is `src/` and each child has `__init__.py`.
```
src/{package_name}/
├── __init__.py
├── <module files>
└── tests/ # or root-level tests/{package_name}/
```
**Namespace** is the import path: `{package_name}.<sub>.<class>`. Project
metadata in `pyproject.toml`.
### Go internal carve-out
**Triggers when:** root path is `internal/` (one-level structure).
```
internal/{pkgname}/
├── *.go # package files
└── *_test.go # tests colocated
```
**Import path:** `{module-path-from-go.mod}/internal/{pkgname}`. No
top-level grouping — each subdir of `internal/` is its own package.
## Output format
1. Module directory under the matched stack carve-out.
2. Stack-native auto-loading + routing (if applicable).
3. Optional per-module `{modules.agent_folder}/` scaffold.
## Auto-trigger keywords
- module structure
- module creation
- module namespace
- create / explore module
- per-module agent docs
### Validate
- Verify namespace matches `modules.namespace_template` (when set).
- Run stack-native auto-loading check (e.g. `php artisan route:list` for
Laravel HMVC, `bin/console debug:container` for Symfony,
`npm test --workspace=<pkg>` for Node monorepo).
- Run module tests — must pass.
- Run quality tools scoped to the new path.
## Gotcha
- **Laravel HMVC only** — namespace has the extra `App` segment
(`App\Modules\X\App\…`). Other stacks do **not**.
- Routes auto-register in Laravel HMVC and Symfony — don't register
manually.
- Shared code lives outside module roots — never inside
`modules.root_paths`.
- Capitalize directory names only where the stack requires it (Laravel
PSR-4 yes, Node `packages/` no).
## Do NOT
- Do NOT hardcode any stack-specific module root (Laravel
`<app>/<Modules>/`, Symfony `src/Domain`, Node `packages/`, …) in
skill bodies, commands, or context docs — read from
`modules.root_paths`.
- Do NOT create a module for trivial functionality — only when logical
separation is needed.
- Do NOT register module routes manually when the stack provides
auto-loading.
- Do NOT add the `framework: laravel` frontmatter back to this skill —
the lint guard fails the build.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!