Skip to main content
Glama

Memory Bank MCP Server

by yywdandan
projects.js18 kB
/** * Memory Bank 项目管理页面脚本 */ document.addEventListener('DOMContentLoaded', function() { // 当前项目ID let currentProjectId = null; let currentDocumentType = null; // API基础URL const API_BASE_URL = '/api'; // DOM元素 const projectsList = document.getElementById('projectsList'); const projectDetail = document.getElementById('projectDetail'); const projectName = document.getElementById('projectName'); const documentsList = document.getElementById('documentsList'); const documentTitle = document.getElementById('documentTitle'); const documentViewer = document.getElementById('documentViewer'); const documentEditor = document.getElementById('documentEditor'); const markdownEditor = document.getElementById('markdownEditor'); const documentActions = document.getElementById('documentActions'); // 初始化 loadProjects(); /** * 加载项目列表 */ function loadProjects() { fetch(`${API_BASE_URL}/projects`) .then(response => response.json()) .then(data => { if (data.success) { renderProjects(data.data); } else { showError('加载项目列表失败', data.error); } }) .catch(error => { showError('加载项目列表失败', error.message); }); } /** * 渲染项目列表 */ function renderProjects(projects) { // 清空项目列表 projectsList.innerHTML = ''; if (projects.length === 0) { projectsList.innerHTML = ` <tr> <td colspan="5" class="text-center py-4"> <p class="text-muted mb-0">暂无项目,请创建新项目</p> </td> </tr> `; return; } // 添加项目列表 projects.forEach(project => { const row = document.createElement('tr'); row.innerHTML = ` <td><strong>${project.name}</strong></td> <td>${project.description || '无描述'}</td> <td>${formatDate(project.createdAt)}</td> <td>${formatDate(project.updatedAt)}</td> <td> <button class="btn btn-sm btn-primary view-project" data-id="${project.id}">查看</button> </td> `; projectsList.appendChild(row); }); // 添加查看项目事件 document.querySelectorAll('.view-project').forEach(button => { button.addEventListener('click', function() { const projectId = this.getAttribute('data-id'); viewProject(projectId); }); }); } /** * 查看项目详情 */ function viewProject(projectId) { currentProjectId = projectId; // 获取项目详情 fetch(`${API_BASE_URL}/projects/${projectId}`) .then(response => response.json()) .then(data => { if (data.success) { const project = data.data; // 显示项目详情 projectName.textContent = project.name; // 显示项目详情页面 hideElement(projectDetail, false); // 加载项目文档 loadProjectDocuments(projectId); } else { showError('加载项目详情失败', data.error); } }) .catch(error => { showError('加载项目详情失败', error.message); }); } /** * 加载项目文档 */ function loadProjectDocuments(projectId) { fetch(`${API_BASE_URL}/projects/${projectId}/documents`) .then(response => response.json()) .then(data => { if (data.success) { renderDocuments(data.data); } else { showError('加载项目文档失败', data.error); } }) .catch(error => { showError('加载项目文档失败', error.message); }); } /** * 渲染文档列表 */ function renderDocuments(documents) { // 清空文档列表 documentsList.innerHTML = ''; if (documents.length === 0) { documentsList.innerHTML = '<p class="text-muted">暂无文档</p>'; return; } // 按文档类型重要性排序 const documentTypeOrder = { 'projectbrief': 1, 'tasks': 2, 'activeContext': 3, 'systemPatterns': 4, 'techContext': 5, 'progress': 6, 'reflections': 7 }; documents.sort((a, b) => { const orderA = documentTypeOrder[a.type] || 100; const orderB = documentTypeOrder[b.type] || 100; return orderA - orderB; }); // 添加文档列表 documents.forEach(doc => { const listItem = document.createElement('a'); listItem.href = '#'; listItem.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center'; listItem.setAttribute('data-type', doc.type); // 设置文档显示名称 let displayName = doc.name; if (doc.type === 'projectbrief') displayName = '项目概述'; if (doc.type === 'tasks') displayName = '任务清单'; if (doc.type === 'activeContext') displayName = '当前上下文'; if (doc.type === 'systemPatterns') displayName = '系统架构'; if (doc.type === 'techContext') displayName = '技术上下文'; if (doc.type === 'progress') displayName = '项目进度'; if (doc.type === 'reflections') displayName = '项目反思'; listItem.innerHTML = ` ${displayName} <span class="badge bg-secondary rounded-pill">${formatDate(doc.updatedAt, true)}</span> `; documentsList.appendChild(listItem); // 添加点击事件 listItem.addEventListener('click', function(e) { e.preventDefault(); const docType = this.getAttribute('data-type'); viewDocument(docType, displayName); // 高亮当前文档 document.querySelectorAll('#documentsList a').forEach(item => { item.classList.remove('active'); }); this.classList.add('active'); }); }); } /** * 查看文档内容 */ function viewDocument(type, displayName) { currentDocumentType = type; // 获取文档内容 fetch(`${API_BASE_URL}/projects/${currentProjectId}/documents/${type}`) .then(response => response.json()) .then(data => { if (data.success) { const doc = data.data; // 显示文档标题 documentTitle.textContent = displayName; // 显示文档内容 documentViewer.innerHTML = doc.html || marked(doc.content); // 高亮代码块 document.querySelectorAll('pre code').forEach(block => { hljs.highlightElement(block); }); // 存储原始markdown内容用于编辑 markdownEditor.value = doc.content; // 显示文档操作按钮 hideElement(documentActions, false); // 隐藏编辑器,显示查看器 hideElement(documentEditor, true); hideElement(documentViewer, false); } else { showError('加载文档内容失败', data.error); } }) .catch(error => { showError('加载文档内容失败', error.message); }); } /** * 格式化日期 */ function formatDate(dateString, shortFormat = false) { if (!dateString) return '未知'; const date = new Date(dateString); if (shortFormat) { return new Intl.DateTimeFormat('zh-CN', { month: 'numeric', day: 'numeric' }).format(date); } return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' }).format(date); } /** * 显示错误消息 */ function showError(title, message) { console.error(title, message); // 这里可以添加显示错误提示的代码,如使用Bootstrap的Toast或Alert alert(`${title}: ${message}`); } /** * 隐藏或显示元素 */ function hideElement(element, hide = true) { if (hide) { element.classList.add('d-none'); } else { element.classList.remove('d-none'); } } // 返回项目列表按钮 document.getElementById('backToListBtn').addEventListener('click', function() { hideElement(projectDetail, true); currentProjectId = null; currentDocumentType = null; }); // 编辑文档按钮 document.getElementById('editDocumentBtn').addEventListener('click', function() { // 显示编辑器,隐藏查看器 hideElement(documentViewer, true); hideElement(documentEditor, false); }); // 取消编辑按钮 document.getElementById('cancelEditBtn').addEventListener('click', function() { // 隐藏编辑器,显示查看器 hideElement(documentEditor, true); hideElement(documentViewer, false); }); // 保存文档按钮 document.getElementById('saveDocumentBtn').addEventListener('click', function() { const content = markdownEditor.value; // 保存文档内容 fetch(`${API_BASE_URL}/projects/${currentProjectId}/documents/${currentDocumentType}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: content }) }) .then(response => response.json()) .then(data => { if (data.success) { // 重新加载文档 const displayName = documentTitle.textContent; viewDocument(currentDocumentType, displayName); } else { showError('保存文档失败', data.error); } }) .catch(error => { showError('保存文档失败', error.message); }); }); // 编辑项目按钮 document.getElementById('editProjectBtn').addEventListener('click', function() { // 加载项目信息到编辑表单 fetch(`${API_BASE_URL}/projects/${currentProjectId}`) .then(response => response.json()) .then(data => { if (data.success) { const project = data.data; document.getElementById('editProjectNameInput').value = project.name; document.getElementById('editProjectDescriptionInput').value = project.description || ''; // 显示编辑项目模态框 const editProjectModal = new bootstrap.Modal(document.getElementById('editProjectModal')); editProjectModal.show(); } else { showError('加载项目信息失败', data.error); } }) .catch(error => { showError('加载项目信息失败', error.message); }); }); // 保存项目按钮 document.getElementById('saveProjectBtn').addEventListener('click', function() { const name = document.getElementById('editProjectNameInput').value; const description = document.getElementById('editProjectDescriptionInput').value; if (!name) { showError('保存项目失败', '项目名称不能为空'); return; } // 更新项目信息 fetch(`${API_BASE_URL}/projects/${currentProjectId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name, description: description }) }) .then(response => response.json()) .then(data => { if (data.success) { // 关闭模态框 bootstrap.Modal.getInstance(document.getElementById('editProjectModal')).hide(); // 更新项目名称 projectName.textContent = name; // 重新加载项目列表 loadProjects(); } else { showError('保存项目失败', data.error); } }) .catch(error => { showError('保存项目失败', error.message); }); }); // 删除项目按钮 document.getElementById('deleteProjectBtn').addEventListener('click', function() { if (!confirm('确定要删除此项目吗?此操作不可撤销!')) { return; } // 删除项目 fetch(`${API_BASE_URL}/projects/${currentProjectId}`, { method: 'DELETE' }) .then(response => response.json()) .then(data => { if (data.success) { // 关闭模态框 bootstrap.Modal.getInstance(document.getElementById('editProjectModal')).hide(); // 返回项目列表 hideElement(projectDetail, true); currentProjectId = null; // 重新加载项目列表 loadProjects(); } else { showError('删除项目失败', data.error); } }) .catch(error => { showError('删除项目失败', error.message); }); }); // 创建项目按钮 document.getElementById('createProjectBtn').addEventListener('click', function() { const name = document.getElementById('projectNameInput').value; const description = document.getElementById('projectDescriptionInput').value; if (!name) { showError('创建项目失败', '项目名称不能为空'); return; } // 创建项目 fetch(`${API_BASE_URL}/projects`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name, description: description }) }) .then(response => response.json()) .then(data => { if (data.success) { // 关闭模态框 bootstrap.Modal.getInstance(document.getElementById('createProjectModal')).hide(); // 重置表单 document.getElementById('createProjectForm').reset(); // 重新加载项目列表 loadProjects(); // 查看新创建的项目 viewProject(data.data.id); } else { showError('创建项目失败', data.error); } }) .catch(error => { showError('创建项目失败', error.message); }); }); // 导出项目按钮 document.getElementById('exportProjectBtn').addEventListener('click', function() { const format = prompt('请选择导出格式 (markdown 或 html):', 'markdown'); if (!format) return; if (format !== 'markdown' && format !== 'html') { showError('导出项目失败', '不支持的导出格式,请选择 markdown 或 html'); return; } // 调用导出API fetch(`${API_BASE_URL}/projects/${currentProjectId}/export`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ format: format }) }) .then(response => response.json()) .then(data => { if (data.success) { alert(`项目导出成功!\n导出路径: ${data.data.exportDir}`); } else { showError('导出项目失败', data.error); } }) .catch(error => { showError('导出项目失败', error.message); }); }); });

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/yywdandan/memory-bank-mcp-server'

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