refactor(ux): consolidate BMAD skills, update design system, and clean up Prisma generated client
This commit is contained in:
43
mcp-server/check-notes.js
Normal file
43
mcp-server/check-notes.js
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Vérifier les propriétés des notes
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '../keep-notes/prisma/client-generated/index.js';
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
datasources: {
|
||||
db: { url: 'file:/Users/sepehr/dev/Keep/keep-notes/prisma/dev.db' },
|
||||
},
|
||||
});
|
||||
|
||||
async function checkNotes() {
|
||||
const notes = await prisma.note.findMany({
|
||||
where: {
|
||||
title: { startsWith: '📘' },
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
isMarkdown: true,
|
||||
type: true,
|
||||
color: true,
|
||||
labels: true,
|
||||
},
|
||||
});
|
||||
|
||||
console.log('📋 Notes trouvées:\n');
|
||||
for (const note of notes) {
|
||||
console.log(`Titre: ${note.title}`);
|
||||
console.log(` isMarkdown: ${note.isMarkdown}`);
|
||||
console.log(` type: ${note.type}`);
|
||||
console.log(` color: ${note.color}`);
|
||||
console.log(` labels: ${note.labels}`);
|
||||
console.log(` id: ${note.id}`);
|
||||
console.log('');
|
||||
}
|
||||
}
|
||||
|
||||
checkNotes()
|
||||
.catch(console.error)
|
||||
.finally(() => prisma.$disconnect());
|
||||
39
mcp-server/delete-notes.js
Normal file
39
mcp-server/delete-notes.js
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Supprimer toutes les notes créées
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '../keep-notes/prisma/client-generated/index.js';
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
datasources: {
|
||||
db: { url: 'file:/Users/sepehr/dev/Keep/keep-notes/prisma/dev.db' },
|
||||
},
|
||||
});
|
||||
|
||||
async function deleteNotes() {
|
||||
console.log('🗑️ Suppression des notes créées...\n');
|
||||
|
||||
// Trouver le notebook "Documentation"
|
||||
const notebook = await prisma.notebook.findFirst({
|
||||
where: { name: 'Documentation' },
|
||||
});
|
||||
|
||||
if (!notebook) {
|
||||
console.log('❌ Notebook "Documentation" non trouvé');
|
||||
return;
|
||||
}
|
||||
|
||||
// Supprimer toutes les notes de ce notebook
|
||||
const result = await prisma.note.deleteMany({
|
||||
where: {
|
||||
notebookId: notebook.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`✅ ${result.count} notes supprimées`);
|
||||
}
|
||||
|
||||
deleteNotes()
|
||||
.catch(console.error)
|
||||
.finally(() => prisma.$disconnect());
|
||||
560
mcp-server/import-docs.js
Normal file
560
mcp-server/import-docs.js
Normal file
@@ -0,0 +1,560 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Script d'import des documents dans Memento
|
||||
* Utilise Prisma pour créer les notes
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '../keep-notes/prisma/client-generated/index.js';
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
datasources: {
|
||||
db: { url: 'file:/Users/sepehr/dev/Keep/keep-notes/prisma/dev.db' },
|
||||
},
|
||||
});
|
||||
|
||||
const documents = [
|
||||
{
|
||||
title: '📘 Guide Utilisateur MCP',
|
||||
content: `Ce guide explique comment utiliser le serveur MCP Memento.
|
||||
|
||||
## Commandes disponibles (18 outils)
|
||||
|
||||
### Gestion des Notes
|
||||
• create_note - Créer une note
|
||||
• get_notes - Lister les notes
|
||||
• get_note - Obtenir une note par ID
|
||||
• update_note - Mettre à jour
|
||||
• delete_note - Supprimer
|
||||
• search_notes - Rechercher
|
||||
|
||||
### Gestion des Notebooks
|
||||
• create_notebook - Créer un notebook
|
||||
• get_notebooks - Lister
|
||||
• get_notebook - Obtenir par ID
|
||||
• update_notebook - Mettre à jour
|
||||
• delete_notebook - Supprimer
|
||||
|
||||
### Gestion des Labels
|
||||
• create_label - Créer un label
|
||||
• get_labels - Lister
|
||||
• delete_label - Supprimer
|
||||
|
||||
### Commandes AI
|
||||
• generate_title_suggestions
|
||||
• reformulate_text
|
||||
• generate_tags
|
||||
|
||||
## Exemple
|
||||
{ "name": "create_note", "arguments": { "title": "Ma Note", "content": "..." } }`,
|
||||
color: 'blue',
|
||||
labels: ['mcp', 'documentation'],
|
||||
},
|
||||
{
|
||||
title: '📁 Source Tree Analysis',
|
||||
content: `Analyse de l'arborescence du projet Keep.
|
||||
|
||||
## Structure
|
||||
keep/
|
||||
├── keep-notes/ # Next.js App
|
||||
├── mcp-server/ # Serveur MCP
|
||||
└── docs/ # Documentation
|
||||
|
||||
## Technologies
|
||||
• Next.js 16 + React 19
|
||||
• TypeScript 5
|
||||
• Prisma ORM
|
||||
• SQLite
|
||||
• Tailwind CSS
|
||||
• MCP SDK 1.0.4
|
||||
|
||||
## Points d'intégration
|
||||
• DB SQLite partagée
|
||||
• Protocole MCP
|
||||
• API REST
|
||||
• Intégration N8N`,
|
||||
color: 'green',
|
||||
labels: ['architecture', 'projet'],
|
||||
},
|
||||
{
|
||||
title: '🎯 Project Overview',
|
||||
content: `Memento - Application de notes avec AI.
|
||||
|
||||
## Architecture
|
||||
• Pattern: JAMstack + App Router
|
||||
• Rendu: SSR + Streaming
|
||||
• DB: SQLite + Prisma
|
||||
• Auth: NextAuth.js
|
||||
|
||||
## Fonctionnalités
|
||||
• Notes texte & checklists
|
||||
• Couleurs personnalisables
|
||||
• Images et liens
|
||||
• Rappels récurrents
|
||||
• Format Markdown
|
||||
|
||||
## Organisation
|
||||
• Notebooks hiérarchiques
|
||||
• Labels et tags
|
||||
• Archivage
|
||||
• Épinglage
|
||||
|
||||
## AI & Intelligence
|
||||
• Recherche sémantique
|
||||
• Génération de titres
|
||||
• Reformulation
|
||||
• Memory Echo
|
||||
• Batch organize`,
|
||||
color: 'purple',
|
||||
labels: ['overview', 'memento'],
|
||||
},
|
||||
{
|
||||
title: '🚀 Deployment Guide',
|
||||
content: `Guide de déploiement Memento.
|
||||
|
||||
## Prérequis
|
||||
• Node.js 20+
|
||||
• npm
|
||||
• SQLite3
|
||||
|
||||
## Installation keep-notes
|
||||
cd keep-notes
|
||||
npm install
|
||||
npx prisma generate
|
||||
npx prisma db push
|
||||
npm run dev
|
||||
|
||||
## Installation mcp-server
|
||||
cd mcp-server
|
||||
npm install
|
||||
export DATABASE_URL="file:..."
|
||||
npm run start:http
|
||||
|
||||
## Variables d'environnement
|
||||
DATABASE_URL
|
||||
NEXTAUTH_SECRET
|
||||
NEXTAUTH_URL
|
||||
PORT=4242
|
||||
APP_BASE_URL
|
||||
|
||||
## Docker
|
||||
Dockerfile disponible pour containerisation.`,
|
||||
color: 'orange',
|
||||
labels: ['deployment', 'guide'],
|
||||
},
|
||||
{
|
||||
title: '💻 Development Guide',
|
||||
content: `Guide développement keep-notes.
|
||||
|
||||
## Stack
|
||||
• Next.js 16 + React 19
|
||||
• TypeScript 5
|
||||
• Tailwind CSS
|
||||
• Radix UI
|
||||
• Framer Motion
|
||||
|
||||
## Structure
|
||||
app/
|
||||
├── (main)/
|
||||
├── api/
|
||||
├── layout.tsx
|
||||
globals.css
|
||||
|
||||
components/
|
||||
├── ui/
|
||||
├── notes/
|
||||
├── notebooks/
|
||||
|
||||
lib/
|
||||
├── prisma.ts
|
||||
├── auth.ts
|
||||
└── utils.ts
|
||||
|
||||
## Patterns
|
||||
Server Components (défaut)
|
||||
Client Components ('use client')
|
||||
Server Actions ('use server')`,
|
||||
color: 'teal',
|
||||
labels: ['development', 'guide'],
|
||||
},
|
||||
{
|
||||
title: '🔌 Integration Architecture',
|
||||
content: `Architecture d'intégration.
|
||||
|
||||
## Communication
|
||||
keep-notes ◄──► SQLite DB ◄──► mcp-server
|
||||
|
||||
## Protocole MCP
|
||||
Client AI ──► MCP Server (4242) ──► SQLite
|
||||
|
||||
## Intégration N8N
|
||||
N8N Workflow ──► MCP Server ──► SQLite
|
||||
|
||||
## Flux de données
|
||||
1. keep-notes → Server Action → Prisma → DB
|
||||
2. MCP Request → Prisma → DB → Response
|
||||
3. Temps réel via DB partagée`,
|
||||
color: 'blue',
|
||||
labels: ['architecture', 'integration'],
|
||||
},
|
||||
{
|
||||
title: '📡 API Contracts Keep Notes',
|
||||
content: `API REST keep-notes.
|
||||
|
||||
## Base URL
|
||||
http://localhost:3000/api
|
||||
|
||||
## Endpoints Notes
|
||||
GET /api/notes
|
||||
POST /api/notes
|
||||
PUT /api/notes/:id
|
||||
DELETE /api/notes/:id
|
||||
|
||||
## AI Features
|
||||
POST /api/ai/title-suggestions
|
||||
POST /api/ai/tags
|
||||
POST /api/ai/reformulate
|
||||
|
||||
## Codes d'erreur
|
||||
200 - Succès
|
||||
400 - Requête invalide
|
||||
401 - Non authentifié
|
||||
404 - Non trouvé
|
||||
500 - Erreur serveur`,
|
||||
color: 'yellow',
|
||||
labels: ['api', 'contracts'],
|
||||
},
|
||||
{
|
||||
title: '🏗️ Architecture Keep Notes',
|
||||
content: `Architecture détaillée.
|
||||
|
||||
## Pattern
|
||||
JAMstack + App Router
|
||||
|
||||
## Flux UI → Server Action → Prisma → SQLite
|
||||
|
||||
## Server Components
|
||||
• Accès direct DB
|
||||
• Pas de JS client
|
||||
• SEO-friendly
|
||||
|
||||
## Client Components
|
||||
• Interactivité
|
||||
• useState/useEffect
|
||||
• APIs navigateur
|
||||
|
||||
## Server Actions
|
||||
'use server'
|
||||
async function createNote() {
|
||||
await prisma.note.create({...})
|
||||
}`,
|
||||
color: 'purple',
|
||||
labels: ['architecture', 'keep-notes'],
|
||||
},
|
||||
{
|
||||
title: '🔍 Code Review Cleanup Report',
|
||||
content: `Rapport nettoyage code.
|
||||
|
||||
## Issues trouvées
|
||||
57 fichiers avec code debug
|
||||
|
||||
## Routes à supprimer (14)
|
||||
/api/debug/*
|
||||
/api/test/route.ts
|
||||
|
||||
## Scripts à supprimer (8)
|
||||
check-*.js
|
||||
debug-*.js
|
||||
test-*.js
|
||||
|
||||
## Console statements (41)
|
||||
Nettoyer tous les console.log
|
||||
|
||||
## Checklist
|
||||
☐ Routes debug
|
||||
☐ Scripts debug
|
||||
☐ Console.log
|
||||
☐ Imports inutilisés
|
||||
☐ TODO/FIXME
|
||||
☐ Test build prod`,
|
||||
color: 'red',
|
||||
labels: ['cleanup', 'review'],
|
||||
},
|
||||
{
|
||||
title: '🗄️ Data Models',
|
||||
content: `Modèles de données Prisma.
|
||||
|
||||
## User
|
||||
id, name, email, password, role
|
||||
Relations: notes[], notebooks[], labels[]
|
||||
|
||||
## Note
|
||||
id, title, content, color
|
||||
isPinned, isArchived, type
|
||||
JSON: checkItems, labels, images, links
|
||||
Relations: user, notebook
|
||||
|
||||
## Notebook
|
||||
id, name, icon, color, order
|
||||
Relations: user, notes[], labels[]
|
||||
|
||||
## Label
|
||||
id, name, color
|
||||
Relations: notebook
|
||||
|
||||
## Relations
|
||||
User 1:N Note
|
||||
User 1:N Notebook
|
||||
Notebook 1:N Note`,
|
||||
color: 'gray',
|
||||
labels: ['database', 'models'],
|
||||
},
|
||||
{
|
||||
title: '🧩 Component Inventory',
|
||||
content: `Inventaire des composants.
|
||||
|
||||
## UI Components
|
||||
Button, Card, Dialog
|
||||
Input, Select, Checkbox
|
||||
|
||||
## Business Components
|
||||
NoteCard, NotebookItem
|
||||
LabelBadge, NoteEditor
|
||||
|
||||
## Layout Components
|
||||
Sidebar, Header, MainContent
|
||||
MasonryGrid, Tabs
|
||||
|
||||
## Hooks
|
||||
useNotes, useNotebooks
|
||||
useLabels, useSearch
|
||||
|
||||
## Utils
|
||||
formatDate, generateId
|
||||
parseContent, debounce`,
|
||||
color: 'teal',
|
||||
labels: ['components', 'inventory'],
|
||||
},
|
||||
{
|
||||
title: '🔧 Architecture MCP Server',
|
||||
content: `Serveur MCP v3.1.0
|
||||
|
||||
## Transport
|
||||
HTTP Streamable (port 4242)
|
||||
|
||||
## 37 Outils
|
||||
12 Notes
|
||||
6 Notebooks
|
||||
4 Labels
|
||||
11 AI
|
||||
1 Reminders
|
||||
3 API Keys
|
||||
|
||||
## Optimisations
|
||||
✓ Connection pooling
|
||||
✓ Batch operations
|
||||
✓ API key caching (60s)
|
||||
✓ Parallel queries
|
||||
✓ Request timeout (10s)
|
||||
|
||||
## Fichiers
|
||||
index.js, index-sse.js
|
||||
tools.js, auth.js`,
|
||||
color: 'blue',
|
||||
labels: ['mcp', 'architecture'],
|
||||
},
|
||||
{
|
||||
title: '📋 API Contracts MCP Server',
|
||||
content: `Contrats API MCP.
|
||||
|
||||
## Protocole
|
||||
MCP SDK 1.0.4
|
||||
|
||||
## Transport
|
||||
Streamable HTTP
|
||||
|
||||
## URL
|
||||
http://localhost:4242/mcp
|
||||
|
||||
## Auth
|
||||
Headers: x-api-key ou x-user-id
|
||||
|
||||
## Réponse
|
||||
{
|
||||
"content": [{
|
||||
"type": "text",
|
||||
"text": "..."
|
||||
}]
|
||||
}
|
||||
|
||||
## Erreurs
|
||||
McpError avec ErrorCode`,
|
||||
color: 'yellow',
|
||||
labels: ['api', 'mcp'],
|
||||
},
|
||||
{
|
||||
title: '💰 Monetization Analysis',
|
||||
content: `Stratégies monétisation.
|
||||
|
||||
## Options
|
||||
☕ Pay me a coffee
|
||||
⭐ Freemium
|
||||
☁️ Cloud Hosting
|
||||
🤖 AI Credits
|
||||
🏢 White-Label
|
||||
|
||||
## Plateformes
|
||||
Ko-fi (0% frais)
|
||||
Buy Me a Coffee
|
||||
GitHub Sponsors
|
||||
|
||||
## Revenus estimés
|
||||
Year 1: $200-500/mois
|
||||
Year 2: $1,000-2,000/mois
|
||||
|
||||
## Recommandé
|
||||
Ko-fi pour commencer`,
|
||||
color: 'green',
|
||||
labels: ['monetization', 'business'],
|
||||
},
|
||||
{
|
||||
title: '📚 Index Documentation',
|
||||
content: `Table des matières.
|
||||
|
||||
## 15 Documents
|
||||
|
||||
### Architecture (5)
|
||||
• Source Tree Analysis
|
||||
• Project Overview
|
||||
• Integration Architecture
|
||||
• Architecture Keep Notes
|
||||
• Architecture MCP Server
|
||||
|
||||
### APIs (3)
|
||||
• API Contracts Keep Notes
|
||||
• API Contracts MCP Server
|
||||
• Data Models
|
||||
|
||||
### Guides (4)
|
||||
• Guide Utilisateur MCP
|
||||
• Deployment Guide
|
||||
• Development Guide
|
||||
• Component Inventory
|
||||
|
||||
### Rapports (3)
|
||||
• Code Review Cleanup
|
||||
• Monetization Analysis
|
||||
• MCP Optimization Report`,
|
||||
color: 'gray',
|
||||
labels: ['index', 'documentation'],
|
||||
},
|
||||
{
|
||||
title: '⚡ MCP Optimization Report',
|
||||
content: `Rapport optimisation v3.1.0
|
||||
|
||||
## Problèmes résolus
|
||||
✓ N+1 queries
|
||||
✓ Batch operations
|
||||
✓ API key O(n) → O(1)
|
||||
✓ HTTP timeouts
|
||||
|
||||
## Optimisations
|
||||
• Connection pooling
|
||||
• Parallel queries
|
||||
• Caching 60s TTL
|
||||
• Session cleanup
|
||||
|
||||
## Gains
|
||||
• 99% moins de requêtes
|
||||
• 80% plus rapide (import)
|
||||
• 95% lookup API keys
|
||||
|
||||
## Fichiers modifiés
|
||||
auth.js, tools.js
|
||||
index.js, index-sse.js`,
|
||||
color: 'purple',
|
||||
labels: ['optimization', 'mcp'],
|
||||
},
|
||||
];
|
||||
|
||||
async function importDocuments() {
|
||||
console.log('📝 Import des documents dans Memento...\n');
|
||||
|
||||
// Trouver ou créer le user
|
||||
let user = await prisma.user.findFirst();
|
||||
if (!user) {
|
||||
console.log('❌ Aucun utilisateur trouvé dans la base');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Trouver ou créer le notebook "Documentation"
|
||||
let notebook = await prisma.notebook.findFirst({
|
||||
where: { name: 'Documentation' },
|
||||
});
|
||||
|
||||
if (!notebook) {
|
||||
const highestOrder = await prisma.notebook.findFirst({
|
||||
orderBy: { order: 'desc' },
|
||||
select: { order: true },
|
||||
});
|
||||
|
||||
notebook = await prisma.notebook.create({
|
||||
data: {
|
||||
name: 'Documentation',
|
||||
icon: '📚',
|
||||
color: '#3B82F6',
|
||||
order: (highestOrder?.order ?? -1) + 1,
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
console.log('📁 Notebook "Documentation" créé\n');
|
||||
} else {
|
||||
console.log('📁 Notebook "Documentation" trouvé\n');
|
||||
}
|
||||
|
||||
// Créer les notes
|
||||
let created = 0;
|
||||
let skipped = 0;
|
||||
|
||||
for (const doc of documents) {
|
||||
// Vérifier si la note existe déjà
|
||||
const existing = await prisma.note.findFirst({
|
||||
where: {
|
||||
title: doc.title,
|
||||
notebookId: notebook.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
console.log(`⏭️ Déjà existant: ${doc.title}`);
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
await prisma.note.create({
|
||||
data: {
|
||||
title: doc.title,
|
||||
content: doc.content,
|
||||
color: doc.color,
|
||||
labels: JSON.stringify(doc.labels),
|
||||
notebookId: notebook.id,
|
||||
userId: user.id,
|
||||
type: 'text',
|
||||
isPinned: false,
|
||||
isArchived: false,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`✅ Créé: ${doc.title}`);
|
||||
created++;
|
||||
}
|
||||
|
||||
console.log(`\n📊 Résumé:`);
|
||||
console.log(` Créés: ${created}`);
|
||||
console.log(` Skippés: ${skipped}`);
|
||||
console.log(` Total: ${documents.length}`);
|
||||
console.log(`\n✨ Import terminé !`);
|
||||
}
|
||||
|
||||
importDocuments()
|
||||
.catch(console.error)
|
||||
.finally(() => prisma.$disconnect());
|
||||
148
mcp-server/import-full-docs.js
Normal file
148
mcp-server/import-full-docs.js
Normal file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Script d'import COMPLET des documents dans Memento
|
||||
* Importe le contenu intégral de chaque fichier .md
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '../keep-notes/prisma/client-generated/index.js';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
datasources: {
|
||||
db: { url: 'file:/Users/sepehr/dev/Keep/keep-notes/prisma/dev.db' },
|
||||
},
|
||||
});
|
||||
|
||||
// Liste des documents avec leurs chemins
|
||||
const documents = [
|
||||
{ file: 'guide-utilisateur-mcp.md', title: '📘 Guide Utilisateur MCP', color: 'blue' },
|
||||
{ file: 'source-tree-analysis.md', title: '📁 Source Tree Analysis', color: 'green' },
|
||||
{ file: 'project-overview.md', title: '🎯 Project Overview', color: 'purple' },
|
||||
{ file: 'deployment-guide.md', title: '🚀 Deployment Guide', color: 'orange' },
|
||||
{ file: 'development-guide-keep-notes.md', title: '💻 Development Guide', color: 'teal' },
|
||||
{ file: 'integration-architecture.md', title: '🔌 Integration Architecture', color: 'blue' },
|
||||
{ file: 'api-contracts-keep-notes.md', title: '📡 API Contracts Keep Notes', color: 'yellow' },
|
||||
{ file: 'architecture-keep-notes.md', title: '🏗️ Architecture Keep Notes', color: 'purple' },
|
||||
{ file: 'code-review-cleanup-report.md', title: '🔍 Code Review Cleanup Report', color: 'red' },
|
||||
{ file: 'data-models.md', title: '🗄️ Data Models', color: 'gray' },
|
||||
{ file: 'component-inventory.md', title: '🧩 Component Inventory', color: 'teal' },
|
||||
{ file: 'architecture-mcp-server.md', title: '🔧 Architecture MCP Server', color: 'blue' },
|
||||
{ file: 'api-contracts-mcp-server.md', title: '📋 API Contracts MCP Server', color: 'yellow' },
|
||||
{ file: 'monetization-analysis.md', title: '💰 Monetization Analysis', color: 'green' },
|
||||
{ file: 'index.md', title: '📚 Index Documentation', color: 'gray' },
|
||||
{ file: 'mcp-optimization-report.md', title: '⚡ MCP Optimization Report', color: 'purple' },
|
||||
];
|
||||
|
||||
async function importDocuments() {
|
||||
console.log('📝 Import COMPLET des documents dans Memento...\n');
|
||||
|
||||
// Trouver le user
|
||||
let user = await prisma.user.findFirst();
|
||||
if (!user) {
|
||||
console.log('❌ Aucun utilisateur trouvé');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Trouver ou créer le notebook "Documentation"
|
||||
let notebook = await prisma.notebook.findFirst({
|
||||
where: { name: 'Documentation' },
|
||||
});
|
||||
|
||||
if (!notebook) {
|
||||
const highestOrder = await prisma.notebook.findFirst({
|
||||
orderBy: { order: 'desc' },
|
||||
select: { order: true },
|
||||
});
|
||||
|
||||
notebook = await prisma.notebook.create({
|
||||
data: {
|
||||
name: 'Documentation',
|
||||
icon: '📚',
|
||||
color: '#3B82F6',
|
||||
order: (highestOrder?.order ?? -1) + 1,
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
console.log('📁 Notebook "Documentation" créé\n');
|
||||
} else {
|
||||
console.log('📁 Notebook "Documentation" trouvé\n');
|
||||
}
|
||||
|
||||
let created = 0;
|
||||
let updated = 0;
|
||||
let errors = 0;
|
||||
|
||||
for (const doc of documents) {
|
||||
try {
|
||||
const filePath = join('/Users/sepehr/dev/Keep/docs', doc.file);
|
||||
let content;
|
||||
|
||||
try {
|
||||
content = readFileSync(filePath, 'utf-8');
|
||||
} catch (e) {
|
||||
console.log(`⚠️ Fichier non trouvé: ${doc.file}`);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Vérifier si la note existe déjà
|
||||
const existing = await prisma.note.findFirst({
|
||||
where: {
|
||||
title: doc.title,
|
||||
notebookId: notebook.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
// Mettre à jour avec le contenu complet
|
||||
await prisma.note.update({
|
||||
where: { id: existing.id },
|
||||
data: {
|
||||
content: content,
|
||||
color: doc.color,
|
||||
labels: JSON.stringify(['documentation']),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
console.log(`🔄 Mis à jour: ${doc.title} (${content.length} caractères)`);
|
||||
updated++;
|
||||
} else {
|
||||
// Créer nouvelle note
|
||||
await prisma.note.create({
|
||||
data: {
|
||||
title: doc.title,
|
||||
content: content,
|
||||
color: doc.color,
|
||||
labels: JSON.stringify(['documentation']),
|
||||
notebookId: notebook.id,
|
||||
userId: user.id,
|
||||
type: 'text',
|
||||
isPinned: false,
|
||||
isArchived: false,
|
||||
},
|
||||
});
|
||||
console.log(`✅ Créé: ${doc.title} (${content.length} caractères)`);
|
||||
created++;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`❌ Erreur ${doc.title}: ${error.message}`);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n📊 Résumé:`);
|
||||
console.log(` Créés: ${created}`);
|
||||
console.log(` Mis à jour: ${updated}`);
|
||||
console.log(` Erreurs: ${errors}`);
|
||||
console.log(` Total: ${documents.length}`);
|
||||
console.log(`\n✨ Import terminé !`);
|
||||
}
|
||||
|
||||
importDocuments()
|
||||
.catch(console.error)
|
||||
.finally(() => prisma.$disconnect());
|
||||
35
mcp-server/opencode.json
Normal file
35
mcp-server/opencode.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"agent": {
|
||||
"analyst": {
|
||||
"prompt": "{file:./.bmad-core/agents/analyst.md}"
|
||||
},
|
||||
"architect": {
|
||||
"prompt": "{file:./.bmad-core/agents/architect.md}"
|
||||
},
|
||||
"bmad-master": {
|
||||
"prompt": "{file:./.bmad-core/agents/bmad-master.md}"
|
||||
},
|
||||
"bmad-orchestrator": {
|
||||
"prompt": "{file:./.bmad-core/agents/bmad-orchestrator.md}"
|
||||
},
|
||||
"dev": {
|
||||
"prompt": "{file:./.bmad-core/agents/dev.md}"
|
||||
},
|
||||
"pm": {
|
||||
"prompt": "{file:./.bmad-core/agents/pm.md}"
|
||||
},
|
||||
"po": {
|
||||
"prompt": "{file:./.bmad-core/agents/po.md}"
|
||||
},
|
||||
"qa": {
|
||||
"prompt": "{file:./.bmad-core/agents/qa.md}"
|
||||
},
|
||||
"sm": {
|
||||
"prompt": "{file:./.bmad-core/agents/sm.md}"
|
||||
},
|
||||
"ux-expert": {
|
||||
"prompt": "{file:./.bmad-core/agents/ux-expert.md}"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
mcp-server/start.sh
Executable file
5
mcp-server/start.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
export PORT=4242
|
||||
export DATABASE_URL="file:../keep-notes/prisma/dev.db"
|
||||
export MCP_LOG_LEVEL=info
|
||||
node index-sse.js
|
||||
114
mcp-server/update-markdown.js
Normal file
114
mcp-server/update-markdown.js
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Script d'import COMPLET des documents Markdown dans Memento
|
||||
* Les notes sont créées avec isMarkdown: true
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '../keep-notes/prisma/client-generated/index.js';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
datasources: {
|
||||
db: { url: 'file:/Users/sepehr/dev/Keep/keep-notes/prisma/dev.db' },
|
||||
},
|
||||
});
|
||||
|
||||
// Liste des documents
|
||||
const documents = [
|
||||
{ file: 'guide-utilisateur-mcp.md', title: '📘 Guide Utilisateur MCP', color: 'blue' },
|
||||
{ file: 'source-tree-analysis.md', title: '📁 Source Tree Analysis', color: 'green' },
|
||||
{ file: 'project-overview.md', title: '🎯 Project Overview', color: 'purple' },
|
||||
{ file: 'deployment-guide.md', title: '🚀 Deployment Guide', color: 'orange' },
|
||||
{ file: 'development-guide-keep-notes.md', title: '💻 Development Guide', color: 'teal' },
|
||||
{ file: 'integration-architecture.md', title: '🔌 Integration Architecture', color: 'blue' },
|
||||
{ file: 'api-contracts-keep-notes.md', title: '📡 API Contracts Keep Notes', color: 'yellow' },
|
||||
{ file: 'architecture-keep-notes.md', title: '🏗️ Architecture Keep Notes', color: 'purple' },
|
||||
{ file: 'code-review-cleanup-report.md', title: '🔍 Code Review Cleanup Report', color: 'red' },
|
||||
{ file: 'data-models.md', title: '🗄️ Data Models', color: 'gray' },
|
||||
{ file: 'component-inventory.md', title: '🧩 Component Inventory', color: 'teal' },
|
||||
{ file: 'architecture-mcp-server.md', title: '🔧 Architecture MCP Server', color: 'blue' },
|
||||
{ file: 'api-contracts-mcp-server.md', title: '📋 API Contracts MCP Server', color: 'yellow' },
|
||||
{ file: 'monetization-analysis.md', title: '💰 Monetization Analysis', color: 'green' },
|
||||
{ file: 'index.md', title: '📚 Index Documentation', color: 'gray' },
|
||||
{ file: 'mcp-optimization-report.md', title: '⚡ MCP Optimization Report', color: 'purple' },
|
||||
];
|
||||
|
||||
async function importDocuments() {
|
||||
console.log('📝 Import des documents Markdown dans Memento...\n');
|
||||
|
||||
// Trouver le user
|
||||
let user = await prisma.user.findFirst();
|
||||
if (!user) {
|
||||
console.log('❌ Aucun utilisateur trouvé');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Trouver le notebook "Documentation"
|
||||
let notebook = await prisma.notebook.findFirst({
|
||||
where: { name: 'Documentation' },
|
||||
});
|
||||
|
||||
if (!notebook) {
|
||||
console.log('❌ Notebook "Documentation" non trouvé');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('📁 Notebook "Documentation" trouvé\n');
|
||||
|
||||
let updated = 0;
|
||||
let errors = 0;
|
||||
|
||||
for (const doc of documents) {
|
||||
try {
|
||||
const filePath = join('/Users/sepehr/dev/Keep/docs', doc.file);
|
||||
let content;
|
||||
|
||||
try {
|
||||
content = readFileSync(filePath, 'utf-8');
|
||||
} catch (e) {
|
||||
console.log(`⚠️ Fichier non trouvé: ${doc.file}`);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Chercher la note existante
|
||||
const existing = await prisma.note.findFirst({
|
||||
where: {
|
||||
title: doc.title,
|
||||
notebookId: notebook.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
// Mettre à jour avec isMarkdown: true
|
||||
await prisma.note.update({
|
||||
where: { id: existing.id },
|
||||
data: {
|
||||
content: content,
|
||||
color: doc.color,
|
||||
labels: JSON.stringify(['documentation']),
|
||||
isMarkdown: true, // ✅ FORMAT MARKDOWN ACTIVÉ
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
console.log(`🔄 Mis à jour (Markdown): ${doc.title}`);
|
||||
updated++;
|
||||
} else {
|
||||
console.log(`⚠️ Note non trouvée: ${doc.title}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`❌ Erreur ${doc.title}: ${error.message}`);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n📊 Résumé:`);
|
||||
console.log(` Mis à jour en Markdown: ${updated}`);
|
||||
console.log(` Erreurs: ${errors}`);
|
||||
console.log(`\n✨ Toutes les notes sont maintenant en format Markdown !`);
|
||||
}
|
||||
|
||||
importDocuments()
|
||||
.catch(console.error)
|
||||
.finally(() => prisma.$disconnect());
|
||||
Reference in New Issue
Block a user