---
name: wire-setup-modules
description: Fiddle-level orchestrator that discovers wired admin-modules workspaces, topo-sorts projects across them by federation externals, auto-wires unwired workspaces, prompts for missing required deps, refreshes cross-workspace symlinks before each build, and runs build+pack+deploy per project. Wraps the `ws-wire-setup-modules` bin (invoked automatically by `wpm admin`).
when_to_use: Activates when re-deploying all (or many) admin remotes without rebuilding the host, after a fresh fiddle setup, when debugging cross-workspace deploy order, when the user types `npx ws-wire-setup-modules` / says "re-deploy all modules", "ship everything to fiddle". Also when handling the workspace topology bounce warning.
allowed-tools:
  - Read
  - Edit
  - Write
  - Bash
---

Language: English only.

This skill is used to orchestrate a multi-workspace federated-remote deploy into a fiddle via `ws-wire-setup-modules`. Used by `wpm admin` after the host build phase; can also be run directly from a fiddle to re-deploy modules without rebuilding the host. Smarter than the legacy `wpm admin-remotes`: respects `modules.json.adminModules`, topo-sorts cross-workspace by `federation.config.js` externals, prompts for missing deps, skips already-deployed projects unless `--force`.

## When this skill applies

- "re-deploy all modules" (without rebuilding the host)
- "ship everything to the fiddle"
- "bring this fiddle's remotes up to date"
- After `wpm install` cloned new module repos and they need first-deploy
- Debugging cross-workspace deploy order
- User runs `npx ws-wire-setup-modules --fiddle <path>` or invokes it via `npm run ship-setup-modules` from inside the host clone

## How it works

Entry point: `/Users/ph/projects/ws-admin-aux/admin-kit/bin/ws-wire-setup-modules.js`. Orchestration lib: `/Users/ph/projects/ws-admin-aux/admin-kit/lib/wire-setup-modules.js`.

End-to-end per invocation:

