Files

119 lines
4.6 KiB
JavaScript
Raw Permalink Normal View History

2026-10-29 11:57:29 +01:00
// Generated, do not edit. sha256:b0dd28dca0d6350eaa3cdbb0db8611b54c802d92405f31a10da8e494e94fbaf6
import { createInterface } from 'node:readline';
import { CONFIG } from '../../shared/config.js';
import { initDatabase, closeDatabase, dbFile, databaseStatus } from '../db.js';
import { prepareLayout, activeName } from '../portfolios.mjs';
import { openDatabase } from '../db/conn.mjs';
import { logAiToolCall } from '../data/ai-audit.js';
import { isAiActive, AI_INACTIVE_TEXT } from '../ai/gate.js';
import { flushChanges } from '../data/bus.js';
import { createMcpServer } from './protocol.mjs';
import { allTools } from './tools.mjs';
import '../edition.mjs';
const naarGebruiker = (regel) => process.stderr.write(`[assetapp-mcp] ${regel}\n`);
function stopAlsUit() {
if (isAiActive()) return false;
naarGebruiker('de AI-koppeling staat uit (schuif "Actief" onder Systeem → AI-activiteit). '
+ 'Deze server doet niets en stopt; zet de schuif aan en start uw AI-programma opnieuw.');
return true;
}
try {
naarGebruiker(prepareLayout().regel);
naarGebruiker(initDatabase());
const uit = stopAlsUit();
closeDatabase();
if (uit) process.exit(0);
} catch (e) {
naarGebruiker(`kan de database niet openen: ${e.message}`);
process.exit(1);
}
const tools = allTools();
const server = createMcpServer({
tools,
logCall: logAiToolCall,
onLogError: (e) => naarGebruiker(`LET OP: een tool-aanroep is NIET vastgelegd: ${e.message}`),
});
naarGebruiker(`gereed als '${CONFIG.AI.SERVER_NAME}', ${tools.length} tool(s), sessie ${server.session.id}`);
const lezer = createInterface({ input: process.stdin, crlfDelay: Infinity });
function kijkIn(regel) {
try {
const bericht = JSON.parse(regel);
return {
id: Object.hasOwn(bericht, 'id') ? bericht.id : undefined,
method: typeof bericht.method === 'string' ? bericht.method : null,
};
} catch { return { id: undefined, method: null }; }
}
const HEEFT_DATABASE_NODIG = 'tools/call';
const INTERNE_FOUT = -32603;
function stuurFout(regel, melding) {
const { id } = kijkIn(regel);
if (id === undefined) return;
process.stdout.write(`${JSON.stringify({ jsonrpc: '2.0', id, error: { code: INTERNE_FOUT, message: melding } })}\n`);
}
function uitlegBijStand(stand) {
const naam = activeName();
if (stand.reden === 'leeg') {
return `De portefeuille '${naam}' heeft nog geen ingerichte database. Dat gebeurt zodra de app hem `
+ 'een keer opent (Systeem → Portefeuilles → Openen). Tot dan is er hier niets te lezen.';
}
if (stand.reden === 'oud') {
return `De database van portefeuille '${naam}' staat op versie ${stand.versie} en deze app verwacht `
+ `${CONFIG.SCHEMA_VERSION}. De migraties draaien als de app die portefeuille opent; doe dat eerst.`;
}
return `De database van portefeuille '${naam}' staat op versie ${stand.versie}, en deze MCP-server kent `
+ `tot en met ${CONFIG.SCHEMA_VERSION}. Is de app net bijgewerkt, herstart dan de AI-koppeling in je `
+ 'AI-client: dit proces laadt nieuwe code pas bij een herstart. Anders is de app zelf ouder dan de '
+ 'database; werk hem dan bij.';
}
let wachtrij = Promise.resolve();
lezer.on('line', (regel) => {
const tekst = regel.trim();
if (!tekst) return;
wachtrij = wachtrij.then(async () => {
try { openDatabase(dbFile()); }
catch (e) {
naarGebruiker(`kan de database niet openen voor dit bericht: ${e.message}`);
stuurFout(tekst, `De database van de actieve portefeuille is nu niet te openen: ${e.message}`);
return;
}
const stand = databaseStatus();
if (stand.klaar && !isAiActive()) {
stuurFout(tekst, AI_INACTIVE_TEXT);
naarGebruiker('de AI-koppeling is uitgezet; deze server stopt.');
try { closeDatabase(); } catch { }
process.exit(0);
}
if (!stand.klaar && kijkIn(tekst).method === HEEFT_DATABASE_NODIG) {
naarGebruiker(`de database van deze portefeuille is niet bruikbaar (${stand.reden}); bericht geweigerd`);
stuurFout(tekst, uitlegBijStand(stand));
try { closeDatabase(); } catch { }
return;
}
try {
const antwoord = await server.handleRegel(tekst);
if (antwoord) process.stdout.write(`${JSON.stringify(antwoord)}\n`);
} catch (e) {
naarGebruiker(`onverwachte fout bij het afhandelen van een bericht: ${e.message}`);
} finally {
try { flushChanges(); } catch (e) { naarGebruiker(`signalen wegschrijven mislukte: ${e.message}`); }
try { closeDatabase(); } catch (e) { naarGebruiker(`database sluiten mislukte: ${e.message}`); }
}
});
});
lezer.on('close', () => { naarGebruiker('verbinding gesloten door de client'); process.exit(0); });