---
name: ship-workflow
description: Build + pack + deploy a single federated module to the bonded fiddle via `npm run ship` (which runs `ws-modules --build --pack --deploy`). Covers per-project deploy mechanics, target resolution (jar vs ext), typings publication, and what arguments scope the run.
when_to_use: Activates when the user types `npm run ship`, asks "deploy this module", "ship to fiddle", "rebuild and deploy", or invokes `ws-modules` directly. Also when iterating on a single module's code and wanting to push the change to the bonded fiddle for testing.
paths:
  - "**/package.json"
allowed-tools:
  - Read
  - Edit
  - Write
  - Bash
---

Language: English only.

This skill is used to ship one (or more) federated modules from a bonded admin-modules workspace into a fiddle. `npm run ship` in any admin-kit-scaffolded workspace is an alias for `ws-modules --build --pack --deploy`. Output lands at `<fiddle>/admin/.federation/<id>/` (typings) plus either `<fiddle>/modules/<id>-*.jar` (jar target, default) or `<fiddle>/scripts/ext-admin-remotes/<id>/` (ext target).

## When this skill applies

- "ship this module"
- "deploy `<name>` to the fiddle"
- "rebuild and push to fiddle"
- "iterate on this remote" (after a code change)
- User runs `npm run ship` or `npx ws-modules --build --pack --deploy`
- User runs `npm run ship:dev` (development configuration)

## How it works

Entry point: `/Users/ph/projects/ws-admin-aux/admin-kit/bin/ws-modules.js`. Driver lib: `/Users/ph/projects/ws-admin-aux/admin-kit/lib/build-modules.js`, `/Users/ph/projects/ws-admin-aux/admin-kit/lib/deploy-remotes.js`. Workspace's `npm run ship` script (in the template's package.json) is just: `ws-modules --build --pack --deploy`.

`ws-modules` reads the bonded fiddle from `wsconfig.json#wpmRoot`, then per project:

1. **buildLibs** — runs `ng run <project>:build-lib` (ng-packagr) → `dist/<project>/` (typings + fesm + package.json).
2. **packRemotes** — runs `ng run <project>:build` (native-federation builder) → `dist/<project>-remote/` (runtime chunks + `remoteEntry.json`). Then stages into `dist/admin-remotes/<project>/{federation.json, remote/<chunks>}`.
3. **deployRemotes** — resolves the target (`jar` or `ext`) via `resolveTarget()` in `target-resolution.js`, copies the staged tree:
   - `target.kind === 'ext'` → copy to `<fiddle>/scripts/ext-admin-remotes/<id>/`.
   - `target.kind === 'jar'` → pack into a jar via `pack-into-jar.js`, write to `<fiddle>/modules/<id>-*.jar`.
   - Publishes lib typings to `<fiddle>/admin/.federation/<id>/` regardless of target (for cross-workspace consumer's compile time).

Selective invocation:

```
npm run ship                                    # default = all projects in workspace (rare; usually targeted)
npx ws-modules --build --pack --deploy <name>   # one project by name (preferred)
npx ws-modules --build --pack --deploy <a> <b>  # multiple projects, in topo order
npx ws-modules --build --pack --deploy --kind ext    # filter by deploy target
npx ws-modules --build                          # build only, no deploy
npx ws-modules --deploy                         # deploy a previously-built dist/
```

`npm run ship:dev` runs the same flow with the dev configuration (sourcemaps, verbose). See the `federation-dev-build` skill.

## 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: ship-workflow` (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 resolve scope before invoking: which project(s) need shipping? Prefer targeted invocation (`<name>` argument) over `npm run ship` with no args — the latter rebuilds every project in the workspace, which is wasteful and breaks the topo-bias optimization in [wire-setup-modules](../wire-setup-modules/SKILL.md).
- MUST verify the workspace is bonded (`wsconfig.json` exists with a `wpmRoot`) before invoking. If absent, run [wire-host](../wire-host/SKILL.md) first.
- MUST run from the workspace root (where `angular.json` lives).
- MUST NOT use `ws-modules` to ship across MULTIPLE workspaces simultaneously — that's [wire-setup-modules](../wire-setup-modules/SKILL.md)'s job, run from the fiddle.
- MUST surface deploy paths in the final report so the user can verify (e.g. "→ `<fiddle>/scripts/ext-admin-remotes/<id>/`").

## Common pitfalls

- **Cross-workspace dep not symlinked.** `npm run ship` doesn't auto-refresh `node_modules/<dep>` symlinks for cross-workspace deps (only `ws-wire-setup-modules` does that between projects). Run `npx ws-sync-paths` first if the lib build errors with `Cannot find module '<dep>'`. See the `federation-error-catalogue` skill entry #2.
- **Jar shadowed by stale ext entry.** After switching a project from ext to jar (or back), the old artifact may still exist. The deploy doesn't auto-remove the alternative. See the `federation-error-catalogue` skill entry #3 — clean explicitly via [clean-workflow](../clean-workflow/SKILL.md).
- **`public-api.ts` missing the expansion-component re-exports.** Ship succeeds, but at runtime the expansion scope renders blank. Federation-error-catalogue entry #12.
- **Module duplication.** A consumer remote shipped its own copy of a shared package. Triggers when someone hand-edits `federation.config.js` to use raw `shared: {...}` instead of `share(remoteShared(...))`. Federation-error-catalogue entry #6.
- **Running from inside `projects/<name>/`.** `ws-modules` expects the workspace root. Wrong cwd → cryptic resolution errors.

## Out of scope

- This skill does NOT bond the workspace to a fiddle — that's [wire-host](../wire-host/SKILL.md) (one-time per workspace).
- Does NOT orchestrate across workspaces — that's [wire-setup-modules](../wire-setup-modules/SKILL.md), invoked from the fiddle by `wpm admin`.
- Does NOT scrub deployed artifacts — that's [clean-workflow](../clean-workflow/SKILL.md).
- Does NOT touch `<fiddle>/build/controller/adminFederation.js` or the host SPA — those are `wpm admin-controller` and `wpm admin` concerns.
- Does NOT bump the project's version — see the `changelog-and-versioning` skill.

## Cross-links

- [wire-host/SKILL.md](../wire-host/SKILL.md) — bond workspace before first ship
- [clean-workflow/SKILL.md](../clean-workflow/SKILL.md) — scrub before re-ship to a different target
- [wire-setup-modules/SKILL.md](../wire-setup-modules/SKILL.md) — fiddle-level orchestration alternative
- the `federation-dev-build` skill — `npm run ship:dev` mechanics
- the `federation-error-catalogue` skill — common ship failures
