@frontmcp/skills 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -95,17 +95,17 @@ This is a router skill. Follow this order to pick a testing approach, then move
95
95
 
96
96
  ## Cross-Cutting Testing Patterns
97
97
 
98
- | Pattern | Rule |
99
- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
100
- | File naming | Always `.spec.ts` (not `.test.ts`); E2E uses `.e2e.spec.ts` |
101
- | File organization | Split E2E tests by app/feature: `e2e/calc.e2e.spec.ts`, `e2e/ecommerce.e2e.spec.ts`. Never put all tests in a single `server.e2e.spec.ts` |
102
- | Test runner | Standalone projects: use `frontmcp test` (auto-generates Jest/SWC config; discovers `src/**/*.spec.ts(x)`, `__tests__/**/*.spec.ts(x)`, and `e2e/**/*.e2e.spec.ts(x)`; transforms both `.ts` and `.tsx` with the automatic JSX runtime; delegates to a user-provided `jest.config.{ts,js,mjs,cjs,json}` if present). Nx monorepos: use `nx test <lib>` (resolves the project's `jest.config.ts`). Never invoke `jest --config ...` directly |
103
- | Coverage threshold | 95%+ across statements, branches, functions, lines |
104
- | Test descriptions | Plain English, no prefixes like "PT-001"; describe behavior not implementation |
105
- | Mocking | Mock providers via DI token replacement, never mock the framework |
106
- | httpMock scope | `httpMock` intercepts HTTP in the **test process** only, NOT in the MCP server subprocess. Do not use httpMock to intercept server-to-API calls — those happen in the child process. Use httpMock for verifying client-to-server request shapes or mocking external APIs called from the test itself |
107
- | Error testing | Assert `instanceof` specific error class AND MCP error code |
108
- | Async | Always `await` async operations; use `expect(...).rejects.toThrow()` for async errors |
98
+ | Pattern | Rule |
99
+ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
100
+ | File naming | Always `.spec.ts` (not `.test.ts`); E2E uses `.e2e.spec.ts` |
101
+ | File organization | Split E2E tests by app/feature: `e2e/calc.e2e.spec.ts`, `e2e/ecommerce.e2e.spec.ts`. Never put all tests in a single `server.e2e.spec.ts` |
102
+ | Test runner | Standalone projects: use `frontmcp test` (auto-generates Jest/SWC config; discovers `src/**/*.spec.ts(x)`, `__tests__/**/*.spec.ts(x)`, and `e2e/**/*.e2e.spec.ts(x)`; transforms both `.ts` and `.tsx` with the automatic JSX runtime; transpiles ESM-only deps such as `jose` under npm, yarn AND pnpm's `node_modules/.pnpm/` store — add your own via `test.esmPackages` in `frontmcp.config.ts`; delegates to a user-provided `jest.config.{ts,js,mjs,cjs,json}` if present, which drops the injected ESM transforms). Nx monorepos: use `nx test <lib>` (resolves the project's `jest.config.ts`). Never invoke `jest --config ...` directly |
103
+ | Coverage threshold | 95%+ across statements, branches, functions, lines |
104
+ | Test descriptions | Plain English, no prefixes like "PT-001"; describe behavior not implementation |
105
+ | Mocking | Mock providers via DI token replacement, never mock the framework |
106
+ | httpMock scope | `httpMock` intercepts HTTP in the **test process** only, NOT in the MCP server subprocess. Do not use httpMock to intercept server-to-API calls — those happen in the child process. Use httpMock for verifying client-to-server request shapes or mocking external APIs called from the test itself |
107
+ | Error testing | Assert `instanceof` specific error class AND MCP error code |
108
+ | Async | Always `await` async operations; use `expect(...).rejects.toThrow()` for async errors |
109
109
 
110
110
  ## Common Patterns
111
111
 
@@ -145,13 +145,14 @@ This is a router skill. Follow this order to pick a testing approach, then move
145
145
 
146
146
  ## Troubleshooting
147
147
 
148
- | Problem | Cause | Solution |
149
- | ---------------------------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------- |
150
- | Jest not finding test files | Wrong file extension (`.test.ts` instead of `.spec.ts`) | Rename to `.spec.ts`; check `testMatch` in jest.config |
151
- | Coverage below 95% | Untested error paths or conditional branches | Run `frontmcp test --coverage` and inspect uncovered lines in the report |
152
- | E2E test timeout | Server startup too slow or port conflict | Increase Jest timeout; use random port allocation |
153
- | DI resolution fails in tests | Provider not registered in test scope | Register mock providers before creating the test context |
154
- | Istanbul shows 0% on async methods | TypeScript source-map mismatch with Istanbul | Known issue with some TS compilation settings; verify coverage with actual test output |
148
+ | Problem | Cause | Solution |
149
+ | ---------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
150
+ | Jest not finding test files | Wrong file extension (`.test.ts` instead of `.spec.ts`) | Rename to `.spec.ts`; check `testMatch` in jest.config |
151
+ | `SyntaxError: Unexpected token 'export'` | An ESM-only dependency is being ignored instead of transpiled | Add it to `test.esmPackages` in `frontmcp.config.ts`. With a hand-written `jest.config.ts`, use the pnpm-safe `transformIgnorePatterns` in [`setup-testing`](./references/setup-testing.md#jest-configuration) AND make sure `transform` matches `.js` (`^.+\.[tj]sx?$` + `allowJs`) — un-ignoring a file does nothing if no transform matches it |
152
+ | Coverage below 95% | Untested error paths or conditional branches | Run `frontmcp test --coverage` and inspect uncovered lines in the report |
153
+ | E2E test timeout | Server startup too slow or port conflict | Increase Jest timeout; use random port allocation |
154
+ | DI resolution fails in tests | Provider not registered in test scope | Register mock providers before creating the test context |
155
+ | Istanbul shows 0% on async methods | TypeScript source-map mismatch with Istanbul | Known issue with some TS compilation settings; verify coverage with actual test output |
155
156
 
156
157
  ## Examples
157
158
 
@@ -22,8 +22,14 @@ export default {
22
22
  displayName: 'my-lib',
23
23
  preset: '../../jest.preset.js',
24
24
  transform: {
25
- '^.+\\.tsx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
25
+ // Must cover `.js` too: `transformIgnorePatterns` only un-ignores a file,
26
+ // the transform still has to match it. An ESM dep's `.js` would otherwise
27
+ // reach Jest untransformed.
28
+ '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
26
29
  },
30
+ // ESM-only deps (jose, reached via @frontmcp/sdk) must be transpiled, not
31
+ // ignored. The `.pnpm` skip keeps this correct under pnpm's symlinked store.
32
+ transformIgnorePatterns: ['node_modules[/\\\\](?!\\.pnpm[/\\\\])(?!(jose)[/\\\\])'],
27
33
  coverageThreshold: {
28
34
  global: {
29
35
  statements: 95,
@@ -42,6 +48,7 @@ export default {
42
48
  "compilerOptions": {
43
49
  "outDir": "../../dist/out-tsc",
44
50
  "module": "commonjs",
51
+ "allowJs": true,
45
52
  "types": ["jest", "node"]
46
53
  },
47
54
  "include": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.spec.tsx"]
@@ -432,8 +432,16 @@ export default {
432
432
  displayName: 'my-lib',
433
433
  preset: '../../jest.preset.js',
434
434
  transform: {
435
- '^.+\\.tsx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
435
+ // Must cover `.js` too: `transformIgnorePatterns` only un-ignores a file,
436
+ // the transform still has to match it. An ESM dep's `.js` would otherwise
437
+ // reach Jest untransformed.
438
+ '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
436
439
  },
440
+ // ESM-only deps (jose, reached via @frontmcp/sdk) must be transpiled, not
441
+ // ignored. Skipping the `.pnpm` segment re-anchors the regex on the inner
442
+ // `node_modules/`, so this holds under npm, yarn AND pnpm's symlinked store;
443
+ // the trailing character classes cover Windows separators.
444
+ transformIgnorePatterns: ['node_modules[/\\\\](?!\\.pnpm[/\\\\])(?!(jose)[/\\\\])'],
437
445
  coverageThreshold: {
438
446
  global: {
439
447
  statements: 95,
@@ -445,6 +453,26 @@ export default {
445
453
  };
446
454
  ```
447
455
 
456
+ Add further ESM-only packages to the alternation (`(jose|nanoid)`). A plain
457
+ `node_modules/(?!(jose)/)` silently breaks under pnpm: the real path is
458
+ `node_modules/.pnpm/jose@6.2.3/node_modules/jose/...`, the unanchored regex
459
+ matches at the first `node_modules/`, and the run fails with
460
+ `SyntaxError: Unexpected token 'export'`.
461
+
462
+ In standalone projects driven by `frontmcp test`, prefer `test.esmPackages` in
463
+ `frontmcp.config.ts` — the injected config already carries the pattern above:
464
+
465
+ ```typescript
466
+ // frontmcp.config.ts
467
+ import { defineConfig } from 'frontmcp';
468
+
469
+ export default defineConfig({
470
+ name: 'my-server',
471
+ deployments: [{ target: 'node' }],
472
+ test: { esmPackages: ['nanoid'] },
473
+ });
474
+ ```
475
+
448
476
  ## Manual Testing with frontmcp dev
449
477
 
450
478
  For interactive development and manual testing, use the CLI:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/skills",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Curated skills catalog for FrontMCP projects",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "homepage": "https://docs.agentfront.dev",