@promptui-lib/mcp-agent 0.1.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/bin/agent.js +8 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +1 -0
- package/dist/config/load-config.d.ts +24 -0
- package/dist/config/load-config.d.ts.map +1 -0
- package/dist/config/load-config.js +98 -0
- package/dist/handlers/generate-handler.d.ts +16 -0
- package/dist/handlers/generate-handler.d.ts.map +1 -0
- package/dist/handlers/generate-handler.js +90 -0
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/server/http-server.d.ts +19 -0
- package/dist/server/http-server.d.ts.map +1 -0
- package/dist/server/http-server.js +110 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +1 -0
- package/package.json +52 -0
package/bin/agent.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { loadConfig, resolveConfig, validateConfig } from './load-config.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Loader
|
|
3
|
+
* Carrega configuração do projeto
|
|
4
|
+
*/
|
|
5
|
+
import type { IPromptUIConfig } from '@promptui-lib/core';
|
|
6
|
+
export interface IResolvedConfig {
|
|
7
|
+
figmaToken: string;
|
|
8
|
+
figmaFileId: string;
|
|
9
|
+
outputBasePath: string;
|
|
10
|
+
port: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Carrega configuração do projeto
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadConfig(cwd?: string): Promise<IPromptUIConfig | null>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve configuração com valores padrão e env vars
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveConfig(config: IPromptUIConfig | null, envOverrides?: Partial<IResolvedConfig>): IResolvedConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Valida configuração resolvida
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateConfig(config: IResolvedConfig): string[];
|
|
24
|
+
//# sourceMappingURL=load-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/config/load-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAS1D,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAuCD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQjC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,GAAG,IAAI,EAC9B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACtC,eAAe,CA+BjB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAYhE"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Loader
|
|
3
|
+
* Carrega configuração do projeto
|
|
4
|
+
*/
|
|
5
|
+
import { readFile, access } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
const CONFIG_FILES = [
|
|
8
|
+
'promptui.config.json',
|
|
9
|
+
'promptui.config.js',
|
|
10
|
+
'.promptuirc',
|
|
11
|
+
'.promptuirc.json',
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Verifica se arquivo existe
|
|
15
|
+
*/
|
|
16
|
+
async function fileExists(path) {
|
|
17
|
+
try {
|
|
18
|
+
await access(path);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Carrega configuração de um arquivo JSON
|
|
27
|
+
*/
|
|
28
|
+
async function loadJsonConfig(path) {
|
|
29
|
+
try {
|
|
30
|
+
const content = await readFile(path, 'utf-8');
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Busca arquivo de configuração no diretório
|
|
39
|
+
*/
|
|
40
|
+
async function findConfigFile(dir) {
|
|
41
|
+
for (const file of CONFIG_FILES) {
|
|
42
|
+
const path = join(dir, file);
|
|
43
|
+
if (await fileExists(path)) {
|
|
44
|
+
return path;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Carrega configuração do projeto
|
|
51
|
+
*/
|
|
52
|
+
export async function loadConfig(cwd = process.cwd()) {
|
|
53
|
+
const configPath = await findConfigFile(cwd);
|
|
54
|
+
if (!configPath) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return loadJsonConfig(configPath);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolve configuração com valores padrão e env vars
|
|
61
|
+
*/
|
|
62
|
+
export function resolveConfig(config, envOverrides) {
|
|
63
|
+
// Prioridade: env vars > config file > defaults
|
|
64
|
+
const figmaToken = envOverrides?.figmaToken ??
|
|
65
|
+
process.env.FIGMA_TOKEN ??
|
|
66
|
+
config?.figma?.token ??
|
|
67
|
+
'';
|
|
68
|
+
const figmaFileId = envOverrides?.figmaFileId ??
|
|
69
|
+
process.env.FIGMA_FILE_ID ??
|
|
70
|
+
config?.figma?.fileId ??
|
|
71
|
+
'';
|
|
72
|
+
const outputBasePath = envOverrides?.outputBasePath ??
|
|
73
|
+
process.env.PROMPTUI_OUTPUT_PATH ??
|
|
74
|
+
config?.output?.basePath ??
|
|
75
|
+
'src/components';
|
|
76
|
+
const port = envOverrides?.port ??
|
|
77
|
+
(process.env.PROMPTUI_PORT ? parseInt(process.env.PROMPTUI_PORT, 10) : null) ??
|
|
78
|
+
17890;
|
|
79
|
+
return {
|
|
80
|
+
figmaToken,
|
|
81
|
+
figmaFileId,
|
|
82
|
+
outputBasePath,
|
|
83
|
+
port,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Valida configuração resolvida
|
|
88
|
+
*/
|
|
89
|
+
export function validateConfig(config) {
|
|
90
|
+
const errors = [];
|
|
91
|
+
if (!config.figmaToken) {
|
|
92
|
+
errors.push('Missing FIGMA_TOKEN. Set via environment variable or config file.');
|
|
93
|
+
}
|
|
94
|
+
if (!config.figmaFileId) {
|
|
95
|
+
errors.push('Missing FIGMA_FILE_ID. Set via environment variable or config file.');
|
|
96
|
+
}
|
|
97
|
+
return errors;
|
|
98
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Handler
|
|
3
|
+
* Orquestra o pipeline de geração: Figma → Parser → Codegen → Files
|
|
4
|
+
*/
|
|
5
|
+
import type { IGenerateRequest, IGenerateResponse } from '@promptui-lib/core';
|
|
6
|
+
export interface IGenerateHandlerOptions {
|
|
7
|
+
request: IGenerateRequest;
|
|
8
|
+
figmaToken: string;
|
|
9
|
+
figmaFileId: string;
|
|
10
|
+
outputBasePath: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Handler principal de geração
|
|
14
|
+
*/
|
|
15
|
+
export declare function handleGenerate(options: IGenerateHandlerOptions): Promise<IGenerateResponse>;
|
|
16
|
+
//# sourceMappingURL=generate-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/generate-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAK9E,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CA6F5B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate Handler
|
|
3
|
+
* Orquestra o pipeline de geração: Figma → Parser → Codegen → Files
|
|
4
|
+
*/
|
|
5
|
+
import { createFigmaClient } from '@promptui-lib/figma-parser';
|
|
6
|
+
import { parseNode } from '@promptui-lib/figma-parser';
|
|
7
|
+
import { writeComponent, generateCode } from '@promptui-lib/codegen';
|
|
8
|
+
/**
|
|
9
|
+
* Handler principal de geração
|
|
10
|
+
*/
|
|
11
|
+
export async function handleGenerate(options) {
|
|
12
|
+
const { request, figmaToken, figmaFileId, outputBasePath } = options;
|
|
13
|
+
const errors = [];
|
|
14
|
+
const warnings = [];
|
|
15
|
+
try {
|
|
16
|
+
console.log(`[PromptUI] Generating component for node: ${request.nodeId}`);
|
|
17
|
+
// 1. Busca node do Figma
|
|
18
|
+
const figmaClient = createFigmaClient({ token: figmaToken });
|
|
19
|
+
const fileId = request.fileId ?? figmaFileId;
|
|
20
|
+
const node = await figmaClient.getNode(fileId, request.nodeId);
|
|
21
|
+
if (!node) {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
componentName: '',
|
|
25
|
+
layer: 'atoms',
|
|
26
|
+
files: { tsx: '', scss: '', index: '' },
|
|
27
|
+
outputPath: '',
|
|
28
|
+
errors: [`Node not found: ${request.nodeId}`],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
console.log(`[PromptUI] Found node: ${node.name} (${node.type})`);
|
|
32
|
+
// 2. Parseia node para AST
|
|
33
|
+
const ast = parseNode(node, {
|
|
34
|
+
forceLayer: request.options?.layer,
|
|
35
|
+
componentName: request.options?.componentName,
|
|
36
|
+
});
|
|
37
|
+
console.log(`[PromptUI] Parsed: ${ast.name} (${ast.layer})`);
|
|
38
|
+
// 3. Se é preview, retorna apenas o código
|
|
39
|
+
if (request.options?.preview) {
|
|
40
|
+
const code = generateCode(ast);
|
|
41
|
+
return {
|
|
42
|
+
success: true,
|
|
43
|
+
componentName: ast.name,
|
|
44
|
+
layer: ast.layer,
|
|
45
|
+
files: { tsx: '', scss: '', index: '' },
|
|
46
|
+
outputPath: '',
|
|
47
|
+
code,
|
|
48
|
+
warnings,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// 4. Escreve arquivos
|
|
52
|
+
const basePath = request.outputPath ?? outputBasePath;
|
|
53
|
+
const writeResult = await writeComponent(ast, {
|
|
54
|
+
basePath,
|
|
55
|
+
forceOverwrite: request.options?.forceOverwrite,
|
|
56
|
+
});
|
|
57
|
+
if (!writeResult.success) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
componentName: ast.name,
|
|
61
|
+
layer: ast.layer,
|
|
62
|
+
files: writeResult.files,
|
|
63
|
+
outputPath: basePath,
|
|
64
|
+
errors: writeResult.errors,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
console.log(`[PromptUI] Generated: ${writeResult.files.tsx}`);
|
|
68
|
+
return {
|
|
69
|
+
success: true,
|
|
70
|
+
componentName: ast.name,
|
|
71
|
+
layer: ast.layer,
|
|
72
|
+
files: writeResult.files,
|
|
73
|
+
outputPath: basePath,
|
|
74
|
+
warnings,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
79
|
+
errors.push(message);
|
|
80
|
+
console.error(`[PromptUI] Error:`, message);
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
componentName: '',
|
|
84
|
+
layer: 'atoms',
|
|
85
|
+
files: { tsx: '', scss: '', index: '' },
|
|
86
|
+
outputPath: '',
|
|
87
|
+
errors,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handlers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { handleGenerate } from './generate-handler.js';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @promptui-lib/mcp-agent
|
|
3
|
+
* MCP Agent server for PromptUI
|
|
4
|
+
*/
|
|
5
|
+
export * from './server/index.js';
|
|
6
|
+
export * from './handlers/index.js';
|
|
7
|
+
export * from './config/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Inicia o agente MCP
|
|
10
|
+
*/
|
|
11
|
+
export declare function startAgent(): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAElC;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAkDhD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @promptui-lib/mcp-agent
|
|
3
|
+
* MCP Agent server for PromptUI
|
|
4
|
+
*/
|
|
5
|
+
import { createHttpServer } from './server/index.js';
|
|
6
|
+
import { loadConfig, resolveConfig, validateConfig } from './config/index.js';
|
|
7
|
+
export * from './server/index.js';
|
|
8
|
+
export * from './handlers/index.js';
|
|
9
|
+
export * from './config/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Inicia o agente MCP
|
|
12
|
+
*/
|
|
13
|
+
export async function startAgent() {
|
|
14
|
+
console.log('[PromptUI] Starting agent...');
|
|
15
|
+
// Carrega configuração
|
|
16
|
+
const config = await loadConfig();
|
|
17
|
+
const resolved = resolveConfig(config);
|
|
18
|
+
// Valida configuração
|
|
19
|
+
const errors = validateConfig(resolved);
|
|
20
|
+
if (errors.length > 0) {
|
|
21
|
+
console.error('[PromptUI] Configuration errors:');
|
|
22
|
+
for (const error of errors) {
|
|
23
|
+
console.error(` - ${error}`);
|
|
24
|
+
}
|
|
25
|
+
console.error('\n[PromptUI] Create a promptui.config.json or set environment variables.');
|
|
26
|
+
console.error('Example config:');
|
|
27
|
+
console.error(JSON.stringify({
|
|
28
|
+
figma: {
|
|
29
|
+
token: 'your-figma-token',
|
|
30
|
+
fileId: 'your-file-id'
|
|
31
|
+
},
|
|
32
|
+
output: {
|
|
33
|
+
basePath: 'src/components'
|
|
34
|
+
}
|
|
35
|
+
}, null, 2));
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Cria e inicia servidor
|
|
39
|
+
const server = createHttpServer({
|
|
40
|
+
port: resolved.port,
|
|
41
|
+
figmaToken: resolved.figmaToken,
|
|
42
|
+
figmaFileId: resolved.figmaFileId,
|
|
43
|
+
outputBasePath: resolved.outputBasePath,
|
|
44
|
+
});
|
|
45
|
+
await server.start();
|
|
46
|
+
// Handle graceful shutdown
|
|
47
|
+
process.on('SIGINT', async () => {
|
|
48
|
+
console.log('\n[PromptUI] Shutting down...');
|
|
49
|
+
await server.stop();
|
|
50
|
+
process.exit(0);
|
|
51
|
+
});
|
|
52
|
+
process.on('SIGTERM', async () => {
|
|
53
|
+
console.log('\n[PromptUI] Shutting down...');
|
|
54
|
+
await server.stop();
|
|
55
|
+
process.exit(0);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Server
|
|
3
|
+
* Expõe API REST para comunicação com o Figma Plugin
|
|
4
|
+
*/
|
|
5
|
+
export interface IServerConfig {
|
|
6
|
+
port: number;
|
|
7
|
+
figmaToken: string;
|
|
8
|
+
figmaFileId: string;
|
|
9
|
+
outputBasePath: string;
|
|
10
|
+
}
|
|
11
|
+
export interface IHttpServer {
|
|
12
|
+
start(): Promise<void>;
|
|
13
|
+
stop(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Cria o servidor HTTP
|
|
17
|
+
*/
|
|
18
|
+
export declare function createHttpServer(config: IServerConfig): IHttpServer;
|
|
19
|
+
//# sourceMappingURL=http-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../../src/server/http-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAsCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CA2EnE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Server
|
|
3
|
+
* Expõe API REST para comunicação com o Figma Plugin
|
|
4
|
+
*/
|
|
5
|
+
import { createServer } from 'node:http';
|
|
6
|
+
import { parse as parseUrl } from 'node:url';
|
|
7
|
+
import { handleGenerate } from '../handlers/generate-handler.js';
|
|
8
|
+
/**
|
|
9
|
+
* Parseia body JSON de uma request
|
|
10
|
+
*/
|
|
11
|
+
async function parseBody(req) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
let body = '';
|
|
14
|
+
req.on('data', (chunk) => {
|
|
15
|
+
body += chunk.toString();
|
|
16
|
+
});
|
|
17
|
+
req.on('end', () => {
|
|
18
|
+
try {
|
|
19
|
+
resolve(JSON.parse(body));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
reject(new Error('Invalid JSON body'));
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
req.on('error', reject);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Envia resposta JSON
|
|
30
|
+
*/
|
|
31
|
+
function sendJson(res, status, data) {
|
|
32
|
+
res.writeHead(status, {
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
'Access-Control-Allow-Origin': '*',
|
|
35
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
36
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
37
|
+
});
|
|
38
|
+
res.end(JSON.stringify(data));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Cria o servidor HTTP
|
|
42
|
+
*/
|
|
43
|
+
export function createHttpServer(config) {
|
|
44
|
+
const server = createServer(async (req, res) => {
|
|
45
|
+
const { pathname } = parseUrl(req.url ?? '/', true);
|
|
46
|
+
const method = req.method ?? 'GET';
|
|
47
|
+
// CORS preflight
|
|
48
|
+
if (method === 'OPTIONS') {
|
|
49
|
+
res.writeHead(204, {
|
|
50
|
+
'Access-Control-Allow-Origin': '*',
|
|
51
|
+
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
|
|
52
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
53
|
+
});
|
|
54
|
+
res.end();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
// Health check
|
|
59
|
+
if (pathname === '/health' && method === 'GET') {
|
|
60
|
+
sendJson(res, 200, { status: 'ok', version: '0.1.0' });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Generate component
|
|
64
|
+
if (pathname === '/generate' && method === 'POST') {
|
|
65
|
+
const body = await parseBody(req);
|
|
66
|
+
const result = await handleGenerate({
|
|
67
|
+
request: body,
|
|
68
|
+
figmaToken: config.figmaToken,
|
|
69
|
+
figmaFileId: config.figmaFileId,
|
|
70
|
+
outputBasePath: config.outputBasePath,
|
|
71
|
+
});
|
|
72
|
+
sendJson(res, result.success ? 200 : 400, result);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// List available frames
|
|
76
|
+
if (pathname === '/frames' && method === 'GET') {
|
|
77
|
+
// TODO: implementar listagem de frames
|
|
78
|
+
sendJson(res, 200, { frames: [] });
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// 404
|
|
82
|
+
sendJson(res, 404, { error: 'Not found' });
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
86
|
+
console.error('[PromptUI] Error:', message);
|
|
87
|
+
sendJson(res, 500, { error: message });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
start: () => new Promise((resolve) => {
|
|
92
|
+
server.listen(config.port, () => {
|
|
93
|
+
console.log(`[PromptUI] Agent running at http://localhost:${config.port}`);
|
|
94
|
+
console.log('[PromptUI] Endpoints:');
|
|
95
|
+
console.log(` GET /health - Health check`);
|
|
96
|
+
console.log(` POST /generate - Generate component from Figma node`);
|
|
97
|
+
console.log(` GET /frames - List available frames`);
|
|
98
|
+
resolve();
|
|
99
|
+
});
|
|
100
|
+
}),
|
|
101
|
+
stop: () => new Promise((resolve, reject) => {
|
|
102
|
+
server.close((err) => {
|
|
103
|
+
if (err)
|
|
104
|
+
reject(err);
|
|
105
|
+
else
|
|
106
|
+
resolve();
|
|
107
|
+
});
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createHttpServer } from './http-server.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@promptui-lib/mcp-agent",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "MCP Agent server for PromptUI - bridges Figma Plugin to code generation",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Desiree Menezes",
|
|
9
|
+
"url": "https://github.com/desireemenezes"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/desireemenezes/promptUI.git",
|
|
14
|
+
"directory": "packages/mcp-agent"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/desireemenezes/promptUI#readme",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"bin": {
|
|
21
|
+
"promptui-agent": "./bin/agent.js"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"bin"
|
|
35
|
+
],
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@promptui-lib/core": "0.1.0",
|
|
38
|
+
"@promptui-lib/figma-parser": "0.1.0",
|
|
39
|
+
"@promptui-lib/codegen": "0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^20.0.0",
|
|
43
|
+
"typescript": "^5.3.0",
|
|
44
|
+
"rimraf": "^5.0.0"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc",
|
|
48
|
+
"dev": "tsc --watch",
|
|
49
|
+
"start": "node dist/index.js",
|
|
50
|
+
"clean": "rimraf dist"
|
|
51
|
+
}
|
|
52
|
+
}
|