@public-ui/mcp 4.0.0-alpha.2 → 4.0.0-alpha.9
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 +339 -139
- package/dist/cli.cjs +37 -42
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +36 -42
- package/dist/data.cjs +88 -0
- package/dist/data.d.cts +34 -0
- package/dist/data.d.mts +34 -0
- package/dist/data.d.ts +34 -0
- package/dist/data.mjs +83 -0
- package/dist/mcp.cjs +298 -0
- package/dist/mcp.d.cts +9 -0
- package/dist/mcp.d.mts +9 -0
- package/dist/mcp.d.ts +9 -0
- package/dist/mcp.mjs +291 -0
- package/dist/search.cjs +52 -0
- package/dist/search.d.cts +16 -0
- package/dist/search.d.mts +16 -0
- package/dist/search.d.ts +16 -0
- package/dist/search.mjs +46 -0
- package/package.json +48 -6
- package/shared/.gitkeep +1 -0
- package/shared/sample-index.json +1860 -0
- package/dist/api-handler.cjs +0 -269
- package/dist/api-handler.mjs +0 -265
- package/dist/chunks/sample-index-runtime.cjs +0 -327
- package/dist/chunks/sample-index-runtime.mjs +0 -320
- package/dist/index.cjs +0 -71
- package/dist/index.mjs +0 -66
- package/dist/sample-index.cjs +0 -117
- package/dist/sample-index.mjs +0 -109
- package/dist/samples.json +0 -1428
- package/dist/samples.mjs +0 -1430
package/dist/index.cjs
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const node_http = require('node:http');
|
|
4
|
-
const sampleIndex = require('./sample-index.cjs');
|
|
5
|
-
const apiHandler = require('./api-handler.cjs');
|
|
6
|
-
require('node:fs/promises');
|
|
7
|
-
require('node:path');
|
|
8
|
-
require('node:url');
|
|
9
|
-
|
|
10
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
11
|
-
const DEFAULT_PORT = Number.parseInt(process.env.PORT ?? "3030", 10);
|
|
12
|
-
async function startServer(options = {}) {
|
|
13
|
-
const port = Number.parseInt(`${options.port ?? DEFAULT_PORT}`, 10);
|
|
14
|
-
let index = await sampleIndex.buildSampleIndex();
|
|
15
|
-
const server = node_http.createServer((request, response) => {
|
|
16
|
-
Promise.resolve(
|
|
17
|
-
apiHandler.handleApiRequest({
|
|
18
|
-
method: request.method ?? "GET",
|
|
19
|
-
url: request.url ?? "/",
|
|
20
|
-
getIndex: () => index
|
|
21
|
-
})
|
|
22
|
-
).then((result) => respondWithResult(response, result)).catch((error) => {
|
|
23
|
-
console.error("[mcp] request failed", error);
|
|
24
|
-
if (!response.headersSent) {
|
|
25
|
-
respondWithResult(response, {
|
|
26
|
-
statusCode: 500,
|
|
27
|
-
headers: {
|
|
28
|
-
"Access-Control-Allow-Origin": "*",
|
|
29
|
-
"Access-Control-Allow-Methods": "GET,POST,OPTIONS",
|
|
30
|
-
"Access-Control-Allow-Headers": "Content-Type"
|
|
31
|
-
},
|
|
32
|
-
body: { error: "internal_error" }
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
server.listen(port, () => {
|
|
38
|
-
console.log(`[mcp] server listening on http://localhost:${port}`);
|
|
39
|
-
});
|
|
40
|
-
return server;
|
|
41
|
-
}
|
|
42
|
-
function respondWithResult(response, result) {
|
|
43
|
-
if (response.headersSent) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
response.statusCode = result.statusCode;
|
|
47
|
-
const headers = {
|
|
48
|
-
"Content-Type": "application/json; charset=utf-8",
|
|
49
|
-
...result.headers
|
|
50
|
-
};
|
|
51
|
-
for (const [name, value] of Object.entries(headers)) {
|
|
52
|
-
response.setHeader(name, value);
|
|
53
|
-
}
|
|
54
|
-
if (result.body === void 0) {
|
|
55
|
-
response.end();
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
response.end(JSON.stringify(result.body, null, 2));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if ((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) === `file://${process.argv[1]}`) {
|
|
62
|
-
startServer().catch((error) => {
|
|
63
|
-
console.error("[mcp] failed to start server", error);
|
|
64
|
-
process.exitCode = 1;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
exports.buildSampleIndex = sampleIndex.buildSampleIndex;
|
|
69
|
-
exports.AI_HINTS_KEY = apiHandler.AI_HINTS_KEY;
|
|
70
|
-
exports.AI_HINTS_MESSAGES = apiHandler.AI_HINTS_MESSAGES;
|
|
71
|
-
exports.handleApiRequest = apiHandler.handleApiRequest;
|
package/dist/index.mjs
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { createServer } from 'node:http';
|
|
2
|
-
import { buildSampleIndex } from './sample-index.mjs';
|
|
3
|
-
import { handleApiRequest } from './api-handler.mjs';
|
|
4
|
-
export { AI_HINTS_KEY, AI_HINTS_MESSAGES } from './api-handler.mjs';
|
|
5
|
-
import 'node:fs/promises';
|
|
6
|
-
import 'node:path';
|
|
7
|
-
import 'node:url';
|
|
8
|
-
|
|
9
|
-
const DEFAULT_PORT = Number.parseInt(process.env.PORT ?? "3030", 10);
|
|
10
|
-
async function startServer(options = {}) {
|
|
11
|
-
const port = Number.parseInt(`${options.port ?? DEFAULT_PORT}`, 10);
|
|
12
|
-
let index = await buildSampleIndex();
|
|
13
|
-
const server = createServer((request, response) => {
|
|
14
|
-
Promise.resolve(
|
|
15
|
-
handleApiRequest({
|
|
16
|
-
method: request.method ?? "GET",
|
|
17
|
-
url: request.url ?? "/",
|
|
18
|
-
getIndex: () => index
|
|
19
|
-
})
|
|
20
|
-
).then((result) => respondWithResult(response, result)).catch((error) => {
|
|
21
|
-
console.error("[mcp] request failed", error);
|
|
22
|
-
if (!response.headersSent) {
|
|
23
|
-
respondWithResult(response, {
|
|
24
|
-
statusCode: 500,
|
|
25
|
-
headers: {
|
|
26
|
-
"Access-Control-Allow-Origin": "*",
|
|
27
|
-
"Access-Control-Allow-Methods": "GET,POST,OPTIONS",
|
|
28
|
-
"Access-Control-Allow-Headers": "Content-Type"
|
|
29
|
-
},
|
|
30
|
-
body: { error: "internal_error" }
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
server.listen(port, () => {
|
|
36
|
-
console.log(`[mcp] server listening on http://localhost:${port}`);
|
|
37
|
-
});
|
|
38
|
-
return server;
|
|
39
|
-
}
|
|
40
|
-
function respondWithResult(response, result) {
|
|
41
|
-
if (response.headersSent) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
response.statusCode = result.statusCode;
|
|
45
|
-
const headers = {
|
|
46
|
-
"Content-Type": "application/json; charset=utf-8",
|
|
47
|
-
...result.headers
|
|
48
|
-
};
|
|
49
|
-
for (const [name, value] of Object.entries(headers)) {
|
|
50
|
-
response.setHeader(name, value);
|
|
51
|
-
}
|
|
52
|
-
if (result.body === void 0) {
|
|
53
|
-
response.end();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
response.end(JSON.stringify(result.body, null, 2));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
60
|
-
startServer().catch((error) => {
|
|
61
|
-
console.error("[mcp] failed to start server", error);
|
|
62
|
-
process.exitCode = 1;
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export { buildSampleIndex, handleApiRequest };
|
package/dist/sample-index.cjs
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const promises = require('node:fs/promises');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
const node_url = require('node:url');
|
|
6
|
-
|
|
7
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
8
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
9
|
-
|
|
10
|
-
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
11
|
-
|
|
12
|
-
const __dirname$1 = path__default.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('sample-index.cjs', document.baseURI).href))));
|
|
13
|
-
function normalizeEntryId(entry) {
|
|
14
|
-
const kind = entry.kind ?? "sample";
|
|
15
|
-
const isDoc = kind === "doc";
|
|
16
|
-
const expectedPrefix = isDoc ? "doc" : "sample";
|
|
17
|
-
if (typeof entry.id === "string" && entry.id.startsWith(`${expectedPrefix}/`)) {
|
|
18
|
-
return entry;
|
|
19
|
-
}
|
|
20
|
-
const segments = [];
|
|
21
|
-
if (entry.group) {
|
|
22
|
-
const groupSegments = entry.group.split("/").filter(Boolean);
|
|
23
|
-
if (isDoc && groupSegments[0] === "docs") {
|
|
24
|
-
groupSegments.shift();
|
|
25
|
-
}
|
|
26
|
-
segments.push(...groupSegments);
|
|
27
|
-
}
|
|
28
|
-
if (entry.name) {
|
|
29
|
-
segments.push(entry.name);
|
|
30
|
-
} else if (entry.id) {
|
|
31
|
-
segments.push(...String(entry.id).split("/").filter(Boolean));
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
...entry,
|
|
35
|
-
id: [expectedPrefix, ...segments.filter(Boolean)].join("/")
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function computeCounts(entries) {
|
|
39
|
-
return entries.reduce(
|
|
40
|
-
(acc, entry) => {
|
|
41
|
-
const kind = entry.kind ?? "sample";
|
|
42
|
-
acc.total += 1;
|
|
43
|
-
acc.byKind.set(kind, (acc.byKind.get(kind) ?? 0) + 1);
|
|
44
|
-
return acc;
|
|
45
|
-
},
|
|
46
|
-
{ total: 0, byKind: /* @__PURE__ */ new Map() }
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
class SampleIndex {
|
|
50
|
-
constructor(entries, generatedAt = /* @__PURE__ */ new Date(), buildMode = "runtime") {
|
|
51
|
-
const normalizedEntries = entries.map((entry) => normalizeEntryId(entry));
|
|
52
|
-
this.entries = normalizedEntries;
|
|
53
|
-
this.map = new Map(normalizedEntries.map((entry) => [entry.id, entry]));
|
|
54
|
-
this.generatedAt = generatedAt;
|
|
55
|
-
this.buildMode = buildMode;
|
|
56
|
-
const counts = computeCounts(normalizedEntries);
|
|
57
|
-
this.counts = {
|
|
58
|
-
total: counts.total,
|
|
59
|
-
byKind: counts.byKind,
|
|
60
|
-
totalSamples: counts.byKind.get("sample") ?? counts.total,
|
|
61
|
-
totalDocs: counts.byKind.get("doc") ?? 0
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
list(query, options = {}) {
|
|
65
|
-
const kinds = options.kinds ? new Set(options.kinds) : void 0;
|
|
66
|
-
const normalizeKind = (entry) => entry.kind ?? "sample";
|
|
67
|
-
let results = kinds ? this.entries.filter((entry) => kinds.has(normalizeKind(entry))) : this.entries;
|
|
68
|
-
if (!query) {
|
|
69
|
-
return results;
|
|
70
|
-
}
|
|
71
|
-
const normalized = query.trim().toLowerCase();
|
|
72
|
-
return results.filter(
|
|
73
|
-
(entry) => entry.id.toLowerCase().includes(normalized) || entry.group.toLowerCase().includes(normalized) || entry.name.toLowerCase().includes(normalized)
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
get(id) {
|
|
77
|
-
return this.map.get(id);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
async function buildSampleIndex() {
|
|
81
|
-
console.log("[buildSampleIndex] Starting sample index...");
|
|
82
|
-
const isProduction = process.env.NODE_ENV === "production" || process.env.BUILD_MODE === "prebuild";
|
|
83
|
-
let samplesJsonPath;
|
|
84
|
-
if (isProduction) {
|
|
85
|
-
if (__dirname$1.endsWith("/src")) {
|
|
86
|
-
samplesJsonPath = path__default.resolve(__dirname$1.replace(/\/src$/, "/dist"), "samples.json");
|
|
87
|
-
} else {
|
|
88
|
-
samplesJsonPath = path__default.resolve(__dirname$1, "samples.json");
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
samplesJsonPath = path__default.resolve(__dirname$1, "samples.json");
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
console.log("[buildSampleIndex] Trying to load prebuilt samples from:", samplesJsonPath);
|
|
95
|
-
const jsonData = await promises.readFile(samplesJsonPath, "utf8");
|
|
96
|
-
const data = JSON.parse(jsonData);
|
|
97
|
-
console.log("[buildSampleIndex] \u2705 Loaded prebuilt samples");
|
|
98
|
-
console.log("[buildSampleIndex] Total entries:", data.entries.length);
|
|
99
|
-
console.log("[buildSampleIndex] Build mode:", data.buildMode);
|
|
100
|
-
console.log("[buildSampleIndex] Generated at:", data.generatedAt);
|
|
101
|
-
return new SampleIndex(data.entries, new Date(data.generatedAt), data.buildMode);
|
|
102
|
-
} catch (error) {
|
|
103
|
-
if (isProduction) {
|
|
104
|
-
throw new Error("[buildSampleIndex] \u274C Prebuilt samples.json not found in production/built mode. Please run the build step before deploying.");
|
|
105
|
-
}
|
|
106
|
-
console.log("[buildSampleIndex] \u26A0\uFE0F Could not load prebuilt samples:", error.message);
|
|
107
|
-
console.log("[buildSampleIndex] Falling back to runtime discovery...");
|
|
108
|
-
const { buildSampleIndex: originalBuildSampleIndex } = await import('./chunks/sample-index-runtime.cjs');
|
|
109
|
-
return await originalBuildSampleIndex();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function getRepoRoot() {
|
|
113
|
-
return __dirname$1;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
exports.buildSampleIndex = buildSampleIndex;
|
|
117
|
-
exports.getRepoRoot = getRepoRoot;
|
package/dist/sample-index.mjs
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
function normalizeEntryId(entry) {
|
|
7
|
-
const kind = entry.kind ?? "sample";
|
|
8
|
-
const isDoc = kind === "doc";
|
|
9
|
-
const expectedPrefix = isDoc ? "doc" : "sample";
|
|
10
|
-
if (typeof entry.id === "string" && entry.id.startsWith(`${expectedPrefix}/`)) {
|
|
11
|
-
return entry;
|
|
12
|
-
}
|
|
13
|
-
const segments = [];
|
|
14
|
-
if (entry.group) {
|
|
15
|
-
const groupSegments = entry.group.split("/").filter(Boolean);
|
|
16
|
-
if (isDoc && groupSegments[0] === "docs") {
|
|
17
|
-
groupSegments.shift();
|
|
18
|
-
}
|
|
19
|
-
segments.push(...groupSegments);
|
|
20
|
-
}
|
|
21
|
-
if (entry.name) {
|
|
22
|
-
segments.push(entry.name);
|
|
23
|
-
} else if (entry.id) {
|
|
24
|
-
segments.push(...String(entry.id).split("/").filter(Boolean));
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
...entry,
|
|
28
|
-
id: [expectedPrefix, ...segments.filter(Boolean)].join("/")
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function computeCounts(entries) {
|
|
32
|
-
return entries.reduce(
|
|
33
|
-
(acc, entry) => {
|
|
34
|
-
const kind = entry.kind ?? "sample";
|
|
35
|
-
acc.total += 1;
|
|
36
|
-
acc.byKind.set(kind, (acc.byKind.get(kind) ?? 0) + 1);
|
|
37
|
-
return acc;
|
|
38
|
-
},
|
|
39
|
-
{ total: 0, byKind: /* @__PURE__ */ new Map() }
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
class SampleIndex {
|
|
43
|
-
constructor(entries, generatedAt = /* @__PURE__ */ new Date(), buildMode = "runtime") {
|
|
44
|
-
const normalizedEntries = entries.map((entry) => normalizeEntryId(entry));
|
|
45
|
-
this.entries = normalizedEntries;
|
|
46
|
-
this.map = new Map(normalizedEntries.map((entry) => [entry.id, entry]));
|
|
47
|
-
this.generatedAt = generatedAt;
|
|
48
|
-
this.buildMode = buildMode;
|
|
49
|
-
const counts = computeCounts(normalizedEntries);
|
|
50
|
-
this.counts = {
|
|
51
|
-
total: counts.total,
|
|
52
|
-
byKind: counts.byKind,
|
|
53
|
-
totalSamples: counts.byKind.get("sample") ?? counts.total,
|
|
54
|
-
totalDocs: counts.byKind.get("doc") ?? 0
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
list(query, options = {}) {
|
|
58
|
-
const kinds = options.kinds ? new Set(options.kinds) : void 0;
|
|
59
|
-
const normalizeKind = (entry) => entry.kind ?? "sample";
|
|
60
|
-
let results = kinds ? this.entries.filter((entry) => kinds.has(normalizeKind(entry))) : this.entries;
|
|
61
|
-
if (!query) {
|
|
62
|
-
return results;
|
|
63
|
-
}
|
|
64
|
-
const normalized = query.trim().toLowerCase();
|
|
65
|
-
return results.filter(
|
|
66
|
-
(entry) => entry.id.toLowerCase().includes(normalized) || entry.group.toLowerCase().includes(normalized) || entry.name.toLowerCase().includes(normalized)
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
get(id) {
|
|
70
|
-
return this.map.get(id);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async function buildSampleIndex() {
|
|
74
|
-
console.log("[buildSampleIndex] Starting sample index...");
|
|
75
|
-
const isProduction = process.env.NODE_ENV === "production" || process.env.BUILD_MODE === "prebuild";
|
|
76
|
-
let samplesJsonPath;
|
|
77
|
-
if (isProduction) {
|
|
78
|
-
if (__dirname.endsWith("/src")) {
|
|
79
|
-
samplesJsonPath = path.resolve(__dirname.replace(/\/src$/, "/dist"), "samples.json");
|
|
80
|
-
} else {
|
|
81
|
-
samplesJsonPath = path.resolve(__dirname, "samples.json");
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
samplesJsonPath = path.resolve(__dirname, "samples.json");
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
console.log("[buildSampleIndex] Trying to load prebuilt samples from:", samplesJsonPath);
|
|
88
|
-
const jsonData = await readFile(samplesJsonPath, "utf8");
|
|
89
|
-
const data = JSON.parse(jsonData);
|
|
90
|
-
console.log("[buildSampleIndex] \u2705 Loaded prebuilt samples");
|
|
91
|
-
console.log("[buildSampleIndex] Total entries:", data.entries.length);
|
|
92
|
-
console.log("[buildSampleIndex] Build mode:", data.buildMode);
|
|
93
|
-
console.log("[buildSampleIndex] Generated at:", data.generatedAt);
|
|
94
|
-
return new SampleIndex(data.entries, new Date(data.generatedAt), data.buildMode);
|
|
95
|
-
} catch (error) {
|
|
96
|
-
if (isProduction) {
|
|
97
|
-
throw new Error("[buildSampleIndex] \u274C Prebuilt samples.json not found in production/built mode. Please run the build step before deploying.");
|
|
98
|
-
}
|
|
99
|
-
console.log("[buildSampleIndex] \u26A0\uFE0F Could not load prebuilt samples:", error.message);
|
|
100
|
-
console.log("[buildSampleIndex] Falling back to runtime discovery...");
|
|
101
|
-
const { buildSampleIndex: originalBuildSampleIndex } = await import('./chunks/sample-index-runtime.mjs');
|
|
102
|
-
return await originalBuildSampleIndex();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function getRepoRoot() {
|
|
106
|
-
return __dirname;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export { buildSampleIndex, getRepoRoot };
|