kramme-connect-workflow/skills/kramme:connect:extract-nx-libs/SKILL.md
Use this Skill when working in the Connect monorepo and needing to extract app code into proper Nx libraries.
npx skillsauth add abildtoft/kramme-cc-workflow kramme:connect:extract-nx-libsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Migrate code from the Connect app folder (apps/connect/) into proper Nx libraries following established conventions.
apps/connect/src/app/ to libs/Follow the naming convention: libs/<product>/<application>/<domain>/<type>
Products: academy, coaching, connect, shared
Applications: cms, shared, ufa (User-Facing Application)
Types: assets, data-access, domain, feature, styles, test-util, ui, util
For a feature like "certification-rubrics", create:
libs/connect/
├── shared/<domain>/domain/ # Shared types used by both CMS and UFA
├── cms/<domain>/
│ ├── domain/ # CMS-specific models/types
│ ├── data-access/ # CMS store, API clients
│ └── feature/ # CMS components
└── ufa/<domain>/
├── domain/ # UFA-specific models/types
├── data-access/ # UFA store, API clients
└── feature/ # UFA components
Before planning the migration, discover ALL code related to the feature and confirm scope with the user.
Search the entire codebase for code related to the feature:
# Find all files with the feature name
find Connect/ng-app-monolith -type f -name "*<feature>*" | grep -v node_modules
# Search for feature-related imports and references
grep -r "<FeatureName>" Connect/ng-app-monolith --include="*.ts" --include="*.html" | grep -v node_modules
# Check for related types, interfaces, enums
grep -r "interface.*<Feature>\|type.*<Feature>\|enum.*<Feature>" Connect/ng-app-monolith --include="*.ts" | grep -v node_modules
Organize findings into categories:
apps/connect/src/app/)
ALWAYS ask the user to confirm what should be moved:
Present a summary like:
## Found Feature-Related Code
### Components (X files)
- `apps/connect/src/app/site/event/components/<feature>/` (UFA)
- `apps/connect/src/app/cms/cms/components/<feature>/` (CMS)
### Stores/Services (X files)
- `libs/connect/cms/<related>/data-access/` - contains <feature> store actions
### Types (X files)
- `libs/connect/cms/<related>/data-access/src/lib/<feature>.model.ts`
### Routes referencing feature
- `apps/connect/src/app/site/event/event.routes.ts`
- `apps/connect/src/app/cms/client/client-cms.routes.ts`
### Related but potentially separate
- `apps/connect/src/app/cms/event/components/reporting/<feature>-reporting/`
(reporting feature - may stay separate)
**Questions:**
1. Should all components be moved to new libraries?
2. Should the store be extracted or stay in existing library?
3. Should reporting components be included or remain separate?
Ask user to confirm the domain name for the new libraries:
<feature> or <feature>-<qualifier>libs/connect/Structure commits in logical, reviewable chunks. Each commit should be atomic and build on the previous.
Extract shared types first
Extract shared <Domain> types to shared domain library
libs/connect/shared/<domain>/domain/Create domain libraries for CMS/UFA-specific types
Add <Domain> domain libraries for CMS and UFA
libs/connect/cms/<domain>/domain/libs/connect/ufa/<domain>/domain/Move stores and API clients
Move <Domain> stores to Nx data-access libraries
Move components
Move <Domain> components to Nx feature libraries
Rename files and selectors to match conventions
Rename <Domain> files, components, and selectors
my-component.ts → ufa-<domain>-my-component.tsco-my-component → co-ufa-<domain>-my-componentAdd metadata and cleanup
Add tech-debt tags to <Domain> libraries
project.jsonfeat:, fix:, etc.)Based on discovery phase, identify what code moves where:
libs/connect/shared/<domain>/domain/libs/connect/cms/<domain>/feature/libs/connect/cms/<domain>/data-access/libs/connect/ufa/<domain>/feature/libs/connect/ufa/<domain>/data-access/cd Connect/ng-app-monolith
# Create domain libraries for types
yarn exec nx g @consensus/nx:angular-library --product=connect --application=shared --domain=<domain> --type=domain
yarn exec nx g @consensus/nx:angular-library --product=connect --application=cms --domain=<domain> --type=domain
yarn exec nx g @consensus/nx:angular-library --product=connect --application=ufa --domain=<domain> --type=domain
# Create data-access libraries for stores/clients
yarn exec nx g @consensus/nx:angular-library --product=connect --application=cms --domain=<domain> --type=data-access
yarn exec nx g @consensus/nx:angular-library --product=connect --application=ufa --domain=<domain> --type=data-access
# Create feature libraries for components
yarn exec nx g @consensus/nx:angular-library --product=connect --application=cms --domain=<domain> --type=feature
yarn exec nx g @consensus/nx:angular-library --product=connect --application=ufa --domain=<domain> --type=feature
Naming conventions:
cms-<domain>-<name>.component.tsufa-<domain>-<name>.component.ts<application>-<domain>.store.ts<application>-<domain>.client.ts<application>-<domain>.model.ts or shared-<domain>.types.tsSelector prefixes:
co-cms-<domain>-co-ufa-<domain>-Shared types (in shared/<domain>/domain/):
CMS-specific types (in cms/<domain>/domain/):
locked, distribution)UFA-specific types (in ufa/<domain>/domain/):
Omit<SharedType, 'adminField'> to hide admin-only fieldsExample type separation:
// shared-certification-rubrics.types.ts
export interface CertificationsQuestionnaire {
id: string;
title: string;
locked: boolean; // Admin-only concept
// ...
}
// ufa-certification-rubrics.model.ts
import { CertificationsQuestionnaire } from '@consensus/connect/shared/certification-rubrics/domain';
// Hide 'locked' from UFA consumers
export type ClientCertificationQuestionnaire = Omit<CertificationsQuestionnaire, 'locked'>;
In each library's index.ts:
// Only export public API
export * from './lib/<domain>.model';
export { MyComponent } from './lib/my-component/my-component.component';
Update consuming code:
// Before (relative import from app)
import { MyComponent } from './components/my-component/my-component.component';
// After (library import)
import { MyComponent } from '@consensus/connect/ufa/<domain>/feature';
Update route imports to use the new library paths:
// apps/connect/src/app/site/event/event.routes.ts
import {
ComponentA,
ComponentB,
} from '@consensus/connect/ufa/<domain>/feature';
If migrating legacy code with known issues, add appropriate tags in project.json:
{
"tags": [
"product:connect",
"application:ufa",
"domain:<domain>",
"type:feature",
"tech-debt:default-change-detection",
"tech-debt:lax-typing"
]
}
After migration:
apps/connect/Confirm tsconfig.base.json has the new path aliases:
{
"@consensus/connect/shared/<domain>/domain": ["libs/connect/shared/<domain>/domain/src/index.ts"],
"@consensus/connect/cms/<domain>/data-access": ["libs/connect/cms/<domain>/data-access/src/index.ts"],
"@consensus/connect/cms/<domain>/domain": ["libs/connect/cms/<domain>/domain/src/index.ts"],
"@consensus/connect/cms/<domain>/feature": ["libs/connect/cms/<domain>/feature/src/index.ts"],
"@consensus/connect/ufa/<domain>/data-access": ["libs/connect/ufa/<domain>/data-access/src/index.ts"],
"@consensus/connect/ufa/<domain>/domain": ["libs/connect/ufa/<domain>/domain/src/index.ts"],
"@consensus/connect/ufa/<domain>/feature": ["libs/connect/ufa/<domain>/feature/src/index.ts"]
}
# Build affected projects
yarn exec nx affected --targets=build --base=master
# Lint affected projects
yarn exec nx affected --targets=lint --base=master
# Run affected tests
yarn exec nx affected --targets=test --base=master
# Check for remaining feature code in app folder
find Connect/ng-app-monolith/apps/connect -type d -name "*<domain>*"
find Connect/ng-app-monolith/apps/connect -type f -name "*<domain>*"
# Check for old import paths still in use
grep -r "from '\.\./.*<domain>" Connect/ng-app-monolith/apps/connect --include="*.ts"
See branch Abildtoft/wan-148-impl for a complete example of migrating Certification Rubrics from apps/connect/ into proper Nx libraries.
development
Runs kramme:pr:code-review as a closeout review loop for local or PR branch changes before commit, ship, or final response. Use when the user asks for autoreview, second-model review, or a final code-review pass after non-trivial edits. Not for UX, visual, accessibility, or product review.
development
Guides topic-level understanding verification for a PR, branch, feature, document, spec, design decision, bug fix, or other concrete subject. Use when the user asks to confirm, quiz, drill, teach-and-check, or verify that they understand a topic. Maintains a topic-specific checklist artifact and requires demonstrated understanding before marking the topic complete. Not for ordinary explanations without verification, end-of-session summaries, or code/test correctness checks.
testing
Design a CI/CD pipeline with quality gates, a <10-minute budget, feature-flag lifecycle, and an exit checklist. Use when adding a new CI pipeline, changing gate configuration, or planning a rollout for a new service. Complementary to kramme:pr:fix-ci (which fixes failures in an existing pipeline). Covers gate ordering, secrets storage, branch protection, rollback mechanism, and staged-rollout guardrails — not a rollout-execution runbook.
tools
--- name: kramme:visual:demo-reel description: Capture local demo evidence for observable product behavior: screenshots, before/after image sets, browser reels, terminal recordings, and short GIF/video proof. Use when shipping UI changes, CLI features, or any change where PR reviewers would benefit from visual or behavioral evidence. argument-hint: "[what to capture] [--url <url>|auto] [--tier static|before-after|browser-reel|terminal-recording]" disable-model-invocation: true user-invocable: tr