1. **Resolve fiddle root** — `--fiddle <path>` arg or walk-up from `process.cwd()` looking for `modules.json`.
2. **Sanity-ensure `<fiddle>/scripts/ext-admin-remotes/`** (creates with `.gitkeep` if absent — needed for ext-target deploys).
3. **Read `modules.json`** — extract `adminModules` (the deploy list) + `additionalAdminModulePaths` (extra workspace discovery paths).
4. **Discover candidate workspaces** — `additionalAdminModulePaths` + `<fiddle>/wpm_modules/*/admin-modules/`, deduped. Filters out: no package.json, legacy moodia-schematics workspaces (`package.json#scripts.build` includes `moodia`), workspaces wsconfig'd to a DIFFERENT fiddle.
5. **Auto-wire unwired workspaces** — for each candidate without `wsconfig.json`, invokes `npx ws-wire-host <fiddle>`. Runs `npm install` if `node_modules` is missing (needed for the `require(federation.config.js)` step that follows).
6. **Enumerate projects per workspace** via `loadOrder()`; partition by kind (libraries are deployed but skipped from federation topo-sort).
7. **Extract externals per project** by spawning `node -p "JSON.stringify(require(<federation.config.js>).externals)"` with `cwd: workspaceDir`. Filters to workspace-known project names.
8. **Build cross-workspace expect-graph + topo-sort** (Kahn's). Workspace-biased: ties resolve toward same-workspace continuation, minimizing bouncing.
9. **Filter by `modules.json.adminModules`** — walks the closure. For each missing required dep that's itself a workspace-known project, prompts: "Add `<name>` to adminModules? It's required by `<consumer>`." On yes → adds to modules.json + includes; on no → drops the consumer.
10. **Per-project loop** (in topo order):
    - Track workspace transitions; record any "bounce" (returning to a workspace after building elsewhere).
    - Resolve target. Pre-check already-deployed (ext dir non-empty OR jar contains the project's META-INF/federation entries).
    - Already deployed AND no `--force` → skip with `⏭` log.
    - Already deployed AND `--force` → `cleanRemotes` for that project, then rebuild.
    - **Re-sync federation symlinks for the workspace** (`syncFederationSymlinks(workspaceDir)`) BEFORE `buildLibs`. Picks up any new typings just deployed for upstream projects in earlier iterations.
    - `buildLibs + packRemotes + deployRemotes`, each with `restrictTo: [name]` — NEVER `all`.
11. **Summary** — built / skipped / failed counts. Bounce warning if any non-monotonic workspace ordering was detected.

Usage:

```
npx --yes -p @wiresphere/admin-kit ws-wire-setup-modules               # walk up to find fiddle
npx --yes -p @wiresphere/admin-kit ws-wire-setup-modules --fiddle <p>  # explicit
npx --yes -p @wiresphere/admin-kit ws-wire-setup-modules --force       # clean-then-rebuild already-deployed
npx --yes -p @wiresphere/admin-kit ws-wire-setup-modules -f            # same as --force
```

Also exposed inside the host clone as `npm run ship-setup-modules` (in ws-admin's `admin/package.json`).

## 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: wire-setup-modules` (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 verify the fiddle has `modules.json` and `wpm_modules/` populated (or `additionalAdminModulePaths` listing explicit workspaces) — without candidates the bin warns "no admin-modules workspaces discovered" and exits 0.
- MUST surface the dep-prompt to the user verbatim and pass the answer through (do not auto-decide).
- MUST respect `--force` semantics — without it, already-deployed projects skip (no work, no churn). Use `--force` only when re-deploys are intended.
- MUST surface the bounce warning at the end and explain what it implies (real cross-workspace cycle, or topo-sort tie). See the `federation-error-catalogue` skill entry #10.
- MUST NOT assume the topo will succeed — cycles in the expect-graph cause hard errors. Catch and surface.

## Common pitfalls

- **Empty `<fiddle>/admin/.federation/`** at first invocation → wire-host's initial sync creates no symlinks → first project's build fails with `Cannot find module '<dep>'`. The bin compensates with per-project re-sync inside the loop. If a workspace was wired BEFORE the bin's per-project re-sync was added, manually run `npx ws-sync-paths` in the affected workspace.
- **`modules.json.adminModules` not set** → bin warns and builds every discovered project. Set it explicitly to scope the deploy.
- **Dep-prompt declined → consumer dropped silently.** The bin logs but agents should surface the dropped list to the user explicitly.
- **Project deps the bin can't see.** Only deps in a project's `federation.config.js#externals` are part of the topo graph. Implicit deps (e.g. a peerDep imported but not externalized) don't influence order — they'll appear as runtime missing-share errors.
- **Workspace bounce warning.** Usually indicates a real cross-workspace cycle. Sometimes a topo tie that the workspace-bias couldn't resolve. Audit the relevant projects' externals.

## Out of scope

- This skill does NOT build the admin host — that's `wpm admin` (or the host's own `npm run build`).
- Does NOT compile the script controller — that's `wpm admin-controller`.
- Does NOT manage `modules.json.adminModules` outside dep-prompts (manual edit OR the dep-prompt yes-path are the only modification paths).
- Does NOT operate from inside a single workspace — for that, use [ship-workflow](../ship-workflow/SKILL.md).

## Cross-links

- [ship-workflow/SKILL.md](../ship-workflow/SKILL.md) — single-workspace alternative
- [wire-host/SKILL.md](../wire-host/SKILL.md) — invoked per unwired workspace during discovery
- [clean-workflow/SKILL.md](../clean-workflow/SKILL.md) — `--force` runs this per project
- the `admin-pipeline` skill — the wpm admin flow that invokes this bin
- the `federation-error-catalogue` skill — entry #2 (symlink), #10 (bounce)
- the `wpm-admin-deploy` skill — full contract
