@jaypie/mcp 0.4.1 → 0.6.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.
- package/README.md +3 -2
- package/dist/createMcpServer.js +34 -0
- package/dist/createMcpServer.js.map +1 -0
- package/dist/index.js +3 -92
- package/dist/index.js.map +1 -1
- package/dist/mcpExpressHandler.js +56 -0
- package/dist/mcpExpressHandler.js.map +1 -0
- package/dist/suite.d.ts +12 -0
- package/dist/suite.js +23 -2426
- package/dist/suite.js.map +1 -1
- package/dist/suites/aws/aws.js +328 -0
- package/dist/suites/aws/aws.js.map +1 -0
- package/dist/suites/aws/help.md +42 -0
- package/dist/suites/aws/index.d.ts +102 -0
- package/dist/suites/aws/index.js +258 -0
- package/dist/suites/aws/index.js.map +1 -0
- package/dist/suites/datadog/datadog.js +828 -0
- package/dist/suites/datadog/datadog.js.map +1 -0
- package/dist/suites/datadog/help.md +39 -0
- package/dist/suites/datadog/index.d.ts +24 -0
- package/dist/suites/datadog/index.js +156 -0
- package/dist/suites/datadog/index.js.map +1 -0
- package/dist/suites/docs/index.d.ts +14 -0
- package/dist/suites/docs/index.js +246 -0
- package/dist/suites/docs/index.js.map +1 -0
- package/dist/suites/docs/release-notes/help.md +37 -0
- package/dist/suites/llm/help.md +39 -0
- package/dist/suites/llm/index.d.ts +11 -0
- package/dist/suites/llm/index.js +61 -0
- package/dist/suites/llm/index.js.map +1 -0
- package/dist/{llm.d.ts → suites/llm/llm.d.ts} +0 -11
- package/dist/suites/llm/llm.js +61 -0
- package/dist/suites/llm/llm.js.map +1 -0
- package/package.json +4 -3
- package/release-notes/aws/1.2.5.md +18 -0
- package/release-notes/constructs/1.2.19.md +35 -0
- package/release-notes/dynamodb/0.4.0.md +44 -0
- package/release-notes/express/1.2.5.md +33 -0
- package/release-notes/fabric/0.2.0.md +77 -0
- package/release-notes/fabric/0.2.1.md +36 -0
- package/release-notes/jaypie/1.2.4.md +11 -0
- package/release-notes/jaypie/1.2.5.md +9 -0
- package/release-notes/lambda/1.2.4.md +39 -0
- package/release-notes/llm/1.2.7.md +12 -0
- package/release-notes/mcp/0.5.0.md +70 -0
- package/release-notes/mcp/0.5.1.md +23 -0
- package/release-notes/mcp/0.6.0.md +19 -0
- package/release-notes/testkit/1.2.17.md +30 -0
- package/release-notes/testkit/1.2.18.md +16 -0
- package/skills/agents.md +2 -2
- package/skills/cdk.md +5 -1
- package/skills/contents.md +24 -0
- package/skills/development.md +19 -0
- package/skills/documentation.md +19 -145
- package/skills/express.md +158 -0
- package/skills/fabric.md +7 -4
- package/skills/handlers.md +172 -0
- package/skills/infrastructure.md +22 -0
- package/skills/lambda.md +164 -0
- package/skills/llm.md +4 -1
- package/skills/meta.md +17 -0
- package/skills/patterns.md +19 -0
- package/skills/skills.md +11 -12
- package/skills/streaming.md +120 -0
- package/skills/style.md +1 -24
- package/skills/tools-aws.md +65 -47
- package/skills/tools-datadog.md +53 -44
- package/skills/tools-dynamodb.md +72 -44
- package/skills/tools.md +55 -42
- package/skills/vocabulary.md +143 -8
- package/skills/websockets.md +203 -0
- /package/dist/{aws.d.ts → suites/aws/aws.d.ts} +0 -0
- /package/dist/{datadog.d.ts → suites/datadog/datadog.d.ts} +0 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { fabricService } from '@jaypie/fabric';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import matter from 'gray-matter';
|
|
6
|
+
import { gt } from 'semver';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Docs Suite - Documentation services (skill, version, release_notes)
|
|
10
|
+
*/
|
|
11
|
+
const BUILD_VERSION_STRING = "@jaypie/mcp@0.6.0#d4227f02"
|
|
12
|
+
;
|
|
13
|
+
const __filename$1 = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname$1 = path.dirname(__filename$1);
|
|
15
|
+
// From dist/suites/docs/, go up 3 levels to package root where skills/ and release-notes/ live
|
|
16
|
+
const RELEASE_NOTES_PATH = path.join(__dirname$1, "..", "..", "..", "release-notes");
|
|
17
|
+
const SKILLS_PATH = path.join(__dirname$1, "..", "..", "..", "skills");
|
|
18
|
+
function isValidSkillAlias(alias) {
|
|
19
|
+
const normalized = alias.toLowerCase().trim();
|
|
20
|
+
if (normalized.includes("/") ||
|
|
21
|
+
normalized.includes("\\") ||
|
|
22
|
+
normalized.includes("..")) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return /^[a-z0-9_-]+$/.test(normalized);
|
|
26
|
+
}
|
|
27
|
+
async function parseReleaseNoteFile(filePath) {
|
|
28
|
+
try {
|
|
29
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
30
|
+
const filename = path.basename(filePath, ".md");
|
|
31
|
+
if (content.startsWith("---")) {
|
|
32
|
+
const parsed = matter(content);
|
|
33
|
+
const frontMatter = parsed.data;
|
|
34
|
+
return {
|
|
35
|
+
date: frontMatter.date,
|
|
36
|
+
filename,
|
|
37
|
+
summary: frontMatter.summary,
|
|
38
|
+
version: frontMatter.version || filename,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return { filename, version: filename };
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return { filename: path.basename(filePath, ".md") };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function formatReleaseNoteListItem(note) {
|
|
48
|
+
const { date, packageName, summary, version } = note;
|
|
49
|
+
const parts = [`* ${packageName}@${version}`];
|
|
50
|
+
if (date) {
|
|
51
|
+
parts.push(`(${date})`);
|
|
52
|
+
}
|
|
53
|
+
if (summary) {
|
|
54
|
+
parts.push(`- ${summary}`);
|
|
55
|
+
}
|
|
56
|
+
return parts.join(" ");
|
|
57
|
+
}
|
|
58
|
+
async function parseSkillFile(filePath) {
|
|
59
|
+
try {
|
|
60
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
61
|
+
const alias = path.basename(filePath, ".md");
|
|
62
|
+
if (content.startsWith("---")) {
|
|
63
|
+
const parsed = matter(content);
|
|
64
|
+
const frontMatter = parsed.data;
|
|
65
|
+
return {
|
|
66
|
+
alias,
|
|
67
|
+
description: frontMatter.description,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return { alias };
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return { alias: path.basename(filePath, ".md") };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function formatSkillListItem(skill) {
|
|
77
|
+
const { alias, description } = skill;
|
|
78
|
+
if (description) {
|
|
79
|
+
return `* ${alias} - ${description}`;
|
|
80
|
+
}
|
|
81
|
+
return `* ${alias}`;
|
|
82
|
+
}
|
|
83
|
+
async function getPackageReleaseNotes(packageName) {
|
|
84
|
+
const packageDir = path.join(RELEASE_NOTES_PATH, packageName);
|
|
85
|
+
try {
|
|
86
|
+
const files = await fs.readdir(packageDir);
|
|
87
|
+
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
88
|
+
const notes = await Promise.all(mdFiles.map(async (file) => {
|
|
89
|
+
const parsed = await parseReleaseNoteFile(path.join(packageDir, file));
|
|
90
|
+
return { ...parsed, packageName };
|
|
91
|
+
}));
|
|
92
|
+
return notes.sort((a, b) => {
|
|
93
|
+
if (!a.version || !b.version)
|
|
94
|
+
return 0;
|
|
95
|
+
try {
|
|
96
|
+
return gt(a.version, b.version) ? -1 : 1;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return b.version.localeCompare(a.version);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function filterReleaseNotesSince(notes, sinceVersion) {
|
|
108
|
+
return notes.filter((note) => {
|
|
109
|
+
if (!note.version)
|
|
110
|
+
return false;
|
|
111
|
+
try {
|
|
112
|
+
return gt(note.version, sinceVersion);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// =============================================================================
|
|
120
|
+
// SKILL SERVICE
|
|
121
|
+
// =============================================================================
|
|
122
|
+
const skillService = fabricService({
|
|
123
|
+
alias: "skill",
|
|
124
|
+
description: "Access Jaypie development documentation. Pass a skill alias (e.g., 'aws', 'tests', 'errors') to get that documentation. Pass 'index' or no argument to list all available skills.",
|
|
125
|
+
input: {
|
|
126
|
+
alias: {
|
|
127
|
+
description: "Skill alias (e.g., 'aws', 'tests'). Omit or use 'index' to list all skills.",
|
|
128
|
+
required: false,
|
|
129
|
+
type: String,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
service: async ({ alias: inputAlias }) => {
|
|
133
|
+
const alias = (inputAlias || "index").toLowerCase().trim();
|
|
134
|
+
if (!isValidSkillAlias(alias)) {
|
|
135
|
+
throw new Error(`Invalid skill alias "${alias}". Use alphanumeric characters, hyphens, and underscores only.`);
|
|
136
|
+
}
|
|
137
|
+
if (alias === "index") {
|
|
138
|
+
const indexPath = path.join(SKILLS_PATH, "index.md");
|
|
139
|
+
let indexContent = "";
|
|
140
|
+
try {
|
|
141
|
+
indexContent = await fs.readFile(indexPath, "utf-8");
|
|
142
|
+
if (indexContent.startsWith("---")) {
|
|
143
|
+
const parsed = matter(indexContent);
|
|
144
|
+
indexContent = parsed.content.trim();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Index file doesn't exist, will just show skill list
|
|
149
|
+
}
|
|
150
|
+
const files = await fs.readdir(SKILLS_PATH);
|
|
151
|
+
const mdFiles = files.filter((file) => file.endsWith(".md") && file !== "index.md");
|
|
152
|
+
const skills = await Promise.all(mdFiles.map((file) => parseSkillFile(path.join(SKILLS_PATH, file))));
|
|
153
|
+
skills.sort((a, b) => a.alias.localeCompare(b.alias));
|
|
154
|
+
const skillList = skills.map(formatSkillListItem).join("\n");
|
|
155
|
+
if (indexContent) {
|
|
156
|
+
return `${indexContent}\n\n## Available Skills\n\n${skillList}`;
|
|
157
|
+
}
|
|
158
|
+
return `# Jaypie Skills\n\n## Available Skills\n\n${skillList}`;
|
|
159
|
+
}
|
|
160
|
+
const skillPath = path.join(SKILLS_PATH, `${alias}.md`);
|
|
161
|
+
try {
|
|
162
|
+
return await fs.readFile(skillPath, "utf-8");
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
throw new Error(`Skill "${alias}" not found. Use skill("index") to list available skills.`);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
// =============================================================================
|
|
170
|
+
// VERSION SERVICE
|
|
171
|
+
// =============================================================================
|
|
172
|
+
const versionService = fabricService({
|
|
173
|
+
alias: "version",
|
|
174
|
+
description: `Prints the current version and hash, \`${BUILD_VERSION_STRING}\``,
|
|
175
|
+
input: {},
|
|
176
|
+
service: async () => BUILD_VERSION_STRING,
|
|
177
|
+
});
|
|
178
|
+
// =============================================================================
|
|
179
|
+
// RELEASE NOTES SERVICE
|
|
180
|
+
// =============================================================================
|
|
181
|
+
async function getReleaseNotesHelp() {
|
|
182
|
+
return fs.readFile(path.join(__dirname$1, "release-notes", "help.md"), "utf-8");
|
|
183
|
+
}
|
|
184
|
+
const releaseNotesService = fabricService({
|
|
185
|
+
alias: "release_notes",
|
|
186
|
+
description: "Browse Jaypie package release notes. Commands: list, read. Call with no args for help.",
|
|
187
|
+
input: {
|
|
188
|
+
command: {
|
|
189
|
+
description: "Command to execute (omit for help)",
|
|
190
|
+
required: false,
|
|
191
|
+
type: String,
|
|
192
|
+
},
|
|
193
|
+
input: {
|
|
194
|
+
description: "Command parameters",
|
|
195
|
+
required: false,
|
|
196
|
+
type: Object,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
service: async ({ command, input: params, }) => {
|
|
200
|
+
if (!command || command === "help") {
|
|
201
|
+
return getReleaseNotesHelp();
|
|
202
|
+
}
|
|
203
|
+
const p = params || {};
|
|
204
|
+
switch (command) {
|
|
205
|
+
case "list": {
|
|
206
|
+
const entries = await fs.readdir(RELEASE_NOTES_PATH, {
|
|
207
|
+
withFileTypes: true,
|
|
208
|
+
});
|
|
209
|
+
const packageDirs = entries
|
|
210
|
+
.filter((entry) => entry.isDirectory())
|
|
211
|
+
.map((entry) => entry.name);
|
|
212
|
+
const packagesToList = p.package
|
|
213
|
+
? packageDirs.filter((pkg) => pkg === p.package)
|
|
214
|
+
: packageDirs;
|
|
215
|
+
if (packagesToList.length === 0 && p.package) {
|
|
216
|
+
return `No release notes found for package "${p.package}".`;
|
|
217
|
+
}
|
|
218
|
+
const allNotes = await Promise.all(packagesToList.map((pkg) => getPackageReleaseNotes(pkg)));
|
|
219
|
+
let flatNotes = allNotes.flat();
|
|
220
|
+
if (p.since_version) {
|
|
221
|
+
flatNotes = filterReleaseNotesSince(flatNotes, p.since_version);
|
|
222
|
+
}
|
|
223
|
+
if (flatNotes.length === 0) {
|
|
224
|
+
const filterDesc = p.since_version
|
|
225
|
+
? ` newer than ${p.since_version}`
|
|
226
|
+
: "";
|
|
227
|
+
return `No release notes found${filterDesc}.`;
|
|
228
|
+
}
|
|
229
|
+
return flatNotes.map(formatReleaseNoteListItem).join("\n");
|
|
230
|
+
}
|
|
231
|
+
case "read": {
|
|
232
|
+
if (!p.package)
|
|
233
|
+
throw new Error("package is required");
|
|
234
|
+
if (!p.version)
|
|
235
|
+
throw new Error("version is required");
|
|
236
|
+
const filePath = path.join(RELEASE_NOTES_PATH, p.package, `${p.version}.md`);
|
|
237
|
+
return fs.readFile(filePath, "utf-8");
|
|
238
|
+
}
|
|
239
|
+
default:
|
|
240
|
+
throw new Error(`Unknown command: ${command}. Use release_notes() for help.`);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
export { releaseNotesService, skillService, versionService };
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/suites/docs/index.ts"],"sourcesContent":["/**\n * Docs Suite - Documentation services (skill, version, release_notes)\n */\nimport { fabricService } from \"@jaypie/fabric\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport matter from \"gray-matter\";\nimport { gt } from \"semver\";\n\n// Build-time constants\ndeclare const __BUILD_VERSION_STRING__: string;\nconst BUILD_VERSION_STRING =\n typeof __BUILD_VERSION_STRING__ !== \"undefined\"\n ? __BUILD_VERSION_STRING__\n : \"@jaypie/mcp@0.0.0\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n// From dist/suites/docs/, go up 3 levels to package root where skills/ and release-notes/ live\nconst RELEASE_NOTES_PATH = path.join(\n __dirname,\n \"..\",\n \"..\",\n \"..\",\n \"release-notes\",\n);\nconst SKILLS_PATH = path.join(__dirname, \"..\", \"..\", \"..\", \"skills\");\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\ninterface ReleaseNoteFrontMatter {\n date?: string;\n summary?: string;\n version?: string;\n}\n\ninterface SkillFrontMatter {\n description?: string;\n}\n\nfunction isValidSkillAlias(alias: string): boolean {\n const normalized = alias.toLowerCase().trim();\n if (\n normalized.includes(\"/\") ||\n normalized.includes(\"\\\\\") ||\n normalized.includes(\"..\")\n ) {\n return false;\n }\n return /^[a-z0-9_-]+$/.test(normalized);\n}\n\nasync function parseReleaseNoteFile(filePath: string): Promise<{\n date?: string;\n filename: string;\n summary?: string;\n version?: string;\n}> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n const filename = path.basename(filePath, \".md\");\n\n if (content.startsWith(\"---\")) {\n const parsed = matter(content);\n const frontMatter = parsed.data as ReleaseNoteFrontMatter;\n return {\n date: frontMatter.date,\n filename,\n summary: frontMatter.summary,\n version: frontMatter.version || filename,\n };\n }\n\n return { filename, version: filename };\n } catch {\n return { filename: path.basename(filePath, \".md\") };\n }\n}\n\nfunction formatReleaseNoteListItem(note: {\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n}): string {\n const { date, packageName, summary, version } = note;\n const parts = [`* ${packageName}@${version}`];\n\n if (date) {\n parts.push(`(${date})`);\n }\n\n if (summary) {\n parts.push(`- ${summary}`);\n }\n\n return parts.join(\" \");\n}\n\nasync function parseSkillFile(filePath: string): Promise<{\n alias: string;\n description?: string;\n}> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n const alias = path.basename(filePath, \".md\");\n\n if (content.startsWith(\"---\")) {\n const parsed = matter(content);\n const frontMatter = parsed.data as SkillFrontMatter;\n return {\n alias,\n description: frontMatter.description,\n };\n }\n\n return { alias };\n } catch {\n return { alias: path.basename(filePath, \".md\") };\n }\n}\n\nfunction formatSkillListItem(skill: {\n alias: string;\n description?: string;\n}): string {\n const { alias, description } = skill;\n if (description) {\n return `* ${alias} - ${description}`;\n }\n return `* ${alias}`;\n}\n\nasync function getPackageReleaseNotes(packageName: string): Promise<\n Array<{\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n }>\n> {\n const packageDir = path.join(RELEASE_NOTES_PATH, packageName);\n try {\n const files = await fs.readdir(packageDir);\n const mdFiles = files.filter((file) => file.endsWith(\".md\"));\n\n const notes = await Promise.all(\n mdFiles.map(async (file) => {\n const parsed = await parseReleaseNoteFile(path.join(packageDir, file));\n return { ...parsed, packageName };\n }),\n );\n\n return notes.sort((a, b) => {\n if (!a.version || !b.version) return 0;\n try {\n return gt(a.version, b.version) ? -1 : 1;\n } catch {\n return b.version.localeCompare(a.version);\n }\n });\n } catch {\n return [];\n }\n}\n\nfunction filterReleaseNotesSince(\n notes: Array<{\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n }>,\n sinceVersion: string,\n): Array<{\n date?: string;\n filename: string;\n packageName: string;\n summary?: string;\n version?: string;\n}> {\n return notes.filter((note) => {\n if (!note.version) return false;\n try {\n return gt(note.version, sinceVersion);\n } catch {\n return false;\n }\n });\n}\n\n// =============================================================================\n// SKILL SERVICE\n// =============================================================================\n\nexport const skillService = fabricService({\n alias: \"skill\",\n description:\n \"Access Jaypie development documentation. Pass a skill alias (e.g., 'aws', 'tests', 'errors') to get that documentation. Pass 'index' or no argument to list all available skills.\",\n input: {\n alias: {\n description:\n \"Skill alias (e.g., 'aws', 'tests'). Omit or use 'index' to list all skills.\",\n required: false,\n type: String,\n },\n },\n service: async ({ alias: inputAlias }: { alias?: string }) => {\n const alias = (inputAlias || \"index\").toLowerCase().trim();\n\n if (!isValidSkillAlias(alias)) {\n throw new Error(\n `Invalid skill alias \"${alias}\". Use alphanumeric characters, hyphens, and underscores only.`,\n );\n }\n\n if (alias === \"index\") {\n const indexPath = path.join(SKILLS_PATH, \"index.md\");\n let indexContent = \"\";\n\n try {\n indexContent = await fs.readFile(indexPath, \"utf-8\");\n if (indexContent.startsWith(\"---\")) {\n const parsed = matter(indexContent);\n indexContent = parsed.content.trim();\n }\n } catch {\n // Index file doesn't exist, will just show skill list\n }\n\n const files = await fs.readdir(SKILLS_PATH);\n const mdFiles = files.filter(\n (file) => file.endsWith(\".md\") && file !== \"index.md\",\n );\n\n const skills = await Promise.all(\n mdFiles.map((file) => parseSkillFile(path.join(SKILLS_PATH, file))),\n );\n\n skills.sort((a, b) => a.alias.localeCompare(b.alias));\n\n const skillList = skills.map(formatSkillListItem).join(\"\\n\");\n\n if (indexContent) {\n return `${indexContent}\\n\\n## Available Skills\\n\\n${skillList}`;\n }\n return `# Jaypie Skills\\n\\n## Available Skills\\n\\n${skillList}`;\n }\n\n const skillPath = path.join(SKILLS_PATH, `${alias}.md`);\n try {\n return await fs.readFile(skillPath, \"utf-8\");\n } catch {\n throw new Error(\n `Skill \"${alias}\" not found. Use skill(\"index\") to list available skills.`,\n );\n }\n },\n});\n\n// =============================================================================\n// VERSION SERVICE\n// =============================================================================\n\nexport const versionService = fabricService({\n alias: \"version\",\n description: `Prints the current version and hash, \\`${BUILD_VERSION_STRING}\\``,\n input: {},\n service: async () => BUILD_VERSION_STRING,\n});\n\n// =============================================================================\n// RELEASE NOTES SERVICE\n// =============================================================================\n\nasync function getReleaseNotesHelp(): Promise<string> {\n return fs.readFile(path.join(__dirname, \"release-notes\", \"help.md\"), \"utf-8\");\n}\n\ninterface ReleaseNotesInput {\n package?: string;\n since_version?: string;\n version?: string;\n}\n\nexport const releaseNotesService = fabricService({\n alias: \"release_notes\",\n description:\n \"Browse Jaypie package release notes. Commands: list, read. Call with no args for help.\",\n input: {\n command: {\n description: \"Command to execute (omit for help)\",\n required: false,\n type: String,\n },\n input: {\n description: \"Command parameters\",\n required: false,\n type: Object,\n },\n },\n service: async ({\n command,\n input: params,\n }: {\n command?: string;\n input?: ReleaseNotesInput;\n }) => {\n if (!command || command === \"help\") {\n return getReleaseNotesHelp();\n }\n\n const p = params || {};\n\n switch (command) {\n case \"list\": {\n const entries = await fs.readdir(RELEASE_NOTES_PATH, {\n withFileTypes: true,\n });\n const packageDirs = entries\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n const packagesToList = p.package\n ? packageDirs.filter((pkg) => pkg === p.package)\n : packageDirs;\n\n if (packagesToList.length === 0 && p.package) {\n return `No release notes found for package \"${p.package}\".`;\n }\n\n const allNotes = await Promise.all(\n packagesToList.map((pkg) => getPackageReleaseNotes(pkg)),\n );\n let flatNotes = allNotes.flat();\n\n if (p.since_version) {\n flatNotes = filterReleaseNotesSince(flatNotes, p.since_version);\n }\n\n if (flatNotes.length === 0) {\n const filterDesc = p.since_version\n ? ` newer than ${p.since_version}`\n : \"\";\n return `No release notes found${filterDesc}.`;\n }\n\n return flatNotes.map(formatReleaseNoteListItem).join(\"\\n\");\n }\n\n case \"read\": {\n if (!p.package) throw new Error(\"package is required\");\n if (!p.version) throw new Error(\"version is required\");\n const filePath = path.join(\n RELEASE_NOTES_PATH,\n p.package,\n `${p.version}.md`,\n );\n return fs.readFile(filePath, \"utf-8\");\n }\n\n default:\n throw new Error(\n `Unknown command: ${command}. Use release_notes() for help.`,\n );\n }\n },\n});\n"],"names":["__filename","__dirname"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Release Notes
|
|
2
|
+
|
|
3
|
+
Browse Jaypie package release notes.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description | Required Parameters |
|
|
8
|
+
|---------|-------------|---------------------|
|
|
9
|
+
| `list` | List available release notes | - |
|
|
10
|
+
| `read` | Read a specific release note | `package`, `version` |
|
|
11
|
+
|
|
12
|
+
## Options for `list`
|
|
13
|
+
|
|
14
|
+
| Option | Description |
|
|
15
|
+
|--------|-------------|
|
|
16
|
+
| `package` | Filter by package name (e.g., "mcp", "jaypie") |
|
|
17
|
+
| `since_version` | Only versions newer than this (e.g., "1.0.0") |
|
|
18
|
+
|
|
19
|
+
## Examples
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
release_notes("list")
|
|
23
|
+
release_notes("list", { package: "mcp" })
|
|
24
|
+
release_notes("list", { package: "jaypie", since_version: "2.0.0" })
|
|
25
|
+
release_notes("read", { package: "mcp", version: "0.4.2" })
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Available Packages
|
|
29
|
+
|
|
30
|
+
Release notes are available for all Jaypie packages including:
|
|
31
|
+
- `jaypie` - Main package
|
|
32
|
+
- `mcp` - MCP server
|
|
33
|
+
- `fabric` - Service handlers and adapters
|
|
34
|
+
- `llm` - LLM provider interface
|
|
35
|
+
- And more...
|
|
36
|
+
|
|
37
|
+
Use `release_notes("list")` to see all available packages and versions.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# LLM Tools
|
|
2
|
+
|
|
3
|
+
Debug and inspect LLM provider responses. Useful for understanding how providers format responses.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description | Required Parameters |
|
|
8
|
+
|---------|-------------|---------------------|
|
|
9
|
+
| `debug_call` | Make a debug call and inspect response | `provider`, `message` |
|
|
10
|
+
|
|
11
|
+
## Providers
|
|
12
|
+
|
|
13
|
+
Supported providers: `openai`, `anthropic`, `gemini`, `openrouter`
|
|
14
|
+
|
|
15
|
+
## Environment Variables
|
|
16
|
+
|
|
17
|
+
| Variable | Description |
|
|
18
|
+
|----------|-------------|
|
|
19
|
+
| `OPENAI_API_KEY` | OpenAI API key |
|
|
20
|
+
| `ANTHROPIC_API_KEY` | Anthropic API key |
|
|
21
|
+
| `GOOGLE_API_KEY` | Google/Gemini API key |
|
|
22
|
+
| `OPENROUTER_API_KEY` | OpenRouter API key |
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
llm("debug_call", { provider: "openai", message: "Hello, world!" })
|
|
28
|
+
llm("debug_call", { provider: "openai", model: "o3-mini", message: "What is 15 * 17? Think step by step." })
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Response Fields
|
|
32
|
+
|
|
33
|
+
The `debug_call` command returns:
|
|
34
|
+
- `content` - The response text
|
|
35
|
+
- `reasoning` - Extracted reasoning/thinking content (if available)
|
|
36
|
+
- `reasoningTokens` - Count of reasoning tokens used
|
|
37
|
+
- `history` - Full conversation history
|
|
38
|
+
- `rawResponses` - Raw API responses
|
|
39
|
+
- `usage` - Token usage statistics
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type LlmProvider } from "./llm.js";
|
|
2
|
+
interface LlmInput {
|
|
3
|
+
message?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
provider?: LlmProvider;
|
|
6
|
+
}
|
|
7
|
+
export declare const llmService: import("@jaypie/fabric").Service<{
|
|
8
|
+
command?: string;
|
|
9
|
+
input?: LlmInput;
|
|
10
|
+
}, string | import("./llm.js").LlmDebugCallResult, string | import("./llm.js").LlmDebugCallResult>;
|
|
11
|
+
export * from "./llm.js";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { fabricService } from '@jaypie/fabric';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { debugLlmCall } from './llm.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* LLM Suite - Unified LLM debugging and inspection
|
|
9
|
+
*/
|
|
10
|
+
const __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
// Silent logger for direct execution
|
|
12
|
+
const log = {
|
|
13
|
+
error: () => { },
|
|
14
|
+
info: () => { },
|
|
15
|
+
};
|
|
16
|
+
async function getHelp() {
|
|
17
|
+
return fs.readFile(path.join(__dirname$1, "help.md"), "utf-8");
|
|
18
|
+
}
|
|
19
|
+
const llmService = fabricService({
|
|
20
|
+
alias: "llm",
|
|
21
|
+
description: "Debug LLM provider responses. Commands: debug_call. Call with no args for help.",
|
|
22
|
+
input: {
|
|
23
|
+
command: {
|
|
24
|
+
description: "Command to execute (omit for help)",
|
|
25
|
+
required: false,
|
|
26
|
+
type: String,
|
|
27
|
+
},
|
|
28
|
+
input: {
|
|
29
|
+
description: "Command parameters",
|
|
30
|
+
required: false,
|
|
31
|
+
type: Object,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
service: async ({ command, input: params, }) => {
|
|
35
|
+
if (!command || command === "help") {
|
|
36
|
+
return getHelp();
|
|
37
|
+
}
|
|
38
|
+
const p = params || {};
|
|
39
|
+
switch (command) {
|
|
40
|
+
case "debug_call": {
|
|
41
|
+
if (!p.provider)
|
|
42
|
+
throw new Error("provider is required");
|
|
43
|
+
if (!p.message)
|
|
44
|
+
throw new Error("message is required");
|
|
45
|
+
const result = await debugLlmCall({
|
|
46
|
+
message: p.message,
|
|
47
|
+
model: p.model,
|
|
48
|
+
provider: p.provider,
|
|
49
|
+
}, log);
|
|
50
|
+
if (!result.success)
|
|
51
|
+
throw new Error(result.error);
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
default:
|
|
55
|
+
throw new Error(`Unknown command: ${command}. Use llm() for help.`);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export { debugLlmCall, llmService };
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/suites/llm/index.ts"],"sourcesContent":["/**\n * LLM Suite - Unified LLM debugging and inspection\n */\nimport { fabricService } from \"@jaypie/fabric\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { debugLlmCall, type LlmProvider } from \"./llm.js\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n// Silent logger for direct execution\nconst log = {\n error: () => {},\n info: () => {},\n};\n\nasync function getHelp(): Promise<string> {\n return fs.readFile(path.join(__dirname, \"help.md\"), \"utf-8\");\n}\n\n// Input type for the unified LLM service\ninterface LlmInput {\n message?: string;\n model?: string;\n provider?: LlmProvider;\n}\n\nexport const llmService = fabricService({\n alias: \"llm\",\n description:\n \"Debug LLM provider responses. Commands: debug_call. Call with no args for help.\",\n input: {\n command: {\n description: \"Command to execute (omit for help)\",\n required: false,\n type: String,\n },\n input: {\n description: \"Command parameters\",\n required: false,\n type: Object,\n },\n },\n service: async ({\n command,\n input: params,\n }: {\n command?: string;\n input?: LlmInput;\n }) => {\n if (!command || command === \"help\") {\n return getHelp();\n }\n\n const p = params || {};\n\n switch (command) {\n case \"debug_call\": {\n if (!p.provider) throw new Error(\"provider is required\");\n if (!p.message) throw new Error(\"message is required\");\n const result = await debugLlmCall(\n {\n message: p.message,\n model: p.model,\n provider: p.provider,\n },\n log,\n );\n if (!result.success) throw new Error(result.error);\n return result;\n }\n\n default:\n throw new Error(`Unknown command: ${command}. Use llm() for help.`);\n }\n },\n});\n\n// Re-export types and functions for testing\nexport * from \"./llm.js\";\n"],"names":["__dirname"],"mappings":";;;;;;AAAA;;AAEG;AAQH,MAAMA,WAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE9D;AACA,MAAM,GAAG,GAAG;AACV,IAAA,KAAK,EAAE,MAAK,EAAE,CAAC;AACf,IAAA,IAAI,EAAE,MAAK,EAAE,CAAC;CACf;AAED,eAAe,OAAO,GAAA;AACpB,IAAA,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAACA,WAAS,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC;AAC9D;AASO,MAAM,UAAU,GAAG,aAAa,CAAC;AACtC,IAAA,KAAK,EAAE,KAAK;AACZ,IAAA,WAAW,EACT,iFAAiF;AACnF,IAAA,KAAK,EAAE;AACL,QAAA,OAAO,EAAE;AACP,YAAA,WAAW,EAAE,oCAAoC;AACjD,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA,KAAK,EAAE;AACL,YAAA,WAAW,EAAE,oBAAoB;AACjC,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACF,KAAA;IACD,OAAO,EAAE,OAAO,EACd,OAAO,EACP,KAAK,EAAE,MAAM,GAId,KAAI;AACH,QAAA,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,EAAE;YAClC,OAAO,OAAO,EAAE;QAClB;AAEA,QAAA,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE;QAEtB,QAAQ,OAAO;YACb,KAAK,YAAY,EAAE;gBACjB,IAAI,CAAC,CAAC,CAAC,QAAQ;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC;gBACxD,IAAI,CAAC,CAAC,CAAC,OAAO;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC;AACtD,gBAAA,MAAM,MAAM,GAAG,MAAM,YAAY,CAC/B;oBACE,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,EACD,GAAG,CACJ;gBACD,IAAI,CAAC,MAAM,CAAC,OAAO;AAAE,oBAAA,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;AAClD,gBAAA,OAAO,MAAM;YACf;AAEA,YAAA;AACE,gBAAA,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,CAAA,qBAAA,CAAuB,CAAC;;IAEzE,CAAC;AACF,CAAA;;;;"}
|
|
@@ -23,19 +23,8 @@ interface Logger {
|
|
|
23
23
|
info: (message: string, ...args: unknown[]) => void;
|
|
24
24
|
error: (message: string, ...args: unknown[]) => void;
|
|
25
25
|
}
|
|
26
|
-
export declare const REASONING_MODELS: Record<string, string>;
|
|
27
26
|
/**
|
|
28
27
|
* Make a debug LLM call and return the raw response data for inspection
|
|
29
28
|
*/
|
|
30
29
|
export declare function debugLlmCall(params: LlmDebugCallParams, log: Logger): Promise<LlmDebugCallResult>;
|
|
31
|
-
/**
|
|
32
|
-
* List available providers and their default/reasoning models
|
|
33
|
-
*/
|
|
34
|
-
export declare function listLlmProviders(): {
|
|
35
|
-
providers: Array<{
|
|
36
|
-
name: LlmProvider;
|
|
37
|
-
defaultModel: string;
|
|
38
|
-
reasoningModels: string[];
|
|
39
|
-
}>;
|
|
40
|
-
};
|
|
41
30
|
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { LLM, Llm } from '@jaypie/llm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* LLM debugging utilities for inspecting raw provider responses
|
|
5
|
+
*/
|
|
6
|
+
// Default models for each provider
|
|
7
|
+
const DEFAULT_MODELS = {
|
|
8
|
+
anthropic: LLM.PROVIDER.ANTHROPIC.MODEL.SMALL,
|
|
9
|
+
gemini: LLM.PROVIDER.GEMINI.MODEL.SMALL,
|
|
10
|
+
openai: LLM.PROVIDER.OPENAI.MODEL.SMALL,
|
|
11
|
+
openrouter: LLM.PROVIDER.OPENROUTER.MODEL.SMALL,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Make a debug LLM call and return the raw response data for inspection
|
|
15
|
+
*/
|
|
16
|
+
async function debugLlmCall(params, log) {
|
|
17
|
+
const { provider, message } = params;
|
|
18
|
+
const model = params.model || DEFAULT_MODELS[provider];
|
|
19
|
+
log.info(`Making debug LLM call to ${provider} with model ${model}`);
|
|
20
|
+
try {
|
|
21
|
+
const llm = new Llm(provider, { model });
|
|
22
|
+
const result = await llm.operate(message, {
|
|
23
|
+
user: "[jaypie-mcp] Debug LLM Call",
|
|
24
|
+
});
|
|
25
|
+
if (result.error) {
|
|
26
|
+
return {
|
|
27
|
+
success: false,
|
|
28
|
+
provider,
|
|
29
|
+
model,
|
|
30
|
+
error: `${result.error.title}: ${result.error.detail || "Unknown error"}`,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Calculate total reasoning tokens
|
|
34
|
+
const reasoningTokens = result.usage.reduce((sum, u) => sum + (u.reasoning || 0), 0);
|
|
35
|
+
return {
|
|
36
|
+
success: true,
|
|
37
|
+
provider,
|
|
38
|
+
model,
|
|
39
|
+
content: typeof result.content === "string"
|
|
40
|
+
? result.content
|
|
41
|
+
: JSON.stringify(result.content),
|
|
42
|
+
reasoning: result.reasoning,
|
|
43
|
+
reasoningTokens,
|
|
44
|
+
history: result.history,
|
|
45
|
+
rawResponses: result.responses,
|
|
46
|
+
usage: result.usage,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
log.error(`Error calling ${provider}:`, error);
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
provider,
|
|
54
|
+
model,
|
|
55
|
+
error: error instanceof Error ? error.message : String(error),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { debugLlmCall };
|
|
61
|
+
//# sourceMappingURL=llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sources":["../../../src/suites/llm/llm.ts"],"sourcesContent":["/**\n * LLM debugging utilities for inspecting raw provider responses\n */\n\nimport { LLM, Llm } from \"@jaypie/llm\";\n\nexport type LlmProvider = \"anthropic\" | \"gemini\" | \"openai\" | \"openrouter\";\n\nexport interface LlmDebugCallParams {\n provider: LlmProvider;\n model?: string;\n message: string;\n}\n\nexport interface LlmDebugCallResult {\n success: boolean;\n provider: string;\n model: string;\n content?: string;\n reasoning?: string[];\n reasoningTokens?: number;\n history?: unknown[];\n rawResponses?: unknown[];\n usage?: unknown[];\n error?: string;\n}\n\ninterface Logger {\n info: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\n// Default models for each provider\nconst DEFAULT_MODELS: Record<LlmProvider, string> = {\n anthropic: LLM.PROVIDER.ANTHROPIC.MODEL.SMALL,\n gemini: LLM.PROVIDER.GEMINI.MODEL.SMALL,\n openai: LLM.PROVIDER.OPENAI.MODEL.SMALL,\n openrouter: LLM.PROVIDER.OPENROUTER.MODEL.SMALL,\n};\n\n/**\n * Make a debug LLM call and return the raw response data for inspection\n */\nexport async function debugLlmCall(\n params: LlmDebugCallParams,\n log: Logger,\n): Promise<LlmDebugCallResult> {\n const { provider, message } = params;\n const model = params.model || DEFAULT_MODELS[provider];\n\n log.info(`Making debug LLM call to ${provider} with model ${model}`);\n\n try {\n const llm = new Llm(provider, { model });\n\n const result = await llm.operate(message, {\n user: \"[jaypie-mcp] Debug LLM Call\",\n });\n\n if (result.error) {\n return {\n success: false,\n provider,\n model,\n error: `${result.error.title}: ${result.error.detail || \"Unknown error\"}`,\n };\n }\n\n // Calculate total reasoning tokens\n const reasoningTokens = result.usage.reduce(\n (sum, u) => sum + (u.reasoning || 0),\n 0,\n );\n\n return {\n success: true,\n provider,\n model,\n content:\n typeof result.content === \"string\"\n ? result.content\n : JSON.stringify(result.content),\n reasoning: result.reasoning,\n reasoningTokens,\n history: result.history,\n rawResponses: result.responses,\n usage: result.usage,\n };\n } catch (error) {\n log.error(`Error calling ${provider}:`, error);\n return {\n success: false,\n provider,\n model,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n"],"names":[],"mappings":";;AAAA;;AAEG;AA8BH;AACA,MAAM,cAAc,GAAgC;IAClD,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK;IAC7C,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;IACvC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;IACvC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK;CAChD;AAED;;AAEG;AACI,eAAe,YAAY,CAChC,MAA0B,EAC1B,GAAW,EAAA;AAEX,IAAA,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,cAAc,CAAC,QAAQ,CAAC;IAEtD,GAAG,CAAC,IAAI,CAAC,CAAA,yBAAA,EAA4B,QAAQ,CAAA,YAAA,EAAe,KAAK,CAAA,CAAE,CAAC;AAEpE,IAAA,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE;AACxC,YAAA,IAAI,EAAE,6BAA6B;AACpC,SAAA,CAAC;AAEF,QAAA,IAAI,MAAM,CAAC,KAAK,EAAE;YAChB,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;gBACd,QAAQ;gBACR,KAAK;AACL,gBAAA,KAAK,EAAE,CAAA,EAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAA,EAAA,EAAK,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,eAAe,CAAA,CAAE;aAC1E;QACH;;QAGA,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CACzC,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EACpC,CAAC,CACF;QAED,OAAO;AACL,YAAA,OAAO,EAAE,IAAI;YACb,QAAQ;YACR,KAAK;AACL,YAAA,OAAO,EACL,OAAO,MAAM,CAAC,OAAO,KAAK;kBACtB,MAAM,CAAC;kBACP,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;YACpC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,eAAe;YACf,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY,EAAE,MAAM,CAAC,SAAS;YAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB;IACH;IAAE,OAAO,KAAK,EAAE;QACd,GAAG,CAAC,KAAK,CAAC,CAAA,cAAA,EAAiB,QAAQ,CAAA,CAAA,CAAG,EAAE,KAAK,CAAC;QAC9C,OAAO;AACL,YAAA,OAAO,EAAE,KAAK;YACd,QAAQ;YACR,KAAK;AACL,YAAA,KAAK,EAAE,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;SAC9D;IACH;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaypie/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Jaypie MCP",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"typecheck": "tsc --noEmit"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@jaypie/fabric": "
|
|
43
|
-
"@jaypie/llm": "
|
|
42
|
+
"@jaypie/fabric": "*",
|
|
43
|
+
"@jaypie/llm": "*",
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.17.0",
|
|
45
45
|
"commander": "^14.0.0",
|
|
46
46
|
"gray-matter": "^4.0.3",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@types/semver": "^7.7.1",
|
|
55
55
|
"express": "^5.1.0",
|
|
56
56
|
"rollup": "^4.53.3",
|
|
57
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
57
58
|
"typescript": "^5.9.3"
|
|
58
59
|
},
|
|
59
60
|
"publishConfig": {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.5
|
|
3
|
+
date: 2025-01-23
|
|
4
|
+
summary: Add WebSocket connection management utilities
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## New Features
|
|
8
|
+
|
|
9
|
+
### WebSocket Utilities
|
|
10
|
+
|
|
11
|
+
- **`sendToConnection(data, { connectionId, domainName, stage })`** - Send data to a WebSocket connection
|
|
12
|
+
- **`broadcastToConnections(data, { connectionIds, domainName, stage })`** - Broadcast data to multiple connections
|
|
13
|
+
|
|
14
|
+
Both functions use the ApiGatewayManagementApi client and handle stale connection errors gracefully.
|
|
15
|
+
|
|
16
|
+
## Dependencies
|
|
17
|
+
|
|
18
|
+
- Added `@aws-sdk/client-apigatewaymanagementapi`
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 1.2.19
|
|
3
|
+
date: 2025-01-23
|
|
4
|
+
summary: Add WebSocket API Gateway constructs
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## New Constructs
|
|
8
|
+
|
|
9
|
+
### JaypieWebSocket
|
|
10
|
+
|
|
11
|
+
WebSocket API using AWS API Gateway v2 with custom domain support:
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
const ws = new JaypieWebSocket(this, "Chat", {
|
|
15
|
+
host: "ws.example.com",
|
|
16
|
+
connect: connectLambda,
|
|
17
|
+
disconnect: disconnectLambda,
|
|
18
|
+
default: messageLambda,
|
|
19
|
+
routes: { sendMessage: sendMessageLambda },
|
|
20
|
+
});
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### JaypieWebSocketLambda
|
|
24
|
+
|
|
25
|
+
Convenience Lambda construct for WebSocket handlers with appropriate defaults.
|
|
26
|
+
|
|
27
|
+
### JaypieWebSocketTable
|
|
28
|
+
|
|
29
|
+
Optional DynamoDB table for connection tracking with TTL support:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
const table = new JaypieWebSocketTable(this, "Connections", {
|
|
33
|
+
ttl: Duration.hours(24),
|
|
34
|
+
});
|
|
35
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: 0.4.0
|
|
3
|
+
date: 2026-01-22
|
|
4
|
+
summary: Rename class to category for consistency with @jaypie/fabric
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# @jaypie/dynamodb 0.4.0
|
|
8
|
+
|
|
9
|
+
## Breaking Changes
|
|
10
|
+
|
|
11
|
+
Renamed `class` to `category` throughout the package to align with `@jaypie/fabric` vocabulary:
|
|
12
|
+
|
|
13
|
+
### Constants
|
|
14
|
+
- `INDEX_CLASS` → `INDEX_CATEGORY`
|
|
15
|
+
|
|
16
|
+
### Functions
|
|
17
|
+
- `buildIndexClass()` → `buildIndexCategory()`
|
|
18
|
+
- `queryByClass()` → `queryByCategory()`
|
|
19
|
+
|
|
20
|
+
### Types
|
|
21
|
+
- `QueryByClassParams` → `QueryByCategoryParams`
|
|
22
|
+
- `recordClass` parameter → `category` parameter
|
|
23
|
+
- `indexClass` field → `indexCategory` field on `StorableEntity`
|
|
24
|
+
|
|
25
|
+
### MCP Tools
|
|
26
|
+
- `dynamodb_query_class` tool → `dynamodb_query_category` tool
|
|
27
|
+
|
|
28
|
+
## Migration
|
|
29
|
+
|
|
30
|
+
Update your code to use the new names:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Before
|
|
34
|
+
import { INDEX_CLASS, buildIndexClass, queryByClass } from "@jaypie/dynamodb";
|
|
35
|
+
|
|
36
|
+
const key = buildIndexClass(scope, model, recordClass);
|
|
37
|
+
const result = await queryByClass({ model, scope, recordClass: "memory" });
|
|
38
|
+
|
|
39
|
+
// After
|
|
40
|
+
import { INDEX_CATEGORY, buildIndexCategory, queryByCategory } from "@jaypie/dynamodb";
|
|
41
|
+
|
|
42
|
+
const key = buildIndexCategory(scope, model, category);
|
|
43
|
+
const result = await queryByCategory({ model, scope, category: "memory" });
|
|
44
|
+
```
|