Skip to main content
Glama
prompt-manager.ts9.12 kB
/** * VibeCoding Prompt 管理系統 * 負責載入、組合和管理所有 MCP 服務的 prompts */ import { readFile } from 'fs/promises'; import { join } from 'path'; // Prompt 類型定義 export interface PromptConfig { serviceId: string; serviceName: string; corePrompts: string[]; servicePrompt: string; workflowPrompts?: string[]; customPrompts?: string[]; } export interface CombinedPrompt { systemIdentity: string; serviceRole: string; workflowContext: string; fullPrompt: string; metadata: { serviceId: string; phase?: string; version: string; loadedAt: Date; }; } // 服務 ID 枚舉 export enum ServiceId { CONTEXT_MANAGER = 'context-manager', CODE_GENERATOR = 'code-generator', DEPENDENCY_TRACKER = 'dependency-tracker', TEST_VALIDATOR = 'test-validator', DOC_GENERATOR = 'doc-generator', DEPLOYMENT_MANAGER = 'deployment-manager' } // 開發階段枚舉 export enum DevelopmentPhase { DISCOVERY = 'discovery', DESIGN = 'design', IMPLEMENTATION = 'implementation', VALIDATION = 'validation', DEPLOYMENT = 'deployment' } export class PromptManager { private promptsBasePath: string; private promptCache = new Map<string, string>(); private combinedPromptCache = new Map<string, CombinedPrompt>(); constructor(promptsBasePath: string = '.vibecoding/prompts') { this.promptsBasePath = promptsBasePath; } /** * 載入單個 prompt 文件 */ async loadPrompt(promptPath: string): Promise<string> { const cacheKey = promptPath; if (this.promptCache.has(cacheKey)) { return this.promptCache.get(cacheKey)!; } try { const fullPath = join(process.cwd(), this.promptsBasePath, promptPath); const content = await readFile(fullPath, 'utf-8'); this.promptCache.set(cacheKey, content); return content; } catch (error) { console.warn(`Failed to load prompt: ${promptPath}`, error); return `# Prompt not found: ${promptPath}\n\nPlease ensure the prompt file exists.`; } } /** * 為特定服務組合完整的 prompt */ async buildServicePrompt( serviceId: ServiceId, phase?: DevelopmentPhase, customContext?: Record<string, any> ): Promise<CombinedPrompt> { const cacheKey = `${serviceId}-${phase || 'default'}-${JSON.stringify(customContext)}`; if (this.combinedPromptCache.has(cacheKey)) { return this.combinedPromptCache.get(cacheKey)!; } try { // 載入核心 prompts const systemIdentity = await this.loadPrompt('core/system-identity.md'); const conversationStyle = await this.loadPrompt('core/conversation-style.md'); const collaborationRules = await this.loadPrompt('core/collaboration-rules.md'); // 載入服務專用 prompt const servicePrompt = await this.loadPrompt(`services/${serviceId}.md`); // 載入階段相關 prompt (如果指定) let workflowContext = ''; if (phase) { workflowContext = await this.loadPrompt(`workflows/${phase}-phase.md`); } // 組合完整 prompt const fullPrompt = this.combinePrompts({ systemIdentity, conversationStyle, collaborationRules, servicePrompt, workflowContext, customContext }); const combinedPrompt: CombinedPrompt = { systemIdentity, serviceRole: servicePrompt, workflowContext, fullPrompt, metadata: { serviceId, phase, version: '1.0.0', loadedAt: new Date() } }; this.combinedPromptCache.set(cacheKey, combinedPrompt); return combinedPrompt; } catch (error) { console.error(`Failed to build prompt for service ${serviceId}:`, error); throw new Error(`Prompt building failed for service: ${serviceId}`); } } /** * 組合多個 prompt 為完整的系統 prompt */ private combinePrompts(components: { systemIdentity: string; conversationStyle: string; collaborationRules: string; servicePrompt: string; workflowContext: string; customContext?: Record<string, any>; }): string { const { systemIdentity, conversationStyle, collaborationRules, servicePrompt, workflowContext, customContext } = components; let combinedPrompt = `# VibeCoding 系統 Prompt ## 🎯 系統身份和核心理念 ${systemIdentity} ## 🎪 對話風格指南 ${conversationStyle} ## 🤝 服務協作規則 ${collaborationRules} ## 🛠️ 服務專用職責和指導 ${servicePrompt} `; // 添加階段特定上下文 if (workflowContext) { combinedPrompt += ` ## 📋 當前階段工作流程 ${workflowContext} `; } // 添加自定義上下文 if (customContext) { combinedPrompt += ` ## 🔧 自定義上下文 ${JSON.stringify(customContext, null, 2)} `; } combinedPrompt += ` --- **重要提醒**: 始終遵循以上所有指導原則,確保提供一致、高質量的 VibeCoding 體驗。 `; return combinedPrompt; } /** * 獲取所有可用的服務 prompts */ async getAvailableServices(): Promise<ServiceId[]> { return Object.values(ServiceId); } /** * 獲取所有可用的開發階段 */ async getAvailablePhases(): Promise<DevelopmentPhase[]> { return Object.values(DevelopmentPhase); } /** * 清除 prompt 緩存 */ clearCache(): void { this.promptCache.clear(); this.combinedPromptCache.clear(); } /** * 重新載入指定服務的 prompt */ async reloadServicePrompt(serviceId: ServiceId): Promise<void> { // 清除相關緩存 const keysToDelete = Array.from(this.combinedPromptCache.keys()) .filter(key => key.startsWith(serviceId)); keysToDelete.forEach(key => this.combinedPromptCache.delete(key)); // 清除服務 prompt 文件緩存 this.promptCache.delete(`services/${serviceId}.md`); } /** * 驗證 prompt 配置 */ async validatePrompts(): Promise<{ valid: boolean; errors: string[] }> { const errors: string[] = []; try { // 檢查核心 prompts const corePrompts = [ 'core/system-identity.md', 'core/conversation-style.md', 'core/collaboration-rules.md' ]; for (const promptPath of corePrompts) { const content = await this.loadPrompt(promptPath); if (content.includes('Prompt not found')) { errors.push(`Missing core prompt: ${promptPath}`); } } // 檢查服務 prompts for (const serviceId of Object.values(ServiceId)) { const content = await this.loadPrompt(`services/${serviceId}.md`); if (content.includes('Prompt not found')) { errors.push(`Missing service prompt: ${serviceId}`); } } return { valid: errors.length === 0, errors }; } catch (error) { errors.push(`Validation failed: ${error}`); return { valid: false, errors }; } } } // 全局 prompt manager 實例 export const promptManager = new PromptManager(); /** * 便利函數:為 MCP 服務快速構建 prompt */ export async function buildMCPServicePrompt( serviceId: ServiceId, phase?: DevelopmentPhase, customContext?: Record<string, any> ): Promise<string> { const combinedPrompt = await promptManager.buildServicePrompt(serviceId, phase, customContext); return combinedPrompt.fullPrompt; } /** * 便利函數:獲取服務的基本角色 prompt */ export async function getServiceRolePrompt(serviceId: ServiceId): Promise<string> { return await promptManager.loadPrompt(`services/${serviceId}.md`); } /** * 便利函數:獲取階段特定的工作流程 prompt */ export async function getPhaseWorkflowPrompt(phase: DevelopmentPhase): Promise<string> { return await promptManager.loadPrompt(`workflows/${phase}-phase.md`); } /** * MCP 服務初始化時使用的 prompt 配置 */ export class MCPServicePromptConfig { constructor( public serviceId: ServiceId, public defaultPhase?: DevelopmentPhase, public customPrompts: string[] = [] ) {} async getFullPrompt( currentPhase?: DevelopmentPhase, context?: Record<string, any> ): Promise<string> { const phase = currentPhase || this.defaultPhase; return await buildMCPServicePrompt(this.serviceId, phase, context); } } // 預定義的服務配置 export const MCP_SERVICE_CONFIGS = { [ServiceId.CONTEXT_MANAGER]: new MCPServicePromptConfig(ServiceId.CONTEXT_MANAGER), [ServiceId.CODE_GENERATOR]: new MCPServicePromptConfig(ServiceId.CODE_GENERATOR, DevelopmentPhase.IMPLEMENTATION), [ServiceId.DEPENDENCY_TRACKER]: new MCPServicePromptConfig(ServiceId.DEPENDENCY_TRACKER), [ServiceId.TEST_VALIDATOR]: new MCPServicePromptConfig(ServiceId.TEST_VALIDATOR, DevelopmentPhase.VALIDATION), [ServiceId.DOC_GENERATOR]: new MCPServicePromptConfig(ServiceId.DOC_GENERATOR), [ServiceId.DEPLOYMENT_MANAGER]: new MCPServicePromptConfig(ServiceId.DEPLOYMENT_MANAGER, DevelopmentPhase.DEPLOYMENT) };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Zenobia000/vibeCoding-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server