@jaypie/mcp 0.3.2 → 0.4.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.
Files changed (79) hide show
  1. package/dist/createMcpServer.d.ts +7 -1
  2. package/dist/index.js +26 -3135
  3. package/dist/index.js.map +1 -1
  4. package/dist/suite.d.ts +1 -0
  5. package/dist/suite.js +2442 -0
  6. package/dist/suite.js.map +1 -0
  7. package/package.json +8 -3
  8. package/release-notes/constructs/1.2.17.md +11 -0
  9. package/release-notes/fabric/0.1.2.md +11 -0
  10. package/release-notes/fabric/0.1.3.md +25 -0
  11. package/release-notes/fabric/0.1.4.md +42 -0
  12. package/release-notes/mcp/0.3.3.md +12 -0
  13. package/release-notes/mcp/0.3.4.md +36 -0
  14. package/release-notes/mcp/0.4.0.md +27 -0
  15. package/release-notes/testkit/1.2.15.md +23 -0
  16. package/skills/agents.md +25 -0
  17. package/skills/aws.md +107 -0
  18. package/skills/cdk.md +141 -0
  19. package/skills/cicd.md +152 -0
  20. package/skills/datadog.md +129 -0
  21. package/skills/debugging.md +148 -0
  22. package/skills/dns.md +134 -0
  23. package/skills/dynamodb.md +140 -0
  24. package/skills/errors.md +142 -0
  25. package/skills/fabric.md +191 -0
  26. package/skills/index.md +7 -0
  27. package/skills/jaypie.md +100 -0
  28. package/skills/legacy.md +97 -0
  29. package/skills/logs.md +160 -0
  30. package/skills/mocks.md +174 -0
  31. package/skills/models.md +195 -0
  32. package/skills/releasenotes.md +94 -0
  33. package/skills/secrets.md +155 -0
  34. package/skills/services.md +175 -0
  35. package/skills/style.md +190 -0
  36. package/skills/tests.md +209 -0
  37. package/skills/tools.md +127 -0
  38. package/skills/topics.md +116 -0
  39. package/skills/variables.md +146 -0
  40. package/skills/writing.md +153 -0
  41. package/prompts/Branch_Management.md +0 -34
  42. package/prompts/Development_Process.md +0 -89
  43. package/prompts/Jaypie_Agent_Rules.md +0 -110
  44. package/prompts/Jaypie_Auth0_Express_Mongoose.md +0 -736
  45. package/prompts/Jaypie_Browser_and_Frontend_Web_Packages.md +0 -18
  46. package/prompts/Jaypie_CDK_Constructs_and_Patterns.md +0 -430
  47. package/prompts/Jaypie_CICD_with_GitHub_Actions.md +0 -371
  48. package/prompts/Jaypie_Commander_CLI_Package.md +0 -166
  49. package/prompts/Jaypie_Core_Errors_and_Logging.md +0 -39
  50. package/prompts/Jaypie_DynamoDB_Package.md +0 -774
  51. package/prompts/Jaypie_Eslint_NPM_Package.md +0 -78
  52. package/prompts/Jaypie_Express_Package.md +0 -630
  53. package/prompts/Jaypie_Fabric_Commander.md +0 -411
  54. package/prompts/Jaypie_Fabric_LLM.md +0 -312
  55. package/prompts/Jaypie_Fabric_Lambda.md +0 -308
  56. package/prompts/Jaypie_Fabric_MCP.md +0 -316
  57. package/prompts/Jaypie_Fabric_Package.md +0 -513
  58. package/prompts/Jaypie_Fabricator.md +0 -617
  59. package/prompts/Jaypie_Ideal_Project_Structure.md +0 -78
  60. package/prompts/Jaypie_Init_CICD_with_GitHub_Actions.md +0 -1186
  61. package/prompts/Jaypie_Init_Express_on_Lambda.md +0 -115
  62. package/prompts/Jaypie_Init_Jaypie_CDK_Package.md +0 -35
  63. package/prompts/Jaypie_Init_Lambda_Package.md +0 -505
  64. package/prompts/Jaypie_Init_Monorepo_Project.md +0 -44
  65. package/prompts/Jaypie_Init_Project_Subpackage.md +0 -65
  66. package/prompts/Jaypie_Legacy_Patterns.md +0 -15
  67. package/prompts/Jaypie_Llm_Calls.md +0 -449
  68. package/prompts/Jaypie_Llm_Tools.md +0 -155
  69. package/prompts/Jaypie_MCP_Package.md +0 -281
  70. package/prompts/Jaypie_Mocks_and_Testkit.md +0 -137
  71. package/prompts/Jaypie_Repokit.md +0 -103
  72. package/prompts/Jaypie_Scrub.md +0 -177
  73. package/prompts/Jaypie_Streaming.md +0 -467
  74. package/prompts/Templates_CDK_Subpackage.md +0 -115
  75. package/prompts/Templates_Express_Subpackage.md +0 -187
  76. package/prompts/Templates_Project_Monorepo.md +0 -326
  77. package/prompts/Templates_Project_Subpackage.md +0 -93
  78. package/prompts/Write_Efficient_Prompt_Guides.md +0 -48
  79. package/prompts/Write_and_Maintain_Engaging_Readme.md +0 -67
