Commit f163640a authored by Pham Tuan's avatar Pham Tuan

Main

parent 045c1da9
export interface ProjectContext {
framework: "react";
language: "ts" | "js";
hasPackageJson: boolean;
}
export declare function inferProjectContext(): ProjectContext;
import fs from "fs";
import path from "path";
export function inferProjectContext() {
const hasPackageJson = fs.existsSync(path.join(process.cwd(), "package.json"));
return {
framework: "react",
language: "ts",
hasPackageJson,
};
}
import { UIIntent } from "./intent.core.js";
export declare function generateReactCode(intent: UIIntent): string;
export declare function generateReactCode(intent: UIIntent): {
code: string;
};
export function generateReactCode(intent) {
return `import { ${intent.components.join(", ")} } from 'awing-library'
const code = `import { ${intent.components.join(", ")} } from 'awing-library'
// ${intent.description}
export default function GeneratedUI() {
return (
<div>
${intent.components.map((c) => `<${c} />`).join("\n ")}
</div>
${intent.components.map((c) => `<${c} />`).join("\n ")}<
/div>
)
}`;
return { code };
}
#!/usr/bin/env node
export {};
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { tools, executeTool } from './tools/index.js';
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
import { tools, executeTool } from "./tools/index.js";
// Create MCP server
const server = new Server({
name: 'ui-platform-mcp',
version: '1.0.0'
name: "ui-platform-mcp",
version: "1.0.0",
}, {
capabilities: {
tools: {}
}
tools: {},
},
});
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: tools
tools: tools,
};
});
// Handle tool calls
......@@ -25,10 +26,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
}
catch (error) {
......@@ -36,11 +37,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
return {
content: [
{
type: 'text',
text: `Error: ${errorMessage}`
}
type: "text",
text: `Error: ${errorMessage}`,
},
],
isError: true
isError: true,
};
}
});
......@@ -48,9 +49,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('UI Platform MCP Server running on stdio');
console.error("UI Platform MCP Server running on stdio");
}
main().catch((error) => {
console.error('Server error:', error);
console.error("Server error:", error);
process.exit(1);
});
export declare const generateUICodeTool: {
name: string;
run(input: any): string;
run(input: any): {
code: string;
};
};
export default {
preset: "ts-jest/presets/default-esm",
testEnvironment: "node",
extensionsToTreatAsEsm: [".ts"],
roots: ["<rootDir>/src", "<rootDir>/tests"],
testMatch: ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"],
transform: {
"^.+\\.ts$": [
"ts-jest",
{
useESM: true,
},
],
},
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts"],
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
};
This diff is collapsed.
......@@ -12,6 +12,8 @@
],
"scripts": {
"build": "tsc",
"test": "jest",
"test:watch": "jest --watch",
"prepublishOnly": "npm run build",
"start": "node dist/index.js",
"dev": "tsx src/index.ts"
......@@ -20,7 +22,10 @@
"@modelcontextprotocol/sdk": "^1.0.0"
},
"devDependencies": {
"@types/jest": "^30.0.0",
"@types/node": "^22.0.0",
"jest": "^30.2.0",
"ts-jest": "^29.4.6",
"tsx": "^4.0.0",
"typescript": "^5.6.0"
},
......
import fs from "fs";
import path from "path";
export interface ProjectContext {
framework: "react";
language: "ts" | "js";
hasPackageJson: boolean;
}
export function inferProjectContext(): ProjectContext {
const hasPackageJson = fs.existsSync(
path.join(process.cwd(), "package.json"),
);
return {
framework: "react",
language: "ts",
hasPackageJson,
};
}
import { UIIntent } from "./intent.core.js";
export function generateReactCode(intent: UIIntent): string {
return `import { ${intent.components.join(", ")} } from 'awing-library'
export function generateReactCode(intent: UIIntent): { code: string } {
const code = `import { ${intent.components.join(", ")} } from 'awing-library'
// ${intent.description}
export default function GeneratedUI() {
return (
<div>
${intent.components.map((c) => `<${c} />`).join("\n ")}
</div>
${intent.components.map((c) => `<${c} />`).join("\n ")}<
/div>
)
}`;
return { code };
}
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
import { tools, executeTool } from './tools/index.js'
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { tools, executeTool } from "./tools/index.js";
// Create MCP server
const server = new Server(
{
name: 'ui-platform-mcp',
version: '1.0.0'
name: "ui-platform-mcp",
version: "1.0.0",
},
{
capabilities: {
tools: {}
}
}
)
tools: {},
},
},
);
// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: tools
}
})
tools: tools,
};
});
// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params
const { name, arguments: args } = request.params;
try {
const result = await executeTool(name, args as Record<string, unknown>)
const result = await executeTool(name, args as Record<string, unknown>);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2)
}
]
}
type: "text",
text: JSON.stringify(result, null, 2),
},
],
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [
{
type: 'text',
text: `Error: ${errorMessage}`
}
type: "text",
text: `Error: ${errorMessage}`,
},
],
isError: true
}
isError: true,
};
}
})
});
// Start the server
async function main() {
const transport = new StdioServerTransport()
await server.connect(transport)
console.error('UI Platform MCP Server running on stdio')
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("UI Platform MCP Server running on stdio");
}
main().catch((error) => {
console.error('Server error:', error)
process.exit(1)
})
console.error("Server error:", error);
process.exit(1);
});
import { generateReactCode } from "../src/core/codegen.core.js";
import { UIIntent } from "../src/core/intent.core.js";
describe("Code Generator", () => {
it("should generate code with Button component", () => {
const intent: UIIntent = {
description: "A simple button",
components: ["Button"],
};
const result = generateReactCode(intent);
expect(result.code).toContain("import");
expect(result.code).toContain("Button");
expect(result.code).toContain("export");
});
it("should generate code with multiple components", () => {
const intent: UIIntent = {
description: "Button and Modal",
components: ["Button", "Modal"],
};
const result = generateReactCode(intent);
expect(result.code).toContain("Button");
expect(result.code).toContain("Modal");
});
it("should include description in code", () => {
const intent: UIIntent = {
description: "User profile form",
components: ["Form"],
};
const result = generateReactCode(intent);
expect(result.code).toContain("User profile form");
});
it("should return valid React component structure", () => {
const intent: UIIntent = {
description: "Test component",
components: ["Button"],
};
const result = generateReactCode(intent);
expect(result.code).toMatch(/export\s+(default\s+)?function/);
});
});
import { parseUIIntent } from "../src/core/intent.core.js";
describe("Intent Parser", () => {
it("should parse button intent", () => {
const result = parseUIIntent("Create a button");
expect(result.description).toBe("Create a button");
expect(result.components).toContain("Button");
});
it("should parse modal intent", () => {
const result = parseUIIntent("Show a modal dialog");
expect(result.description).toBe("Show a modal dialog");
expect(result.components).toContain("Modal");
});
it("should parse multiple components", () => {
const result = parseUIIntent("Create a button that opens a modal");
expect(result.components).toContain("Button");
expect(result.components).toContain("Modal");
expect(result.components).toHaveLength(2);
});
it("should return empty components for unknown intent", () => {
const result = parseUIIntent("Something random");
expect(result.components).toHaveLength(0);
});
it("should be case insensitive", () => {
const result = parseUIIntent("CREATE A BUTTON");
expect(result.components).toContain("Button");
});
});
import { executeTool, tools } from "../src/tools/index.js";
describe("MCP Tools", () => {
describe("Tool Definitions", () => {
it("should have all required tools defined", () => {
const toolNames = tools.map((t) => t.name);
expect(toolNames).toContain("analyze_design_system");
expect(toolNames).toContain("analyze_storybook");
expect(toolNames).toContain("parse_ui_intent");
expect(toolNames).toContain("get_project_context");
expect(toolNames).toContain("generate_ui_code");
});
it("should have valid tool schemas", () => {
tools.forEach((tool) => {
expect(tool.name).toBeDefined();
expect(tool.description).toBeDefined();
expect(tool.inputSchema).toBeDefined();
expect(tool.inputSchema.type).toBe("object");
});
});
});
describe("executeTool", () => {
it("should throw error for unknown tool", async () => {
await expect(executeTool("unknown_tool", {})).rejects.toThrow(
"Unknown tool: unknown_tool",
);
});
it("should execute parse_ui_intent tool", async () => {
const result = await executeTool("parse_ui_intent", {
prompt: "Create a button and modal",
});
expect(result).toHaveProperty("description");
expect(result).toHaveProperty("components");
expect((result as any).components).toContain("Button");
expect((result as any).components).toContain("Modal");
});
it("should execute get_project_context tool", async () => {
const result = await executeTool("get_project_context", {});
expect(result).toHaveProperty("framework");
expect(result).toHaveProperty("hasPackageJson");
});
it("should execute generate_ui_code tool", async () => {
const result = await executeTool("generate_ui_code", {
description: "A simple button",
components: ["Button"],
});
expect(result).toHaveProperty("code");
expect((result as any).code).toContain("Button");
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment