mirror of
https://github.com/sveltejs/ai-tools.git
synced 2026-07-04 03:19:38 +08:00
Compare commits
1 Commits
@sveltejs/
...
wip-docs-w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
199d57a8e3 |
@@ -1,3 +1,4 @@
|
|||||||
DATABASE_URL=file:test.db
|
DATABASE_URL=file:test.db
|
||||||
DATABASE_TOKEN=needs_to_be_set_but_it_can_be_anything
|
DATABASE_TOKEN=needs_to_be_set_but_it_can_be_anything
|
||||||
VOYAGE_API_KEY=your_actual_api_key_here
|
VOYAGE_API_KEY=your_actual_api_key_here
|
||||||
|
GITHUB_WEBHOOK_SECRET=some_secret
|
||||||
@@ -65,6 +65,7 @@
|
|||||||
"@sveltejs/mcp-schema": "workspace:^",
|
"@sveltejs/mcp-schema": "workspace:^",
|
||||||
"@sveltejs/mcp-server": "workspace:^",
|
"@sveltejs/mcp-server": "workspace:^",
|
||||||
"@tmcp/transport-http": "^0.6.3",
|
"@tmcp/transport-http": "^0.6.3",
|
||||||
"tmcp": "^1.14.0"
|
"tmcp": "^1.14.0",
|
||||||
|
"valibot": "^1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
apps/mcp-remote/src/lib/schemas/index.ts
Normal file
32
apps/mcp-remote/src/lib/schemas/index.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import * as v from 'valibot';
|
||||||
|
|
||||||
|
// not the full schema but it contains the information we need
|
||||||
|
export const github_webhook_schema = v.object({
|
||||||
|
action: v.union([v.literal('closed')]),
|
||||||
|
pull_request: v.object({
|
||||||
|
patch_url: v.string(),
|
||||||
|
merged: v.boolean(),
|
||||||
|
user: v.object({
|
||||||
|
login: v.string(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const github_content_schema = v.object({
|
||||||
|
name: v.string(),
|
||||||
|
path: v.string(),
|
||||||
|
sha: v.string(),
|
||||||
|
size: v.number(),
|
||||||
|
url: v.string(),
|
||||||
|
html_url: v.string(),
|
||||||
|
git_url: v.string(),
|
||||||
|
download_url: v.nullable(v.string()),
|
||||||
|
type: v.literal('file'),
|
||||||
|
content: v.string(),
|
||||||
|
encoding: v.literal('base64'),
|
||||||
|
_links: v.object({
|
||||||
|
self: v.string(),
|
||||||
|
git: v.string(),
|
||||||
|
html: v.string(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
54
apps/mcp-remote/src/routes/webhooks/docs/+server.ts
Normal file
54
apps/mcp-remote/src/routes/webhooks/docs/+server.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { github_content_schema, github_webhook_schema } from '$lib/schemas/index.js';
|
||||||
|
import * as v from 'valibot';
|
||||||
|
|
||||||
|
export async function POST({ request, fetch }) {
|
||||||
|
const body = await request.json();
|
||||||
|
// TODO add secret validation
|
||||||
|
const validated_pull_request = v.safeParse(github_webhook_schema, body);
|
||||||
|
if (!validated_pull_request.success) {
|
||||||
|
return new Response('Invalid payload', { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { pull_request } = validated_pull_request.output;
|
||||||
|
|
||||||
|
if (!pull_request.merged) {
|
||||||
|
return new Response(null, { status: 204 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const patch = await fetch(pull_request.patch_url);
|
||||||
|
if (!patch.ok) {
|
||||||
|
return new Response('Failed to fetch patch', { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const patch_text = await patch.text();
|
||||||
|
const files = [
|
||||||
|
...patch_text.matchAll(
|
||||||
|
/^diff --git\sa\/(?<file>.+?)\sb\/\1\n(?:(?<action>deleted|new)\sfile mode)?/gm,
|
||||||
|
),
|
||||||
|
].map((res) => ({ file: res.groups!.file, action: res.groups?.action ?? 'modified' }));
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
if (file.action === 'deleted') {
|
||||||
|
// delete path from db
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const new_file_content = await fetch(
|
||||||
|
`https://api.github.com/repos/sveltejs/svelte.dev/contents/${file.file}`,
|
||||||
|
);
|
||||||
|
if (!new_file_content.ok) {
|
||||||
|
// push file in queue and try again later?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const new_file_json = await new_file_content.json();
|
||||||
|
const validated_content = v.safeParse(github_content_schema, new_file_json);
|
||||||
|
if (!validated_content.success) {
|
||||||
|
// push file in queue and try again later?
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const content = Buffer.from(validated_content.output.content, 'base64').toString('utf-8');
|
||||||
|
// save content and distilled content in the db
|
||||||
|
console.log({ content, file: file.file });
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(null, { status: 204 });
|
||||||
|
}
|
||||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -62,6 +62,9 @@ importers:
|
|||||||
tmcp:
|
tmcp:
|
||||||
specifier: ^1.14.0
|
specifier: ^1.14.0
|
||||||
version: 1.14.0(typescript@5.9.2)
|
version: 1.14.0(typescript@5.9.2)
|
||||||
|
valibot:
|
||||||
|
specifier: ^1.1.0
|
||||||
|
version: 1.1.0(typescript@5.9.2)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@eslint/compat':
|
'@eslint/compat':
|
||||||
specifier: ^1.3.2
|
specifier: ^1.3.2
|
||||||
|
|||||||
Reference in New Issue
Block a user