@@ -0,0 +1,191 @@
1
+ ---
2
+ description: Fabric service patterns and adapters
3
+ related: services, errors, tools
4
+ ---
5
+
6
+ # Fabric Services
7
+
8
+ Fabric provides a unified service pattern that works across CLI, Lambda, LLM tools, and MCP.
9
+
10
+ ## Core Concept
11
+
12
+ Define a service once, deploy it anywhere:
13
+
14
+ ```typescript
15
+ import { fabricService } from "@jaypie/fabric";
16
+
17
+ const greetService = fabricService({
18
+ alias: "greet",
19
+ description: "Greet a user by name",
20
+ input: {
21
+ name: {
22
+ type: String,
23
+ required: true,
24
+ description: "Name to greet",
25
+ },
26
+ },
27
+ service: async ({ name }) => {
28
+ return `Hello, ${name}!`;
29
+ },
30
+ });
31
+ ```
32
+
33
+ ## Adapters
34
+
35
+ ### Lambda Handler
36
+
37
+ ```typescript
38
+ import { fabricLambdaHandler } from "@jaypie/fabric";
39
+
40
+ export const handler = fabricLambdaHandler(greetService);
41
+ // Invoked via Lambda with { name: "World" }
42
+ ```
43
+
44
+ ### CLI Command
45
+
46
+ ```typescript
47
+ import { fabricCommand } from "@jaypie/fabric";
48
+
49
+ const program = new Command();
50
+ program.addCommand(fabricCommand(greetService));
51
+ // $ cli greet --name World
52
+ ```
53
+
54
+ ### MCP Tool
55
+
56
+ ```typescript
57
+ import { fabricMcp, FabricMcpServer } from "@jaypie/fabric/mcp";
58
+
59
+ // Single service registration
60
+ fabricMcp({ service: greetService, server });
61
+
62
+ // Multi-service server (preferred)
63
+ const server = FabricMcpServer({
64
+ name: "my-server",
65
+ version: "1.0.0",
66
+ services: [greetService, searchService],
67
+ });
68
+ // Available as MCP tools "greet" and "search"
69
+ ```
70
+
71
+ ### LLM Tool
72
+
73
+ ```typescript
74
+ import { fabricLlmTool } from "@jaypie/fabric";
75
+
76
+ const tools = [fabricLlmTool(greetService)];
77
+ // Available to LLM as function call
78
+ ```
79
+
80
+ ## Service Suites
81
+
82
+ Group related services:
83
+
84
+ ```typescript
85
+ import { createServiceSuite, fabricService } from "@jaypie/fabric";
86
+
87
+ const userService = fabricService({
88
+ alias: "user_get",
89
+ description: "Get user by ID",
90
+ input: { id: { type: String, required: true } },
91
+ service: async ({ id }) => User.findById(id),
92
+ });
93
+
94
+ const userListService = fabricService({
95
+ alias: "user_list",
96
+ description: "List all users",
97
+ input: {},
98
+ service: async () => User.find(),
99
+ });
100
+
101
+ const suite = createServiceSuite({
102
+ name: "users",
103
+ version: "1.0.0",
104
+ });
105
+
106
+ suite.register(userService, "users");
107
+ suite.register(userListService, "users");
108
+
109
+ // Access services
110
+ suite.services; // ServiceMeta[] - metadata for listing
111
+ suite.getServiceFunctions(); // Service[] - actual functions
112
+ suite.execute("user_get", { id }); // Direct execution
113
+ ```
114
+
115
+ ### Suite to MCP Server
116
+
117
+ Connect suites directly to MCP:
118
+
119
+ ```typescript
120
+ import { createMcpServerFromSuite } from "@jaypie/fabric/mcp";
121
+
122
+ const server = createMcpServerFromSuite(suite, {
123
+ name: "users-api", // Optional override
124
+ version: "1.0.0",
125
+ });
126
+ // All suite services now available as MCP tools
127
+ ```
128
+
129
+ ## Input Validation
130
+
131
+ Fabric validates inputs automatically:
132
+
133
+ ```typescript
134
+ const service = fabricService({
135
+ input: {
136
+ email: {
137
+ type: String,
138
+ required: true,
139
+ description: "User email address",
140
+ },
141
+ count: {
142
+ type: Number,
143
+ required: false,
144
+ description: "Number of results",
145
+ },
146
+ status: {
147
+ type: ["active", "inactive"] as const,
148
+ required: false,
149
+ description: "Filter by status",
150
+ },
151
+ },
152
+ service: async ({ email, count, status }) => {
153
+ // email: string (validated)
154
+ // count: number | undefined
155
+ // status: "active" | "inactive" | undefined
156
+ },
157
+ });
158
+ ```
159
+
160
+ ## Error Handling
161
+
162
+ Fabric services use Jaypie errors:
163
+
164
+ ```typescript
165
+ import { fabricService } from "@jaypie/fabric";
166
+ import { NotFoundError, BadRequestError } from "jaypie";
167
+
168
+ const service = fabricService({
169
+ alias: "user_get",
170
+ input: { id: { type: String, required: true } },
171
+ service: async ({ id }) => {
172
+ if (!isValidId(id)) {
173
+ throw new BadRequestError("Invalid user ID format");
174
+ }
175
+ const user = await User.findById(id);
176
+ if (!user) {
177
+ throw new NotFoundError(`User ${id} not found`);
178
+ }
179
+ return user;
180
+ },
181
+ });
182
+ ```
183
+
184
+ ## Best Practices
185
+
186
+ 1. **Single Responsibility**: Each service does one thing
187
+ 2. **Descriptive Aliases**: Use `noun_verb` format (`user_get`, `order_create`)
188
+ 3. **Clear Descriptions**: Write for AI tools that need context
189
+ 4. **Input Documentation**: Describe what each input expects
190
+ 5. **Return Types**: Return JSON-serializable data
191
+
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Skill directory listing
3
+ ---
4
+
5
+ # Jaypie Skills
6
+
7
+ Query the Jaypie MCP `skill` tool with one of the following alias keywords `mcp__jaypie__skill(alias: String)`:
@@ -0,0 +1,100 @@
1
+ ---
2
+ description: Jaypie overview and core concepts
3
+ ---
4
+
5
+ # Introduction to Jaypie
6
+
7
+ Jaypie is a complete stack framework for building multi-environment cloud applications on AWS using TypeScript/Node.js.
8
+
9
+ ## Core Packages
10
+
11
+ ### Main Package: `jaypie`
12
+
13
+ The main package provides:
14
+ - **Secrets**: AWS Secrets Manager integration
15
+ - **Errors**: Structured error types (ConfigurationError, etc.)
16
+ - **Events**: Event parsing for Lambda handlers
17
+ - **Lifecycle**: Handler lifecycle management
18
+ - **Logging**: Structured logging with context
19
+ - **Queues**: SQS messaging utilities
20
+
21
+ ```typescript
22
+ import {
23
+ getSecret,
24
+ log,
25
+ ConfigurationError,
26
+ HTTP,
27
+ PROJECT
28
+ } from "jaypie";
29
+ ```
30
+
31
+ ### Infrastructure: `@jaypie/constructs`
32
+
33
+ CDK constructs for AWS infrastructure:
34
+ - Lambda functions with best practices
35
+ - SQS queues with DLQ
36
+ - S3 buckets with encryption
37
+ - CloudFront distributions
38
+ - Secrets Manager secrets
39
+
40
+ ### Testing: `@jaypie/testkit`
41
+
42
+ Testing utilities and mocks:
43
+ - Mock implementations for all Jaypie functions
44
+ - Vitest configuration helpers
45
+ - Test data fabrication
46
+
47
+ ## Project Structure
48
+
49
+ Jaypie projects use npm workspaces:
50
+
51
+ ```
52
+ project/
53
+ ├── packages/ # npm packages
54
+ │ ├── api/ # Express API
55
+ │ └── lib/ # Shared library
56
+ ├── stacks/ # CDK infrastructure
57
+ │ └── cdk/ # CDK app
58
+ └── package.json # Root workspace config
59
+ ```
60
+
61
+ ## Key Conventions
62
+
63
+ ### Environment Variables
64
+
65
+ | Variable | Purpose |
66
+ |----------|---------|
67
+ | `PROJECT_ENV` | Environment: local, sandbox, production |
68
+ | `PROJECT_KEY` | Project identifier for logging |
69
+ | `PROJECT_NONCE` | Unique resource identifier |
70
+ | `LOG_LEVEL` | Log level: trace, debug, info, warn, error |
71
+
72
+ ### Error Handling
73
+
74
+ Never throw vanilla `Error`. Use Jaypie errors:
75
+
76
+ ```typescript
77
+ import { ConfigurationError, NotFoundError } from "jaypie";
78
+
79
+ if (!config.required) {
80
+ throw new ConfigurationError("Missing required config");
81
+ }
82
+ ```
83
+
84
+ ### Logging
85
+
86
+ Use structured logging with context:
87
+
88
+ ```typescript
89
+ import { log } from "jaypie";
90
+
91
+ log.info("Processing request", { userId, action });
92
+ log.error("Request failed", { error: error.message });
93
+ ```
94
+
95
+ ## Next Steps
96
+
97
+ - `skill("style")` - Code style conventions
98
+ - `skill("errors")` - Error handling patterns
99
+ - `skill("tests")` - Testing with Vitest
100
+ - `skill("cdk")` - Infrastructure with CDK
@@ -0,0 +1,97 @@
1
+ ---
2
+ description: Legacy libraries and deprecated patterns
3
+ related: dynamodb, fabric, mocks
4
+ ---
5
+
6
+ # Legacy Patterns
7
+
8
+ Deprecated libraries and patterns that may exist in older Jaypie projects.
9
+
10
+ ## @jaypie/core (Deprecated)
11
+
12
+ Migrated to `@jaypie/kit`. Update imports:
13
+
14
+ ```typescript
15
+ // Old
16
+ import { someUtil } from "@jaypie/core";
17
+
18
+ // New
19
+ import { someUtil } from "@jaypie/kit";
20
+ ```
21
+
22
+ ## @jaypie/mongoose (Legacy)
23
+
24
+ MongoDB/Mongoose integration. Consider DynamoDB for new projects.
25
+
26
+ ### Connection
27
+
28
+ ```typescript
29
+ import { connectMongoose } from "@jaypie/mongoose";
30
+
31
+ export const handler = async (event) => {
32
+ await connectMongoose();
33
+ // Connection cached for Lambda warm starts
34
+ };
35
+ ```
36
+
37
+ ### Models
38
+
39
+ ```typescript
40
+ import mongoose, { Schema, Document } from "mongoose";
41
+
42
+ interface IUser extends Document {
43
+ email: string;
44
+ name: string;
45
+ }
46
+
47
+ const userSchema = new Schema<IUser>({
48
+ email: { type: String, required: true },
49
+ name: { type: String, required: true },
50
+ }, { timestamps: true });
51
+
52
+ export const User = mongoose.model<IUser>("User", userSchema);
53
+ ```
54
+
55
+ ### Mocking
56
+
57
+ ```typescript
58
+ vi.mock("@jaypie/mongoose", async () => {
59
+ const { mockMongoose } = await import("@jaypie/testkit");
60
+ return mockMongoose(vi);
61
+ });
62
+ ```
63
+
64
+ ## Migration Guides
65
+
66
+ ### Mongoose to DynamoDB
67
+
68
+ 1. Define DynamoDB item types (see `skill("dynamodb")`)
69
+ 2. Update data access patterns for single-table design
70
+ 3. Replace Mongoose queries with DynamoDB operations
71
+ 4. Update tests to mock DynamoDB instead of Mongoose
72
+
73
+ ### Core to Kit
74
+
75
+ Direct replacement - same exports, new package name:
76
+
77
+ ```bash
78
+ npm uninstall @jaypie/core
79
+ npm install @jaypie/kit
80
+ ```
81
+
82
+ Update imports throughout codebase.
83
+
84
+ ## When to Keep Legacy
85
+
86
+ Keep legacy patterns when:
87
+ - Existing production system is stable
88
+ - Migration cost outweighs benefits
89
+ - Team expertise is in legacy stack
90
+ - Database has significant existing data
91
+
92
+ Migrate when:
93
+ - Starting new features
94
+ - Performance issues arise
95
+ - Scaling requirements change
96
+ - Simplifying architecture
97
+
package/skills/logs.md ADDED
@@ -0,0 +1,160 @@
1
+ ---
2
+ description: Logging patterns and conventions
3
+ related: debugging, datadog, variables
4
+ ---
5
+
6
+ # Logging Patterns
7
+
8
+ Jaypie provides structured logging for observability.
9
+
10
+ ## Basic Usage
11
+
12
+ ```typescript
13
+ import { log } from "jaypie";
14
+
15
+ log.trace("Detailed debug info");
16
+ log.debug("Debug information");
17
+ log.info("Informational message");
18
+ log.warn("Warning message");
19
+ log.error("Error message");
20
+ log.fatal("Fatal error");
21
+ ```
22
+
23
+ ## Structured Logging
24
+
25
+ Always include context as the second argument:
26
+
27
+ ```typescript
28
+ log.info("User logged in", {
29
+ userId: user.id,
30
+ email: user.email,
31
+ method: "oauth",
32
+ });
33
+
34
+ log.error("Payment failed", {
35
+ orderId: order.id,
36
+ amount: order.total,
37
+ error: error.message,
38
+ });
39
+ ```
40
+
41
+ ## Log Levels
42
+
43
+ | Level | Use For |
44
+ |-------|---------|
45
+ | trace | Very detailed debugging (loops, iterations) |
46
+ | debug | Development debugging |
47
+ | info | Normal operations, business events |
48
+ | warn | Unexpected but handled situations |
49
+ | error | Errors that need attention |
50
+ | fatal | Application cannot continue |
51
+
52
+ ## Setting Log Level
53
+
54
+ Via environment variable:
55
+
56
+ ```bash
57
+ LOG_LEVEL=debug npm run dev
58
+ LOG_LEVEL=trace npm test
59
+ ```
60
+
61
+ In production, typically `info` or `warn`.
62
+
63
+ ## Request Context
64
+
65
+ Include request identifiers for tracing:
66
+
67
+ ```typescript
68
+ log.info("Processing request", {
69
+ requestId: req.id,
70
+ path: req.path,
71
+ userId: req.user?.id,
72
+ });
73
+ ```
74
+
75
+ ## Error Logging
76
+
77
+ Log errors with full context:
78
+
79
+ ```typescript
80
+ try {
81
+ await riskyOperation();
82
+ } catch (error) {
83
+ log.error("Operation failed", {
84
+ error: error.message,
85
+ stack: error.stack,
86
+ input: sanitizedInput,
87
+ });
88
+ throw error;
89
+ }
90
+ ```
91
+
92
+ ## Sensitive Data
93
+
94
+ Never log sensitive data:
95
+
96
+ ```typescript
97
+ // BAD
98
+ log.info("User auth", { password: user.password });
99
+
100
+ // GOOD
101
+ log.info("User auth", { userId: user.id, hasPassword: !!user.password });
102
+ ```
103
+
104
+ ## Searching Logs
105
+
106
+ ### Via MCP (Datadog)
107
+
108
+ ```
109
+ # Search by requestId
110
+ datadog_logs --query "@requestId:abc-123"
111
+
112
+ # Search errors
113
+ datadog_logs --query "status:error" --from "now-1h"
114
+
115
+ # Search by user
116
+ datadog_logs --query "@userId:user-456"
117
+ ```
118
+
119
+ ### Via MCP (CloudWatch)
120
+
121
+ ```
122
+ aws_logs_filter_log_events \
123
+ --logGroupName "/aws/lambda/my-function" \
124
+ --filterPattern "ERROR"
125
+ ```
126
+
127
+ ## Log Format
128
+
129
+ Jaypie logs are JSON-formatted for Datadog:
130
+
131
+ ```json
132
+ {
133
+ "level": "info",
134
+ "message": "User logged in",
135
+ "timestamp": "2024-01-15T10:00:00.000Z",
136
+ "userId": "user-123",
137
+ "method": "oauth",
138
+ "dd": {
139
+ "trace_id": "abc123",
140
+ "span_id": "def456"
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Lambda Logging
146
+
147
+ Lambda handlers automatically add context:
148
+
149
+ ```typescript
150
+ import { lambdaHandler } from "@jaypie/lambda";
151
+
152
+ export const handler = lambdaHandler(async (event) => {
153
+ // Logs automatically include:
154
+ // - requestId
155
+ // - functionName
156
+ // - cold_start indicator
157
+ log.info("Processing", { customField: "value" });
158
+ });
159
+ ```
160
+
@@ -0,0 +1,174 @@
1
+ ---
2
+ description: Mock patterns via @jaypie/testkit
3
+ related: tests, errors
4
+ ---
5
+
6
+ # Testing Mocks
7
+
8
+ `@jaypie/testkit` provides mocks for Jaypie packages in tests.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install -D @jaypie/testkit
14
+ ```
15
+
16
+ ## Setup
17
+
18
+ In your test setup file:
19
+
20
+ ```typescript
21
+ // vitest.setup.ts
22
+ import { vi } from "vitest";
23
+
24
+ vi.mock("jaypie", async () => {
25
+ const { mockJaypie } = await import("@jaypie/testkit");
26
+ return mockJaypie(vi);
27
+ });
28
+ ```
29
+
30
+ Configure in vitest.config.ts:
31
+
32
+ ```typescript
33
+ export default defineConfig({
34
+ test: {
35
+ setupFiles: ["./vitest.setup.ts"],
36
+ },
37
+ });
38
+ ```
39
+
40
+ ## Available Mocks
41
+
42
+ ### Main Package (jaypie)
43
+
44
+ ```typescript
45
+ vi.mock("jaypie", async () => {
46
+ const { mockJaypie } = await import("@jaypie/testkit");
47
+ return mockJaypie(vi);
48
+ });
49
+
50
+ // Mocked: log, getSecret, sendMessage, etc.
51
+ ```
52
+
53
+ ### Logger
54
+
55
+ ```typescript
56
+ vi.mock("@jaypie/logger", async () => {
57
+ const { mockLogger } = await import("@jaypie/testkit");
58
+ return mockLogger(vi);
59
+ });
60
+ ```
61
+
62
+ ### AWS
63
+
64
+ ```typescript
65
+ vi.mock("@jaypie/aws", async () => {
66
+ const { mockAws } = await import("@jaypie/testkit");
67
+ return mockAws(vi);
68
+ });
69
+ ```
70
+
71
+ ### Legacy Mocks
72
+
73
+ For legacy packages, see `skill("legacy")`.
74
+
75
+ ## Using Mocks in Tests
76
+
77
+ ### Verify Logging
78
+
79
+ ```typescript
80
+ import { log } from "jaypie";
81
+
82
+ it("logs the operation", async () => {
83
+ await myFunction();
84
+
85
+ expect(log.info).toHaveBeenCalledWith(
86
+ "Operation completed",
87
+ expect.objectContaining({ userId: "123" })
88
+ );
89
+ });
90
+ ```
91
+
92
+ ### Mock Secret Values
93
+
94
+ ```typescript
95
+ import { getSecret } from "jaypie";
96
+
97
+ beforeEach(() => {
98
+ vi.mocked(getSecret).mockResolvedValue("mock-api-key");
99
+ });
100
+
101
+ it("uses the API key", async () => {
102
+ const result = await myFunction();
103
+
104
+ expect(getSecret).toHaveBeenCalledWith("api-key-name");
105
+ expect(result.authenticated).toBe(true);
106
+ });
107
+ ```
108
+
109
+ ### Mock Errors
110
+
111
+ ```typescript
112
+ import { getSecret } from "jaypie";
113
+ import { ConfigurationError } from "jaypie";
114
+
115
+ it("handles missing secrets", async () => {
116
+ vi.mocked(getSecret).mockRejectedValue(
117
+ new ConfigurationError("Secret not found")
118
+ );
119
+
120
+ await expect(myFunction()).rejects.toThrow(ConfigurationError);
121
+ });
122
+ ```
123
+
124
+ ## Mock Matchers
125
+
126
+ ### toBeJaypieError
127
+
128
+ ```typescript
129
+ import { matchers } from "@jaypie/testkit";
130
+
131
+ expect.extend(matchers);
132
+
133
+ it("throws a Jaypie error", async () => {
134
+ await expect(myFunction()).rejects.toBeJaypieError();
135
+ });
136
+ ```
137
+
138
+ ### toBeValidSchema
139
+
140
+ ```typescript
141
+ it("returns valid schema", () => {
142
+ const result = buildSchema();
143
+ expect(result).toBeValidSchema();
144
+ });
145
+ ```
146
+
147
+ ## Per-Test Mock Reset
148
+
149
+ ```typescript
150
+ beforeEach(() => {
151
+ vi.clearAllMocks();
152
+ });
153
+
154
+ afterEach(() => {
155
+ vi.resetAllMocks();
156
+ });
157
+ ```
158
+
159
+ ## Export Verification
160
+
161
+ When adding exports to packages, update testkit:
162
+
163
+ ```typescript
164
+ // packages/testkit/src/mocks/mockJaypie.ts
165
+ export function mockJaypie(vi) {
166
+ return {
167
+ log: mockLog(vi),
168
+ getSecret: vi.fn().mockResolvedValue("mock"),
169
+ // Add new exports here
170
+ newFunction: vi.fn(),
171
+ };
172
+ }
173
+ ```
174
+