@jaypie/mcp 0.3.1 → 0.3.4
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.
- package/dist/aws-B3dW_-bD.js +1202 -0
- package/dist/aws-B3dW_-bD.js.map +1 -0
- package/dist/index.js +357 -1200
- package/dist/index.js.map +1 -1
- package/dist/suite.d.ts +1 -0
- package/dist/suite.js +1252 -0
- package/dist/suite.js.map +1 -0
- package/package.json +11 -2
- package/prompts/Jaypie_Fabric_MCP.md +22 -2
- package/prompts/Jaypie_Fabric_Package.md +86 -0
- package/prompts/Jaypie_MCP_Package.md +34 -2
- package/release-notes/constructs/1.2.17.md +11 -0
- package/release-notes/fabric/0.1.1.md +17 -0
- package/release-notes/fabric/0.1.2.md +11 -0
- package/release-notes/mcp/0.3.2.md +14 -0
- package/release-notes/mcp/0.3.3.md +12 -0
- package/release-notes/mcp/0.3.4.md +36 -0
- package/skills/agents.md +25 -0
- package/skills/aws.md +107 -0
- package/skills/cdk.md +141 -0
- package/skills/cicd.md +152 -0
- package/skills/datadog.md +129 -0
- package/skills/debugging.md +148 -0
- package/skills/dns.md +134 -0
- package/skills/dynamodb.md +140 -0
- package/skills/errors.md +142 -0
- package/skills/fabric.md +164 -0
- package/skills/index.md +7 -0
- package/skills/jaypie.md +100 -0
- package/skills/legacy.md +97 -0
- package/skills/logs.md +160 -0
- package/skills/mocks.md +174 -0
- package/skills/models.md +195 -0
- package/skills/releasenotes.md +94 -0
- package/skills/secrets.md +155 -0
- package/skills/services.md +175 -0
- package/skills/style.md +190 -0
- package/skills/tests.md +209 -0
- package/skills/tools.md +127 -0
- package/skills/topics.md +116 -0
- package/skills/variables.md +146 -0
- package/skills/writing.md +153 -0
package/skills/legacy.md
ADDED
|
@@ -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
|
+
|
package/skills/mocks.md
ADDED
|
@@ -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
|
+
|
package/skills/models.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Data models and type definitions
|
|
3
|
+
related: fabric, dynamodb, services
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Data Models
|
|
7
|
+
|
|
8
|
+
Patterns for defining data models and types in Jaypie applications.
|
|
9
|
+
|
|
10
|
+
## TypeScript Interfaces
|
|
11
|
+
|
|
12
|
+
### Basic Model
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
export interface User {
|
|
16
|
+
id: string;
|
|
17
|
+
email: string;
|
|
18
|
+
name: string;
|
|
19
|
+
role: "user" | "admin";
|
|
20
|
+
createdAt: string;
|
|
21
|
+
updatedAt: string;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Input/Output Types
|
|
26
|
+
|
|
27
|
+
Separate types for different operations:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Create input - required fields only
|
|
31
|
+
export interface UserCreateInput {
|
|
32
|
+
email: string;
|
|
33
|
+
name: string;
|
|
34
|
+
role?: "user" | "admin";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Update input - all optional
|
|
38
|
+
export interface UserUpdateInput {
|
|
39
|
+
name?: string;
|
|
40
|
+
role?: "user" | "admin";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Response type - full model
|
|
44
|
+
export interface UserResponse extends User {
|
|
45
|
+
// Additional computed fields
|
|
46
|
+
displayName: string;
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Fabric Service Models
|
|
51
|
+
|
|
52
|
+
Define input schemas inline with fabric services:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { fabricService } from "@jaypie/fabric";
|
|
56
|
+
|
|
57
|
+
const createUser = fabricService({
|
|
58
|
+
alias: "user_create",
|
|
59
|
+
description: "Create a new user",
|
|
60
|
+
input: {
|
|
61
|
+
email: {
|
|
62
|
+
type: String,
|
|
63
|
+
required: true,
|
|
64
|
+
description: "User email address",
|
|
65
|
+
},
|
|
66
|
+
name: {
|
|
67
|
+
type: String,
|
|
68
|
+
required: true,
|
|
69
|
+
description: "User display name",
|
|
70
|
+
},
|
|
71
|
+
role: {
|
|
72
|
+
type: ["user", "admin"] as const,
|
|
73
|
+
required: false,
|
|
74
|
+
description: "User role (defaults to user)",
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
service: async ({ email, name, role }) => {
|
|
78
|
+
// Input is validated and typed
|
|
79
|
+
return createUserInDatabase({ email, name, role: role || "user" });
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Validation Patterns
|
|
85
|
+
|
|
86
|
+
### Zod Schemas
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { z } from "zod";
|
|
90
|
+
|
|
91
|
+
export const userSchema = z.object({
|
|
92
|
+
email: z.string().email(),
|
|
93
|
+
name: z.string().min(1).max(100),
|
|
94
|
+
role: z.enum(["user", "admin"]).default("user"),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export type User = z.infer<typeof userSchema>;
|
|
98
|
+
|
|
99
|
+
// Validate input
|
|
100
|
+
const validated = userSchema.parse(input);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Custom Validators
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const emailValidator = (email: string): boolean => {
|
|
107
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const service = fabricService({
|
|
111
|
+
alias: "user_create",
|
|
112
|
+
input: {
|
|
113
|
+
email: { type: String, required: true },
|
|
114
|
+
},
|
|
115
|
+
service: async ({ email }) => {
|
|
116
|
+
if (!emailValidator(email)) {
|
|
117
|
+
throw new BadRequestError("Invalid email format");
|
|
118
|
+
}
|
|
119
|
+
// ...
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## DynamoDB Models
|
|
125
|
+
|
|
126
|
+
See `skill("dynamodb")` for DynamoDB-specific patterns.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Single-table design types
|
|
130
|
+
export interface DynamoItem {
|
|
131
|
+
pk: string; // Partition key
|
|
132
|
+
sk: string; // Sort key
|
|
133
|
+
type: string;
|
|
134
|
+
data: Record<string, unknown>;
|
|
135
|
+
createdAt: string;
|
|
136
|
+
updatedAt: string;
|
|
137
|
+
ttl?: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface UserItem extends DynamoItem {
|
|
141
|
+
type: "USER";
|
|
142
|
+
data: {
|
|
143
|
+
email: string;
|
|
144
|
+
name: string;
|
|
145
|
+
role: "user" | "admin";
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## API Response Models
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Standard response wrapper
|
|
154
|
+
export interface ApiResponse<T> {
|
|
155
|
+
success: boolean;
|
|
156
|
+
data?: T;
|
|
157
|
+
error?: {
|
|
158
|
+
code: string;
|
|
159
|
+
message: string;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Paginated response
|
|
164
|
+
export interface PaginatedResponse<T> {
|
|
165
|
+
items: T[];
|
|
166
|
+
nextToken?: string;
|
|
167
|
+
total?: number;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Best Practices
|
|
172
|
+
|
|
173
|
+
1. **Export types** - Make types available for consumers
|
|
174
|
+
2. **Separate concerns** - Input, output, and storage types differ
|
|
175
|
+
3. **Use const assertions** - `as const` for literal types
|
|
176
|
+
4. **Document fields** - Add JSDoc comments for complex types
|
|
177
|
+
5. **Prefer interfaces** - Use `interface` over `type` for objects
|
|
178
|
+
|
|
179
|
+
## Type Documentation
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
/**
|
|
183
|
+
* Represents a user in the system.
|
|
184
|
+
* @property id - Unique identifier (UUID)
|
|
185
|
+
* @property email - Validated email address
|
|
186
|
+
* @property role - Access level for permissions
|
|
187
|
+
*/
|
|
188
|
+
export interface User {
|
|
189
|
+
id: string;
|
|
190
|
+
email: string;
|
|
191
|
+
name: string;
|
|
192
|
+
role: "user" | "admin";
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Version history and release notes
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Release Notes
|
|
6
|
+
|
|
7
|
+
How to access and write release notes for Jaypie packages.
|
|
8
|
+
|
|
9
|
+
## MCP Tools
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
mcp__jaypie__list_release_notes()
|
|
13
|
+
mcp__jaypie__list_release_notes(package: "mcp")
|
|
14
|
+
mcp__jaypie__list_release_notes(package: "jaypie", since_version: "1.0.0")
|
|
15
|
+
mcp__jaypie__read_release_note(package: "mcp", version: "0.3.4")
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Directory Structure
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
packages/mcp/release-notes/
|
|
22
|
+
├── jaypie/
|
|
23
|
+
│ └── 1.2.3.md
|
|
24
|
+
├── mcp/
|
|
25
|
+
│ └── 0.3.4.md
|
|
26
|
+
└── testkit/
|
|
27
|
+
└── 2.0.0.md
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## File Format
|
|
31
|
+
|
|
32
|
+
Create `release-notes/<package>/<version>.md`:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
---
|
|
36
|
+
version: 0.3.4
|
|
37
|
+
date: 2025-01-20
|
|
38
|
+
summary: Brief one-line summary for listing
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Changes
|
|
42
|
+
|
|
43
|
+
### New Features
|
|
44
|
+
|
|
45
|
+
- Feature description
|
|
46
|
+
|
|
47
|
+
### Bug Fixes
|
|
48
|
+
|
|
49
|
+
- Fix description
|
|
50
|
+
|
|
51
|
+
### Breaking Changes
|
|
52
|
+
|
|
53
|
+
- Breaking change description
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## When to Add
|
|
57
|
+
|
|
58
|
+
Add release notes when:
|
|
59
|
+
- Bumping package version (required)
|
|
60
|
+
- Merging significant features
|
|
61
|
+
- Making breaking changes
|
|
62
|
+
- Fixing notable bugs
|
|
63
|
+
|
|
64
|
+
## Writing Guidelines
|
|
65
|
+
|
|
66
|
+
1. **Summary** - One line, present tense, describes the release
|
|
67
|
+
2. **Changes** - Group by type: New Features, Bug Fixes, Breaking Changes
|
|
68
|
+
3. **Bullets** - Start with verb (Add, Fix, Update, Remove)
|
|
69
|
+
4. **Links** - Reference issues/PRs when relevant
|
|
70
|
+
|
|
71
|
+
## Example
|
|
72
|
+
|
|
73
|
+
```markdown
|
|
74
|
+
---
|
|
75
|
+
version: 1.2.0
|
|
76
|
+
date: 2025-01-15
|
|
77
|
+
summary: Add streaming support for LLM providers
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Changes
|
|
81
|
+
|
|
82
|
+
### New Features
|
|
83
|
+
|
|
84
|
+
- Add streaming response support for Anthropic and OpenAI
|
|
85
|
+
- Add `onChunk` callback for real-time token processing
|
|
86
|
+
|
|
87
|
+
### Bug Fixes
|
|
88
|
+
|
|
89
|
+
- Fix timeout handling in concurrent requests
|
|
90
|
+
|
|
91
|
+
### Breaking Changes
|
|
92
|
+
|
|
93
|
+
- Remove deprecated `legacyMode` option
|
|
94
|
+
```
|