@assistant-ui/mcp-docs-server 0.1.17 → 0.1.18
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/.docs/organized/code-examples/with-ag-ui.md +146 -152
- package/.docs/organized/code-examples/with-ai-sdk-v5.md +96 -101
- package/.docs/organized/code-examples/with-assistant-transport.md +132 -220
- package/.docs/organized/code-examples/with-cloud.md +124 -131
- package/.docs/organized/code-examples/with-custom-thread-list.md +26 -46
- package/.docs/organized/code-examples/with-external-store.md +146 -151
- package/.docs/organized/code-examples/with-ffmpeg.md +129 -139
- package/.docs/organized/code-examples/with-langgraph.md +231 -225
- package/.docs/organized/code-examples/with-parent-id-grouping.md +146 -151
- package/.docs/organized/code-examples/with-react-hook-form.md +146 -152
- package/.docs/organized/code-examples/{store-example.md → with-store.md} +16 -20
- package/.docs/organized/code-examples/with-tanstack.md +23 -41
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +36 -0
- package/.docs/raw/docs/runtimes/custom/local.mdx +31 -8
- package/.docs/raw/docs/ui/Scrollbar.mdx +0 -6
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -0
- package/dist/prepare-docs/code-examples.d.ts +2 -0
- package/dist/prepare-docs/code-examples.d.ts.map +1 -0
- package/dist/prepare-docs/code-examples.js +129 -0
- package/dist/prepare-docs/code-examples.js.map +1 -0
- package/dist/prepare-docs/copy-raw.d.ts +2 -0
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -0
- package/dist/prepare-docs/copy-raw.js +50 -0
- package/dist/prepare-docs/copy-raw.js.map +1 -0
- package/dist/prepare-docs/prepare.d.ts +2 -0
- package/dist/prepare-docs/prepare.d.ts.map +1 -0
- package/dist/prepare-docs/prepare.js +18 -195
- package/dist/prepare-docs/prepare.js.map +1 -0
- package/dist/stdio.d.ts +3 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +4 -5
- package/dist/stdio.js.map +1 -0
- package/dist/tools/docs.d.ts +23 -0
- package/dist/tools/docs.d.ts.map +1 -0
- package/dist/tools/docs.js +168 -0
- package/dist/tools/docs.js.map +1 -0
- package/dist/tools/examples.d.ts +23 -0
- package/dist/tools/examples.d.ts.map +1 -0
- package/dist/tools/examples.js +95 -0
- package/dist/tools/examples.js.map +1 -0
- package/dist/tools/tests/test-setup.d.ts +4 -0
- package/dist/tools/tests/test-setup.d.ts.map +1 -0
- package/dist/tools/tests/test-setup.js +36 -0
- package/dist/tools/tests/test-setup.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +20 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-format.d.ts +7 -0
- package/dist/utils/mcp-format.d.ts.map +1 -0
- package/dist/utils/mcp-format.js +11 -0
- package/dist/utils/mcp-format.js.map +1 -0
- package/dist/utils/mdx.d.ts +9 -0
- package/dist/utils/mdx.d.ts.map +1 -0
- package/dist/utils/mdx.js +27 -0
- package/dist/utils/mdx.js.map +1 -0
- package/dist/utils/paths.d.ts +8 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +84 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/security.d.ts +2 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +43 -0
- package/dist/utils/security.js.map +1 -0
- package/package.json +37 -19
- package/src/constants.ts +22 -0
- package/src/index.ts +51 -0
- package/src/prepare-docs/code-examples.ts +158 -0
- package/src/prepare-docs/copy-raw.ts +55 -0
- package/src/prepare-docs/prepare.ts +24 -0
- package/src/stdio.ts +7 -0
- package/src/tools/docs.ts +207 -0
- package/src/tools/examples.ts +107 -0
- package/src/tools/tests/docs.test.ts +122 -0
- package/src/tools/tests/examples.test.ts +94 -0
- package/src/tools/tests/integration.test.ts +46 -0
- package/src/tools/tests/json-parsing.test.ts +23 -0
- package/src/tools/tests/mcp-protocol.test.ts +133 -0
- package/src/tools/tests/path-traversal.test.ts +81 -0
- package/src/tools/tests/test-setup.ts +40 -0
- package/src/utils/logger.ts +20 -0
- package/src/utils/mcp-format.ts +12 -0
- package/src/utils/mdx.ts +39 -0
- package/src/utils/paths.ts +114 -0
- package/src/utils/security.ts +52 -0
- package/src/utils/tests/security.test.ts +119 -0
- package/dist/chunk-M2RKUM66.js +0 -38
- package/dist/chunk-NVNFQ5ZO.js +0 -423
|
@@ -1,199 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
await mkdir(dest, { recursive: true });
|
|
11
|
-
const entries = await readdir(src, { withFileTypes: true });
|
|
12
|
-
for (const entry of entries) {
|
|
13
|
-
const srcPath = join(src, entry.name);
|
|
14
|
-
const destPath = join(dest, entry.name);
|
|
15
|
-
if (entry.isDirectory()) {
|
|
16
|
-
await copyDir(srcPath, destPath);
|
|
17
|
-
} else if (entry.isFile()) {
|
|
18
|
-
const ext = extname(entry.name).toLowerCase();
|
|
19
|
-
if (ext === ".mdx" || ext === ".md") {
|
|
20
|
-
await copyFile(srcPath, destPath);
|
|
21
|
-
logger.debug(`Copied: ${srcPath} -> ${destPath}`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
} catch (error) {
|
|
26
|
-
logger.error(`Failed to copy directory: ${src}`, error);
|
|
27
|
-
throw error;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async function copyRaw() {
|
|
31
|
-
logger.info("Copying raw documentation files...");
|
|
32
|
-
try {
|
|
33
|
-
await rm(DOCS_DEST, { recursive: true, force: true });
|
|
34
|
-
await mkdir(DOCS_DEST, { recursive: true });
|
|
35
|
-
const docsPath = join(DOCS_DEST, "docs");
|
|
36
|
-
await copyDir(DOCS_SOURCE, docsPath);
|
|
37
|
-
logger.info(`Copied documentation to ${docsPath}`);
|
|
38
|
-
const blogPath = join(DOCS_DEST, "blog");
|
|
39
|
-
await copyDir(BLOG_SOURCE, blogPath);
|
|
40
|
-
logger.info(`Copied blog posts to ${blogPath}`);
|
|
41
|
-
logger.info("Raw documentation copy complete");
|
|
42
|
-
} catch (error) {
|
|
43
|
-
logger.error("Failed to copy raw documentation", error);
|
|
44
|
-
throw error;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
var OUTPUT_DIR = join(
|
|
48
|
-
ROOT_DIR,
|
|
49
|
-
"packages/mcp-docs-server/.docs/organized/code-examples"
|
|
50
|
-
);
|
|
51
|
-
var MAX_LINES = 1e4;
|
|
52
|
-
async function scanDirectory(dir, baseDir) {
|
|
53
|
-
const files = [];
|
|
54
|
-
try {
|
|
55
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
56
|
-
for (const entry of entries) {
|
|
57
|
-
const fullPath = join(dir, entry.name);
|
|
58
|
-
if (entry.isDirectory()) {
|
|
59
|
-
const skipDirs = [
|
|
60
|
-
"node_modules",
|
|
61
|
-
"dist",
|
|
62
|
-
"build",
|
|
63
|
-
".next",
|
|
64
|
-
".git",
|
|
65
|
-
".turbo"
|
|
66
|
-
];
|
|
67
|
-
if (!skipDirs.includes(entry.name)) {
|
|
68
|
-
const subFiles = await scanDirectory(fullPath, baseDir);
|
|
69
|
-
files.push(...subFiles);
|
|
70
|
-
}
|
|
71
|
-
} else if (entry.isFile()) {
|
|
72
|
-
const includeExts = [
|
|
73
|
-
".ts",
|
|
74
|
-
".tsx",
|
|
75
|
-
".js",
|
|
76
|
-
".jsx",
|
|
77
|
-
".json",
|
|
78
|
-
".css",
|
|
79
|
-
".md",
|
|
80
|
-
".mdx"
|
|
81
|
-
];
|
|
82
|
-
const ext = extname(entry.name).toLowerCase();
|
|
83
|
-
if (includeExts.includes(ext) || entry.name === "package.json" || entry.name === "tsconfig.json") {
|
|
84
|
-
try {
|
|
85
|
-
const content = await readFile(fullPath, "utf-8");
|
|
86
|
-
const relativePath = relative(baseDir, fullPath);
|
|
87
|
-
files.push({ path: relativePath, content });
|
|
88
|
-
} catch (error) {
|
|
89
|
-
logger.warn(`Failed to read file: ${fullPath}`, error);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
1
|
+
import { logger } from "../utils/logger.js";
|
|
2
|
+
import { copyRaw } from "./copy-raw.js";
|
|
3
|
+
import { prepareCodeExamples } from "./code-examples.js";
|
|
4
|
+
async function prepare() {
|
|
5
|
+
logger.info("Starting documentation preparation...");
|
|
6
|
+
try {
|
|
7
|
+
await copyRaw();
|
|
8
|
+
await prepareCodeExamples();
|
|
9
|
+
logger.info("Documentation preparation complete");
|
|
93
10
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return files;
|
|
98
|
-
}
|
|
99
|
-
function getFileType(filename) {
|
|
100
|
-
const ext = extname(filename).toLowerCase();
|
|
101
|
-
const extMap = {
|
|
102
|
-
".ts": "typescript",
|
|
103
|
-
".tsx": "tsx",
|
|
104
|
-
".js": "javascript",
|
|
105
|
-
".jsx": "jsx",
|
|
106
|
-
".json": "json",
|
|
107
|
-
".css": "css",
|
|
108
|
-
".md": "markdown",
|
|
109
|
-
".mdx": "mdx"
|
|
110
|
-
};
|
|
111
|
-
return extMap[ext] || "text";
|
|
112
|
-
}
|
|
113
|
-
async function prepareCodeExamples() {
|
|
114
|
-
logger.info("Preparing code examples...");
|
|
115
|
-
try {
|
|
116
|
-
await rm(OUTPUT_DIR, { recursive: true, force: true });
|
|
117
|
-
await mkdir(OUTPUT_DIR, { recursive: true });
|
|
118
|
-
const exampleDirs = await readdir(EXAMPLES_PATH, { withFileTypes: true });
|
|
119
|
-
for (const dir of exampleDirs) {
|
|
120
|
-
if (dir.isDirectory() && !dir.name.startsWith(".")) {
|
|
121
|
-
const examplePath = join(EXAMPLES_PATH, dir.name);
|
|
122
|
-
logger.info(`Processing example: ${dir.name}`);
|
|
123
|
-
let description = "";
|
|
124
|
-
try {
|
|
125
|
-
const packageJsonPath = join(examplePath, "package.json");
|
|
126
|
-
const packageJson = JSON.parse(
|
|
127
|
-
await readFile(packageJsonPath, "utf-8")
|
|
128
|
-
);
|
|
129
|
-
description = packageJson.description || "";
|
|
130
|
-
} catch (error) {
|
|
131
|
-
if (error?.code !== "ENOENT") {
|
|
132
|
-
logger.warn(`Failed to read package.json for ${dir.name}:`, error);
|
|
133
|
-
} else {
|
|
134
|
-
logger.debug(`No package.json found for example: ${dir.name}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const files = await scanDirectory(examplePath, examplePath);
|
|
138
|
-
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
139
|
-
let markdown = `# Example: ${dir.name}
|
|
140
|
-
|
|
141
|
-
`;
|
|
142
|
-
if (description) {
|
|
143
|
-
markdown += `${description}
|
|
144
|
-
|
|
145
|
-
`;
|
|
146
|
-
}
|
|
147
|
-
let totalLines = 0;
|
|
148
|
-
for (const file of files) {
|
|
149
|
-
const lines = file.content.split("\n").length;
|
|
150
|
-
if (totalLines + lines > MAX_LINES) {
|
|
151
|
-
markdown += `
|
|
152
|
-
_Note: Additional files truncated due to size limits_
|
|
153
|
-
`;
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
markdown += `## ${file.path.replace(/\\/g, "/")}
|
|
157
|
-
|
|
158
|
-
`;
|
|
159
|
-
markdown += `\`\`\`${getFileType(file.path)}
|
|
160
|
-
`;
|
|
161
|
-
markdown += file.content;
|
|
162
|
-
markdown += `
|
|
163
|
-
\`\`\`
|
|
164
|
-
|
|
165
|
-
`;
|
|
166
|
-
totalLines += lines;
|
|
167
|
-
}
|
|
168
|
-
const outputPath = join(OUTPUT_DIR, `${dir.name}.md`);
|
|
169
|
-
await writeFile(outputPath, markdown, "utf-8");
|
|
170
|
-
logger.debug(`Created example: ${outputPath}`);
|
|
171
|
-
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
logger.error("Documentation preparation failed", error);
|
|
13
|
+
throw error;
|
|
172
14
|
}
|
|
173
|
-
logger.info("Code examples preparation complete");
|
|
174
|
-
} catch (error) {
|
|
175
|
-
logger.error("Failed to prepare code examples", error);
|
|
176
|
-
throw error;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// src/prepare-docs/prepare.ts
|
|
181
|
-
async function prepare() {
|
|
182
|
-
logger.info("Starting documentation preparation...");
|
|
183
|
-
try {
|
|
184
|
-
await copyRaw();
|
|
185
|
-
await prepareCodeExamples();
|
|
186
|
-
logger.info("Documentation preparation complete");
|
|
187
|
-
} catch (error) {
|
|
188
|
-
logger.error("Documentation preparation failed", error);
|
|
189
|
-
throw error;
|
|
190
|
-
}
|
|
191
15
|
}
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
16
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
17
|
+
prepare().catch((error) => {
|
|
18
|
+
logger.error("Preparation failed", error);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
});
|
|
197
21
|
}
|
|
198
|
-
|
|
199
|
-
export { prepare };
|
|
22
|
+
//# sourceMappingURL=prepare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare.js","sourceRoot":"","sources":["../../src/prepare-docs/prepare.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,KAAK,UAAU,OAAO;IACpB,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,OAAO,EAAE,CAAC;QAChB,MAAM,mBAAmB,EAAE,CAAC;QAE5B,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QACxD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/stdio.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":""}
|
package/dist/stdio.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { runServer } from
|
|
3
|
-
|
|
4
|
-
// src/stdio.ts
|
|
2
|
+
import { runServer } from "./index.js";
|
|
5
3
|
void runServer().catch((error) => {
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
console.error("Failed to start server:", error);
|
|
5
|
+
process.exit(1);
|
|
8
6
|
});
|
|
7
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,KAAK,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC/B,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
declare const docsInputSchema: z.ZodObject<{
|
|
3
|
+
paths: z.ZodArray<z.ZodString, "many">;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
paths: string[];
|
|
6
|
+
}, {
|
|
7
|
+
paths: string[];
|
|
8
|
+
}>;
|
|
9
|
+
export declare const docsTools: {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
parameters: {
|
|
13
|
+
paths: z.ZodArray<z.ZodString, "many">;
|
|
14
|
+
};
|
|
15
|
+
execute: ({ paths }: z.infer<typeof docsInputSchema>) => Promise<{
|
|
16
|
+
content: Array<{
|
|
17
|
+
type: "text";
|
|
18
|
+
text: string;
|
|
19
|
+
}>;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/tools/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAe3B,QAAA,MAAM,eAAe;;;;;;EAOnB,CAAC;AA6IH,eAAO,MAAM,SAAS;;;;;;yBAKO,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC;;;;;;CAsC3D,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
import { stat, lstat } from "node:fs/promises";
|
|
3
|
+
import { join, extname } from "node:path";
|
|
4
|
+
import { DOCS_PATH, MDX_EXTENSION, MAX_FILE_SIZE } from "../constants.js";
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
6
|
+
import { listDirContents, getAvailablePaths, findNearestPaths, pathExists, } from "../utils/paths.js";
|
|
7
|
+
import { readMDXFile, formatMDXContent } from "../utils/mdx.js";
|
|
8
|
+
import { formatMCPResponse } from "../utils/mcp-format.js";
|
|
9
|
+
import { sanitizePath } from "../utils/security.js";
|
|
10
|
+
const docsInputSchema = z.object({
|
|
11
|
+
paths: z
|
|
12
|
+
.array(z.string())
|
|
13
|
+
.min(1)
|
|
14
|
+
.describe('Documentation paths to retrieve (e.g., ["getting-started", "api-reference/primitives/Thread"])'),
|
|
15
|
+
});
|
|
16
|
+
async function readDocumentation(docPath) {
|
|
17
|
+
logger.debug(`Reading documentation for path: ${docPath}`);
|
|
18
|
+
if (docPath === "/" || docPath === "") {
|
|
19
|
+
const { directories, files } = await listDirContents(DOCS_PATH);
|
|
20
|
+
return {
|
|
21
|
+
path: "/",
|
|
22
|
+
found: true,
|
|
23
|
+
type: "directory",
|
|
24
|
+
directories,
|
|
25
|
+
files: files.map((f) => f.replace(MDX_EXTENSION, "")),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const sanitized = sanitizePath(docPath);
|
|
30
|
+
const fullPath = join(DOCS_PATH, sanitized);
|
|
31
|
+
try {
|
|
32
|
+
const lstats = await lstat(fullPath);
|
|
33
|
+
if (lstats.isSymbolicLink()) {
|
|
34
|
+
logger.warn(`Symlink detected at path: ${fullPath}`);
|
|
35
|
+
return {
|
|
36
|
+
path: docPath,
|
|
37
|
+
found: false,
|
|
38
|
+
error: "Symlinks are not allowed for security reasons",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
if (await pathExists(fullPath)) {
|
|
44
|
+
const stats = await stat(fullPath);
|
|
45
|
+
if (stats.isFile() && stats.size > MAX_FILE_SIZE) {
|
|
46
|
+
logger.warn(`File too large: ${fullPath} (${stats.size} bytes)`);
|
|
47
|
+
return {
|
|
48
|
+
path: docPath,
|
|
49
|
+
found: false,
|
|
50
|
+
error: `File size exceeds maximum allowed size of ${MAX_FILE_SIZE} bytes`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (stats.isDirectory()) {
|
|
54
|
+
const { directories, files } = await listDirContents(fullPath);
|
|
55
|
+
const contents = {};
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
const mdxContent = await readMDXFile(join(fullPath, file));
|
|
58
|
+
if (mdxContent) {
|
|
59
|
+
const fileName = file.replace(MDX_EXTENSION, "");
|
|
60
|
+
contents[fileName] = formatMDXContent(mdxContent);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const content = Object.keys(contents).length > 0
|
|
64
|
+
? JSON.stringify(contents, null, 2)
|
|
65
|
+
: undefined;
|
|
66
|
+
return {
|
|
67
|
+
path: docPath,
|
|
68
|
+
found: true,
|
|
69
|
+
type: "directory",
|
|
70
|
+
directories,
|
|
71
|
+
files: files.map((f) => f.replace(MDX_EXTENSION, "")),
|
|
72
|
+
...(content !== undefined && { content }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const mdxPath = extname(fullPath) === MDX_EXTENSION
|
|
77
|
+
? fullPath
|
|
78
|
+
: `${fullPath}${MDX_EXTENSION}`;
|
|
79
|
+
try {
|
|
80
|
+
const mdxLstats = await lstat(mdxPath);
|
|
81
|
+
if (mdxLstats.isSymbolicLink()) {
|
|
82
|
+
logger.warn(`Symlink detected at MDX path: ${mdxPath}`);
|
|
83
|
+
return {
|
|
84
|
+
path: docPath,
|
|
85
|
+
found: false,
|
|
86
|
+
error: "Symlinks are not allowed for security reasons",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (mdxLstats.size > MAX_FILE_SIZE) {
|
|
90
|
+
logger.warn(`MDX file too large: ${mdxPath} (${mdxLstats.size} bytes)`);
|
|
91
|
+
return {
|
|
92
|
+
path: docPath,
|
|
93
|
+
found: false,
|
|
94
|
+
error: `File size exceeds maximum allowed size of ${MAX_FILE_SIZE} bytes`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch { }
|
|
99
|
+
if (await pathExists(mdxPath)) {
|
|
100
|
+
const mdxContent = await readMDXFile(mdxPath);
|
|
101
|
+
if (mdxContent) {
|
|
102
|
+
return {
|
|
103
|
+
path: docPath,
|
|
104
|
+
found: true,
|
|
105
|
+
type: "file",
|
|
106
|
+
content: formatMDXContent(mdxContent),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const availablePaths = await getAvailablePaths();
|
|
111
|
+
const suggestions = findNearestPaths(docPath, availablePaths);
|
|
112
|
+
return {
|
|
113
|
+
path: docPath,
|
|
114
|
+
found: false,
|
|
115
|
+
suggestions,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (error instanceof Error && error.message.includes("Invalid path")) {
|
|
120
|
+
return {
|
|
121
|
+
path: docPath,
|
|
122
|
+
found: false,
|
|
123
|
+
error: error.message,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export const docsTools = {
|
|
130
|
+
name: "assistantUIDocs",
|
|
131
|
+
description: 'Retrieve assistant-ui documentation by path. Use "/" to list all sections. Supports multiple paths in a single request.',
|
|
132
|
+
parameters: docsInputSchema.shape,
|
|
133
|
+
execute: async ({ paths }) => {
|
|
134
|
+
logger.info(`Retrieving documentation for paths: ${paths.join(", ")}`);
|
|
135
|
+
try {
|
|
136
|
+
const results = await Promise.all(paths.map((path) => readDocumentation(path)));
|
|
137
|
+
if (results.length === 1) {
|
|
138
|
+
const result = results[0];
|
|
139
|
+
if (result.error) {
|
|
140
|
+
return formatMCPResponse({
|
|
141
|
+
error: result.error,
|
|
142
|
+
path: result.path,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (!result.found) {
|
|
146
|
+
return formatMCPResponse({
|
|
147
|
+
error: `Documentation not found for path: ${result.path}`,
|
|
148
|
+
suggestions: result.suggestions,
|
|
149
|
+
hint: 'Use "/" to list all available documentation sections',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return formatMCPResponse(result);
|
|
153
|
+
}
|
|
154
|
+
return formatMCPResponse({
|
|
155
|
+
results,
|
|
156
|
+
summary: `Retrieved ${results.filter((r) => r.found).length} of ${results.length} requested paths`,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
logger.error("Failed to retrieve documentation", error);
|
|
161
|
+
return formatMCPResponse({
|
|
162
|
+
error: "Failed to retrieve documentation",
|
|
163
|
+
message: error instanceof Error ? error.message : String(error),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/tools/docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
declare const examplesInputSchema: z.ZodObject<{
|
|
3
|
+
example: z.ZodOptional<z.ZodString>;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
example?: string | undefined;
|
|
6
|
+
}, {
|
|
7
|
+
example?: string | undefined;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const examplesTools: {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
parameters: {
|
|
13
|
+
example: z.ZodOptional<z.ZodString>;
|
|
14
|
+
};
|
|
15
|
+
execute: ({ example }: z.infer<typeof examplesInputSchema>) => Promise<{
|
|
16
|
+
content: Array<{
|
|
17
|
+
type: "text";
|
|
18
|
+
text: string;
|
|
19
|
+
}>;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=examples.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"examples.d.ts","sourceRoot":"","sources":["../../src/tools/examples.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAQ3B,QAAA,MAAM,mBAAmB;;;;;;EAOvB,CAAC;AAuCH,eAAO,MAAM,aAAa;;;;;;2BAKK,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC;;;;;;CA+CjE,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from "zod/v3";
|
|
2
|
+
import { readFile, readdir, lstat } from "node:fs/promises";
|
|
3
|
+
import { join, extname } from "node:path";
|
|
4
|
+
import { CODE_EXAMPLES_PATH, MAX_FILE_SIZE } from "../constants.js";
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
6
|
+
import { formatMCPResponse } from "../utils/mcp-format.js";
|
|
7
|
+
import { sanitizePath } from "../utils/security.js";
|
|
8
|
+
const examplesInputSchema = z.object({
|
|
9
|
+
example: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('Example name (e.g., "with-ai-sdk"). Leave empty to list all examples.'),
|
|
13
|
+
});
|
|
14
|
+
async function listCodeExamples() {
|
|
15
|
+
try {
|
|
16
|
+
const files = await readdir(CODE_EXAMPLES_PATH);
|
|
17
|
+
return files
|
|
18
|
+
.filter((file) => extname(file) === ".md")
|
|
19
|
+
.map((file) => file.replace(".md", ""))
|
|
20
|
+
.sort();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
logger.error("Failed to list code examples", error);
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function readCodeExample(exampleName) {
|
|
28
|
+
try {
|
|
29
|
+
const sanitized = sanitizePath(exampleName);
|
|
30
|
+
const filePath = join(CODE_EXAMPLES_PATH, `${sanitized}.md`);
|
|
31
|
+
const stats = await lstat(filePath);
|
|
32
|
+
if (stats.isSymbolicLink()) {
|
|
33
|
+
logger.warn(`Attempted to read symlink: ${filePath}`);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
37
|
+
logger.warn(`File size exceeds limit: ${filePath} (${stats.size} bytes)`);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const content = await readFile(filePath, "utf-8");
|
|
41
|
+
return content;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
logger.error(`Failed to read example: ${exampleName}`, error);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export const examplesTools = {
|
|
49
|
+
name: "assistantUIExamples",
|
|
50
|
+
description: "List available examples or retrieve complete code for a specific example",
|
|
51
|
+
parameters: examplesInputSchema.shape,
|
|
52
|
+
execute: async ({ example }) => {
|
|
53
|
+
try {
|
|
54
|
+
if (!example) {
|
|
55
|
+
logger.info("Listing all available examples");
|
|
56
|
+
const examples = await listCodeExamples();
|
|
57
|
+
if (examples.length === 0) {
|
|
58
|
+
return formatMCPResponse({
|
|
59
|
+
error: "No examples found. Please run documentation preparation first.",
|
|
60
|
+
hint: "Run: pnpm prepare-docs",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return formatMCPResponse({
|
|
64
|
+
type: "list",
|
|
65
|
+
examples,
|
|
66
|
+
total: examples.length,
|
|
67
|
+
hint: "Use example parameter to get complete code for any example",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
logger.info(`Retrieving example: ${example}`);
|
|
71
|
+
const content = await readCodeExample(example);
|
|
72
|
+
if (!content) {
|
|
73
|
+
const availableExamples = await listCodeExamples();
|
|
74
|
+
return formatMCPResponse({
|
|
75
|
+
error: `Example not found: ${example}`,
|
|
76
|
+
availableExamples,
|
|
77
|
+
hint: "Use without example parameter to list all available examples",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return formatMCPResponse({
|
|
81
|
+
type: "example",
|
|
82
|
+
name: example,
|
|
83
|
+
content,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
logger.error("Failed to retrieve examples", error);
|
|
88
|
+
return formatMCPResponse({
|
|
89
|
+
error: "Failed to retrieve examples",
|
|
90
|
+
message: error instanceof Error ? error.message : String(error),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=examples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"examples.js","sourceRoot":"","sources":["../../src/tools/examples.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,uEAAuE,CACxE;CACJ,CAAC,CAAC;AAEH,KAAK,UAAU,gBAAgB;IAC7B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAChD,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;aACzC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;aACtC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,WAAmB;IAChD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,GAAG,SAAS,KAAK,CAAC,CAAC;QAE7D,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,8BAA8B,QAAQ,EAAE,CAAC,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,4BAA4B,QAAQ,KAAK,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;YAC1E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,2BAA2B,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EACT,0EAA0E;IAC5E,UAAU,EAAE,mBAAmB,CAAC,KAAK;IACrC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAuC,EAAE,EAAE;QAClE,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,MAAM,gBAAgB,EAAE,CAAC;gBAE1C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,OAAO,iBAAiB,CAAC;wBACvB,KAAK,EACH,gEAAgE;wBAClE,IAAI,EAAE,wBAAwB;qBAC/B,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,iBAAiB,CAAC;oBACvB,IAAI,EAAE,MAAM;oBACZ,QAAQ;oBACR,KAAK,EAAE,QAAQ,CAAC,MAAM;oBACtB,IAAI,EAAE,4DAA4D;iBACnE,CAAC,CAAC;YACL,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;YAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,iBAAiB,GAAG,MAAM,gBAAgB,EAAE,CAAC;gBACnD,OAAO,iBAAiB,CAAC;oBACvB,KAAK,EAAE,sBAAsB,OAAO,EAAE;oBACtC,iBAAiB;oBACjB,IAAI,EAAE,8DAA8D;iBACrE,CAAC,CAAC;YACL,CAAC;YAED,OAAO,iBAAiB,CAAC;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACnD,OAAO,iBAAiB,CAAC;gBACvB,KAAK,EAAE,6BAA6B;gBACpC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../../../src/tools/tests/test-setup.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW;qBACC,MAAM,QAAQ,GAAG;CAmBzC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { beforeAll } from "vitest";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { PACKAGE_DIR } from "../../constants.js";
|
|
5
|
+
import { docsTools } from "../docs.js";
|
|
6
|
+
import { examplesTools } from "../examples.js";
|
|
7
|
+
const tools = {
|
|
8
|
+
assistantUIDocs: docsTools,
|
|
9
|
+
assistantUIExamples: examplesTools,
|
|
10
|
+
};
|
|
11
|
+
export const testContext = {
|
|
12
|
+
callTool: async (name, args) => {
|
|
13
|
+
const tool = tools[name];
|
|
14
|
+
if (!tool) {
|
|
15
|
+
throw new Error(`Tool ${name} not found`);
|
|
16
|
+
}
|
|
17
|
+
const result = await tool.execute(args);
|
|
18
|
+
const text = result.content?.[0]?.text;
|
|
19
|
+
if (text === undefined) {
|
|
20
|
+
throw new Error(`Tool ${name} returned no content`);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(text);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw new Error(`Tool ${name} returned invalid JSON. Output: ${text}\nParse error: ${error instanceof Error ? error.message : String(error)}`);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
beforeAll(() => {
|
|
31
|
+
const docsPath = join(PACKAGE_DIR, ".docs");
|
|
32
|
+
if (!existsSync(docsPath)) {
|
|
33
|
+
throw new Error("Documentation not prepared. Run: pnpm build");
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=test-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-setup.js","sourceRoot":"","sources":["../../../src/tools/tests/test-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,KAAK,GAAG;IACZ,eAAe,EAAE,SAAS;IAC1B,mBAAmB,EAAE,aAAa;CACnC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,KAAK,EAAE,IAAY,EAAE,IAAS,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,IAA0B,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAExC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;QACvC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,sBAAsB,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,QAAQ,IAAI,mCAAmC,IAAI,kBAAkB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC9H,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC;AAEF,SAAS,CAAC,GAAG,EAAE;IACb,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const logger: {
|
|
2
|
+
debug: (message: string, ...args: any[]) => void;
|
|
3
|
+
info: (message: string, ...args: any[]) => void;
|
|
4
|
+
error: (message: string, ...args: any[]) => void;
|
|
5
|
+
warn: (message: string, ...args: any[]) => void;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;qBACA,MAAM,WAAW,GAAG,EAAE;oBAKvB,MAAM,WAAW,GAAG,EAAE;qBAKrB,MAAM,WAAW,GAAG,EAAE;oBAGvB,MAAM,WAAW,GAAG,EAAE;CAGvC,CAAC"}
|