---
name: generate-module
description: Scaffolds a new federated admin module project under projects/<name>/ in the current admin-modules workspace. Wraps the `ws-generate-module` bin — delegates Angular's `ng generate library`, then overlays federation.config.js, BOM-only peerDeps, and workspace registration.
when_to_use: Activates when adding a new federated remote/module project, when the user types `npx ws-generate-module <name>` or says "create a new admin module", "scaffold a new remote", "add a federated module called X".
allowed-tools:
  - Read
  - Edit
  - Write
  - Bash
---

Language: English only.

This skill is used to scaffold a new federated admin module project inside an admin-modules workspace via `ws-generate-module`. The bin layers federation conventions on top of `ng generate library` so the new project is wired up out of the box (federation.config.js with `share`/`remoteExternals`, BOM-only peerDeps, public-api.ts, ng-package.json with allowedNonPeerDependencies).

## When this skill applies

- "scaffold a new admin module called `<name>`"
- "create a new federated remote project `<name>`"
- "add a module under projects/"
- User runs `npx ws-generate-module <name>`
- User has an empty `projects/` (or `projects/<existing-modules>/`) and wants to add a new one

## How it works

Entry point: `/Users/ph/projects/ws-admin-aux/admin-kit/bin/ws-generate-module.js`. Implementation: `/Users/ph/projects/ws-admin-aux/admin-kit/lib/generate-module.js`. Templates: `/Users/ph/projects/ws-admin-aux/admin-kit/template-module/`.

Steps the bin performs:

1. Validates the workspace context (must be inside an admin-modules workspace — `angular.json` present).
2. Delegates to `ng generate library <name>` for Angular's blessed scaffolding (creates `projects/<name>/`, registers in `angular.json`, sets up tsconfig.lib.json + ng-package.json).
3. Overlays federation-specific files from `template-module/`:
   - `projects/<name>/src/federation.config.js` — with `share(remoteShared({self}))` + `externals: remoteExternals({self})` from `@wiresphere/shared`
   - `projects/<name>/src/exposed-module.ts` — the canonical `./Module` exposed entry
   - `projects/<name>/package.json` — BOM-only peerDeps (`@wiresphere/shared` + lib-local siblings)
   - `projects/<name>/ng-package.json` — with `allowedNonPeerDependencies` regex array stamped
   - `projects/<name>/public-api.ts` — with module + exposed module export skeletons
4. Adds a `build` target for federation (`build` → native-federation, `build-lib` → ng-packagr) in angular.json.
5. Runs `npm install` so the new project's peers materialize.
6. After this runs, the dev can immediately `npm run ship` for that module (once the workspace is bonded to a fiddle).

Usage:

```
npx ws-generate-module <name>
```

`<name>` is the project name (kebab-case). Becomes the federation remote name + the npm package name.

## Behavior contract (the agent MUST follow this when this skill is active)

- **Announce on load (MUST).** The first time this skill informs a response in a session, begin that response with the line `🧩 skill: generate-module` (combine as `🧩 skills: a, b` when several load together). Once per skill per session — it's a load marker, not a summary; do not repeat it on later turns.
- MUST run from the workspace root (where `angular.json` lives), not from inside `projects/`.
- MUST use a kebab-case name with no special characters (becomes the npm name + federation name).
- MUST surface any `ng generate` error verbatim — bin failures are usually Angular-side and the message is the fix.
- MUST verify `projects/<name>/src/federation.config.js` and `public-api.ts` were created after running; if not, the overlay step failed and the project needs cleanup ([drop-module](../drop-module/SKILL.md)) before retry.
- MUST NOT manually edit `angular.json` after the bin runs — the bin's modifications are the source of truth; manual edits will diverge.
- MUST NOT hand-author federation.config.js for the new module — the template is the convention. Customize after generation if needed.

## Common pitfalls

- **Name already taken.** Conflicts with an existing project under `projects/`. Pick a different name OR remove the existing project via [drop-module](../drop-module/SKILL.md) first.
- **Workspace not bonded.** Module scaffolds fine but `npm run ship` errors with no `wpmRoot`. Run [wire-host](../wire-host/SKILL.md) first.
- **Missing public-api re-exports for expansion components.** Bin scaffolds the skeleton — when adding `@ExpansionEntry`/`@TabExpansionEntry` components later, the dev MUST add `export *` for them to public-api.ts or expansion registration silently fails at runtime. See the `federation-error-catalogue` skill entry #12.
- **`OWN` not declared when the module provides a singleton package.** If the new module bundles a unique third-party (e.g. some specific charting lib that nothing else uses), it MUST declare it in `federation.config.js`'s `OWN` array. Otherwise consumers won't be able to import it via the share map.

## Out of scope

- This skill does NOT bond the workspace to a fiddle. See [wire-host](../wire-host/SKILL.md).
- Does NOT deploy the new module — that's [ship-workflow](../ship-workflow/SKILL.md) after the workspace is bonded.
- Does NOT add the module to `<fiddle>/modules.json.adminModules`. The fiddle operator does that (or it's done automatically by [wire-setup-modules](../wire-setup-modules/SKILL.md) on dep prompts).
- Does NOT write `MODULE.md` — separate authoring task (see the `module-md-authoring` skill).

## Cross-links

- [workspace-init/SKILL.md](../workspace-init/SKILL.md) — scaffold workspace before generating modules
- [drop-module/SKILL.md](../drop-module/SKILL.md) — inverse: remove a module
- [wire-host/SKILL.md](../wire-host/SKILL.md) — bond workspace to fiddle before ship
- [ship-workflow/SKILL.md](../ship-workflow/SKILL.md) — deploy the generated module
- the `module-md-authoring` skill — document the new module
