modernizing-toolchain
Migrates lenne.tech projects from the legacy jest+eslint+prettier toolchain to the current vitest+oxlint+oxfmt baseline used by nest-server-starter and nuxt-base-starter. Covers swc decoratorMetadata config, the @Prop union-type fix for SWC, supertest default-import correction, ESM/CJS interop, the Nitro PORT-vs-NITRO_PORT bug, ANSI escape stripping in workspace runners (lerna/nx), free-port logic for check-server-start.sh, the offers-pattern config.env.ts (NSC__-only + fail-fast + auto-derived appUrl), and the multi-phase check-envs.sh smoke test. Activates whenever someone is migrating an existing project to the new toolchain, debugging "Cannot determine a type for the X field" Mongoose errors, ERR_SOCKET_BAD_PORT crashes from check-server-start, or wants to align an existing project with the current starter conventions.
What this skill does
# Modernizing the lenne.tech Toolchain
## When This Skill Activates
- Migrating an existing API/App from jest → vitest, eslint → oxlint, prettier → oxfmt
- Adopting the `check` / `check:fix` / `check:envs` pipeline used by the starters
- Debugging Mongoose `"Cannot determine a type for the X field (union/intersection/ambiguous type was used)"` after switching to vitest+SWC
- Debugging `ERR_SOCKET_BAD_PORT` from `node .output/server/index.mjs` in any check pipeline
- Debugging missing or stale `types.gen.ts` after a Nuxt update
- Aligning a project with the current `config.env.ts` shape (NSC__-only + fail-fast + helper functions)
- Cleaning up phantom Unix-domain-sockets named `[33m12345[39m` in the project root
## Reference Repositories (public)
All references in this skill are to the public lenne.tech repos. **Never reference local clone paths in skill output**:
- API starter: <https://github.com/lenneTech/nest-server-starter>
- API framework: <https://github.com/lenneTech/nest-server>
- App starter: <https://github.com/lenneTech/nuxt-base-starter>
- App framework: <https://github.com/lenneTech/nuxt-extensions>
- Monorepo template: <https://github.com/lenneTech/lt-monorepo>
- CLI: <https://github.com/lenneTech/cli>
## The Migration Checklist (full pipeline)
Apply these in order. Each phase has a clear "done" signal — proceed only when met.
### Phase 1 — Inventory
1. Detect project shape: monorepo (`projects/api`, `projects/app`) vs single-package?
2. Detect package manager: `npm` (check `package-lock.json`) vs `pnpm` (check `pnpm-lock.yaml`).
3. Detect baseline toolchain in EACH subproject:
- jest? → `jest-e2e.json` or `jest.config.*` exists
- eslint? → `eslint.config.*` or `.eslintrc.*` exists
- prettier? → `.prettierrc*` exists
- vitest? → `vitest.config.ts` or `vitest-e2e.config.ts` exists
- oxlint? → `oxlint.json` exists
4. Detect deployment shape: GitLab CI? Docker Compose? both?
The migration is identical regardless of mode (monorepo / single, npm / pnpm) — only the invocation
syntax changes. Examples in this skill use `npm run` for npm projects and `pnpm run` for pnpm projects;
substitute as appropriate.
### Phase 2 — API: jest → vitest
1. **Install dev dependencies**:
```
<pm> add -D vitest @vitest/coverage-v8 @vitest/ui unplugin-swc vite-plugin-node
```
Pin `vitest` to the same version the upstream `nest-server-starter` uses (check
`https://raw.githubusercontent.com/lenneTech/nest-server-starter/main/package.json`).
2. **Create `vitest-e2e.config.ts`** at the API root. The exact swc options are mandatory —
anything missing causes silent test failures with confusing error messages:
```ts
import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [
swc.vite({
jsc: {
target: 'es2022',
transform: {
decoratorMetadata: true, // required: NestJS DI + Mongoose @Prop need this
legacyDecorator: true, // required: nest uses pre-stage-3 decorators
useDefineForClassFields: true, // must MATCH tsconfig.useDefineForClassFields
},
},
}),
],
test: {
environment: 'node',
exclude: ['tests/helpers/**/*', 'tests/fixtures/**/*', 'tests/global-setup.ts', 'tests/report.js'],
fileParallelism: false, // sequential: each test boots a NestJS app
globals: true,
globalSetup: ['tests/global-setup.ts'],
hookTimeout: 60000,
include: ['tests/**/*.e2e-spec.ts'],
isolate: true,
maxConcurrency: 1,
pool: 'forks', // forks > threads for NestJS
reporters: ['default'],
retry: 3, // mongo race conditions are flaky
root: './',
teardownTimeout: 30000,
testTimeout: 30000,
watch: false,
},
});
```
3. **Create `vitest.config.ts`** for unit specs (slim, mostly defaults):
```ts
import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [swc.vite()],
test: {
environment: 'node',
globals: true,
include: ['src/**/*.spec.ts'],
root: './',
},
});
```
4. **Create `tests/global-setup.ts`** that drops the e2e DB before the run:
```ts
import { MongoClient } from 'mongodb';
export async function setup() {
const uri = process.env.NSC__MONGOOSE__URI || 'mongodb://127.0.0.1/<your-db>-e2e';
const c = await MongoClient.connect(uri);
await c.db().dropDatabase();
await c.close();
}
```
Do NOT import `src/config.env` here — it runs outside the swc pipeline and will fail with
`Cannot find module './src/config.env'`.
5. **Update `tsconfig.json`**:
```jsonc
{
"compilerOptions": {
"target": "es2022", // bump from es2020 — needed for `new Error(msg, { cause })`
"useDefineForClassFields": true, // MUST match swc setting above
"types": ["vitest/globals"] // describe/it/expect/vi available without per-file imports
}
}
```
6. **Migrate all `jest.*` calls** to `vi.*`:
- `jest.spyOn` → `vi.spyOn`
- `jest.fn` → `vi.fn`
- `jest.mock` → `vi.mock`
- `jest.restoreAllMocks` → `vi.restoreAllMocks`
- `jest.clearAllMocks` → `vi.clearAllMocks`
- `jest.resetAllMocks` → `vi.resetAllMocks`
Watch for **multi-line patterns**:
```ts
const fetchSpy = jest // <- stays here on its own line
.spyOn(globalThis, 'fetch')
```
`sed 's/jest\.spyOn/vi.spyOn/g'` won't catch this. Run it again as
`sed 's/^[[:space:]]*const \([a-zA-Z]*\) = jest$/ const \1 = vi/' || grep "jest$" tests/`.
7. **Replace `import * as supertest`** with default import:
```diff
-import * as supertest from 'supertest';
+import supertest from 'supertest';
```
The namespace form resolves to `{ default: <function> }` under SWC's CJS↔ESM interop and breaks
the call site.
8. **The @Prop union-type fix (CRITICAL)**: SWC's `decoratorMetadata` emits `Object` for TypeScript
union types, where `ts-jest` emits `String`. Mongoose rejects `Object` with:
```
Cannot determine a type for the "MyModelClass.statusField" field
(union/intersection/ambiguous type was used). Make sure your property
is decorated with a "@Prop({ type: TYPE_HERE })" decorator.
```
**Fix every `@Prop`** whose property has a union/literal-union TypeScript type by adding
`type: String` (or `type: Object` for record-like unions):
```diff
-@Prop({ default: 'none' }) transform?: TransformKind;
+@Prop({ default: 'none', type: String }) transform?: TransformKind;
-@Prop({ enum: [...], required: true }) mode: AuthMode;
+@Prop({ enum: [...], required: true, type: String }) mode: AuthMode;
-@Prop({ default: null }) someId: null | string;
+@Prop({ default: null, type: String }) someId: null | string;
```
Sweep with: `grep -rn "@Prop" src/server/modules/ | grep -v "type:" | head`. Inspect each match,
add `type:` if the property type is a literal union (e.g. `'a' | 'b'`), a renamed type alias for
such a union, or `null | string`.
9. **Update package.json scripts**:
```jsonc
{
"scripts": {
"test": "<pm> run vitest",
"test:ci": "<pm> run vitest:ci",
"test:e2e": "<pm> run vitest",
"vitest": "NODE_ENV=e2e vitest run --config vitest-e2e.config.ts",
"vitest:ci": "NODE_ENV=ci vitest run --config vitest-e2e.config.ts",
"vitest:cov": "NODE_ENV=e2e vitest run --coverage --config vitest-e2e.config.ts",
"vitest:watch": "NODE_ENV=e2e vitest --config vitest-e2e.config.ts",
"vitest:unit": "vitest run --config vitest.config.ts"
}
}
```
10. **Remove jest artifacts**:
- delete `jest-e2e.json`, `babel.config.js`, `tests/report.js`
- uninstall `jest`, `@types/jest`, `babel-jestRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.