@dollhousemcp/mcp-server
Version:
DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.
108 lines • 15.1 kB
JavaScript
import { EvictingQueue } from '../../utils/EvictingQueue.js';
import { LOG_LEVEL_PRIORITY } from '../types.js';
const CATEGORY_KEY = {
application: 'appCapacity',
security: 'securityCapacity',
performance: 'perfCapacity',
telemetry: 'telemetryCapacity',
};
export class MemoryLogSink {
queues;
evictionCounts = new Map();
constructor(options) {
this.queues = new Map();
for (const [category, key] of Object.entries(CATEGORY_KEY)) {
this.queues.set(category, new EvictingQueue(options[key]));
this.evictionCounts.set(category, 0);
}
}
write(entry) {
const queue = this.queues.get(entry.category);
if (queue) {
if (queue.size >= queue.capacity) {
this.evictionCounts.set(entry.category, (this.evictionCounts.get(entry.category) ?? 0) + 1);
}
queue.push(entry);
}
}
async flush() {
// No-op — in-memory, nothing to flush.
}
async close() {
for (const queue of this.queues.values()) {
queue.clear();
}
}
query(options) {
const category = options?.category ?? 'all';
const limit = Math.max(1, Math.min(options?.limit ?? 50, 10000));
const offset = Math.max(0, options?.offset ?? 0);
// 1. Select queues
const selectedQueues = [];
if (category === 'all') {
for (const q of this.queues.values()) {
selectedQueues.push(q);
}
}
else {
const q = this.queues.get(category);
if (q)
selectedQueues.push(q);
}
// 2. Collect entries from selected queues
let entries = [];
for (const q of selectedQueues) {
entries.push(...q.toArray());
}
// 3. Apply filters conjunctively
if (options?.level) {
const minPriority = LOG_LEVEL_PRIORITY[options.level];
entries = entries.filter(e => LOG_LEVEL_PRIORITY[e.level] >= minPriority);
}
if (options?.source) {
const needle = options.source.toLowerCase();
entries = entries.filter(e => e.source.toLowerCase().includes(needle));
}
if (options?.message) {
const needle = options.message.toLowerCase();
entries = entries.filter(e => e.message.toLowerCase().includes(needle));
}
if (options?.since) {
const since = options.since;
entries = entries.filter(e => e.timestamp > since);
}
if (options?.until) {
const until = options.until;
entries = entries.filter(e => e.timestamp < until);
}
if (options?.correlationId) {
const corrId = options.correlationId;
entries = entries.filter(e => e.correlationId === corrId);
}
// 4. Count total before pagination
const total = entries.length;
// 5. Sort newest-first (descending timestamp)
entries.sort((a, b) => (a.timestamp > b.timestamp ? -1 : a.timestamp < b.timestamp ? 1 : 0));
// 6. Paginate
entries = entries.slice(offset, offset + limit);
return {
entries,
total,
hasMore: offset + limit < total,
limit,
offset,
};
}
getStats() {
const stats = {};
for (const [category, queue] of this.queues) {
stats[category] = {
size: queue.size,
capacity: queue.capacity,
evictions: this.evictionCounts.get(category) ?? 0,
};
}
return stats;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWVtb3J5TG9nU2luay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sb2dnaW5nL3NpbmtzL01lbW9yeUxvZ1NpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBUTdELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQVNqRCxNQUFNLFlBQVksR0FBb0Q7SUFDcEUsV0FBVyxFQUFFLGFBQWE7SUFDMUIsUUFBUSxFQUFFLGtCQUFrQjtJQUM1QixXQUFXLEVBQUUsY0FBYztJQUMzQixTQUFTLEVBQUUsbUJBQW1CO0NBQy9CLENBQUM7QUFFRixNQUFNLE9BQU8sYUFBYTtJQUNQLE1BQU0sQ0FBbUQ7SUFDekQsY0FBYyxHQUE2QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRXRFLFlBQVksT0FBNkI7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBK0MsQ0FBQztRQUNyRSxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQzNELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNiLFFBQXVCLEVBQ3ZCLElBQUksYUFBYSxDQUFrQixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FDakQsQ0FBQztZQUNGLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQXVCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsS0FBc0I7UUFDMUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUks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LENBQUMsQ0FBQyxDQUFDO1FBRTdGLGNBQWM7UUFDZCxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBRWhELE9BQU87WUFDTCxPQUFPO1lBQ1AsS0FBSztZQUNMLE9BQU8sRUFBRSxNQUFNLEdBQUcsS0FBSyxHQUFHLEtBQUs7WUFDL0IsS0FBSztZQUNMLE1BQU07U0FDUCxDQUFDO0lBQ0osQ0FBQztJQUVELFFBQVE7UUFDTixNQUFNLEtBQUssR0FBRyxFQUFnRixDQUFDO1FBQy9GLEtBQUssTUFBTSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDNUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHO2dCQUNoQixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtnQkFDeEIsU0FBUyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7YUFDbEQsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2aWN0aW5nUXVldWUgfSBmcm9tICcuLi8uLi91dGlscy9FdmljdGluZ1F1ZXVlLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgSUxvZ1NpbmssXG4gIExvZ0NhdGVnb3J5LFxuICBMb2dRdWVyeU9wdGlvbnMsXG4gIExvZ1F1ZXJ5UmVzdWx0LFxuICBVbmlmaWVkTG9nRW50cnksXG59IGZyb20gJy4uL3R5cGVzLmpzJztcbmltcG9ydCB7IExPR19MRVZFTF9QUklPUklUWSB9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBNZW1vcnlMb2dTaW5rT3B0aW9ucyB7XG4gIGFwcENhcGFjaXR5OiBudW1iZXI7XG4gIHNlY3VyaXR5Q2FwYWNpdHk6IG51bWJlcjtcbiAgcGVyZkNhcGFjaXR5OiBudW1iZXI7XG4gIHRlbGVtZXRyeUNhcGFjaXR5OiBudW1iZXI7XG59XG5cbmNvbnN0IENBVEVHT1JZX0tFWTogUmVjb3JkPExvZ0NhdGVnb3J5LCBrZXlvZiBNZW1vcnlMb2dTaW5rT3B0aW9ucz4gPSB7XG4gIGFwcGxpY2F0aW9uOiAnYXBwQ2FwYWNpdHknLFxuICBzZWN1cml0eTogJ3NlY3VyaXR5Q2FwYWNpdHknLFxuICBwZXJmb3JtYW5jZTogJ3BlcmZDYXBhY2l0eScsXG4gIHRlbGVtZXRyeTogJ3RlbGVtZXRyeUNhcGFjaXR5Jyxcbn07XG5cbmV4cG9ydCBjbGFzcyBNZW1vcnlMb2dTaW5rIGltcGxlbWVudHMgSUxvZ1Npbmsge1xuICBwcml2YXRlIHJlYWRvbmx5IHF1ZXVlczogTWFwPExvZ0NhdGVnb3J5LCBFdmljdGluZ1F1ZXVlPFVuaWZpZWRMb2dFbnRyeT4+O1xuICBwcml2YXRlIHJlYWRvbmx5IGV2aWN0aW9uQ291bnRzOiBNYXA8TG9nQ2F0ZWdvcnksIG51bWJlcj4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogTWVtb3J5TG9nU2lua09wdGlvbnMpIHtcbiAgICB0aGlzLnF1ZXVlcyA9IG5ldyBNYXA8TG9nQ2F0ZWdvcnksIEV2aWN0aW5nUXVldWU8VW5pZmllZExvZ0VudHJ5Pj4oKTtcbiAgICBmb3IgKGNvbnN0IFtjYXRlZ29yeSwga2V5XSBvZiBPYmplY3QuZW50cmllcyhDQVRFR09SWV9LRVkpKSB7XG4gICAgICB0aGlzLnF1ZXVlcy5zZXQoXG4gICAgICAgIGNhdGVnb3J5IGFzIExvZ0NhdGVnb3J5LFxuICAgICAgICBuZXcgRXZpY3RpbmdRdWV1ZTxVbmlmaWVkTG9nRW50cnk+KG9wdGlvbnNba2V5XSksXG4gICAgICApO1xuICAgICAgdGhpcy5ldmljdGlvbkNvdW50cy5zZXQoY2F0ZWdvcnkgYXMgTG9nQ2F0ZWdvcnksIDApO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlKGVudHJ5OiBVbmlmaWVkTG9nRW50cnkpOiB2b2lkIHtcbiAgICBjb25zdCBxdWV1ZSA9IHRoaXMucXVldWVzLmdldChlbnRyeS5jYXRlZ29yeSk7XG4gICAgaWYgKHF1ZXVlKSB7XG4gICAgICBpZiAocXVldWUuc2l6ZSA+PSBxdWV1ZS5jYXBhY2l0eSkge1xuICAgICAgICB0aGlzLmV2aWN0aW9uQ291bnRzLnNldChcbiAgICAgICAgICBlbnRyeS5jYXRlZ29yeSxcbiAgICAgICAgICAodGhpcy5ldmljdGlvbkNvdW50cy5nZXQoZW50cnkuY2F0ZWdvcnkpID8/IDApICsgMSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHF1ZXVlLnB1c2goZW50cnkpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZsdXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIE5vLW9wIOKAlCBpbi1tZW1vcnksIG5vdGhpbmcgdG8gZmx1c2guXG4gIH1cblxuICBhc3luYyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IHF1ZXVlIG9mIHRoaXMucXVldWVzLnZhbHVlcygpKSB7XG4gICAgICBxdWV1ZS5jbGVhcigpO1xuICAgIH1cbiAgfVxuXG4gIHF1ZXJ5KG9wdGlvbnM/OiBMb2dRdWVyeU9wdGlvbnMpOiBMb2dRdWVyeVJlc3VsdCB7XG4gICAgY29uc3QgY2F0ZWdvcnkgPSBvcHRpb25zPy5jYXRlZ29yeSA/PyAnYWxsJztcbiAgICBjb25zdCBsaW1pdCA9IE1hdGgubWF4KDEsIE1hdGgubWluKG9wdGlvbnM/LmxpbWl0ID8/IDUwLCAxMDAwMCkpO1xuICAgIGNvbnN0IG9mZnNldCA9IE1hdGgubWF4KDAsIG9wdGlvbnM/Lm9mZnNldCA/PyAwKTtcblxuICAgIC8vIDEuIFNlbGVjdCBxdWV1ZXNcbiAgICBjb25zdCBzZWxlY3RlZFF1ZXVlczogRXZpY3RpbmdRdWV1ZTxVbmlmaWVkTG9nRW50cnk+W10gPSBbXTtcbiAgICBpZiAoY2F0ZWdvcnkgPT09ICdhbGwnKSB7XG4gICAgICBmb3IgKGNvbnN0IHEgb2YgdGhpcy5xdWV1ZXMudmFsdWVzKCkpIHtcbiAgICAgICAgc2VsZWN0ZWRRdWV1ZXMucHVzaChxKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcSA9IHRoaXMucXVldWVzLmdldChjYXRlZ29yeSk7XG4gICAgICBpZiAocSkgc2VsZWN0ZWRRdWV1ZXMucHVzaChxKTtcbiAgICB9XG5cbiAgICAvLyAyLiBDb2xsZWN0IGVudHJpZXMgZnJvbSBzZWxlY3RlZCBxdWV1ZXNcbiAgICBsZXQgZW50cmllczogVW5pZmllZExvZ0VudHJ5W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHEgb2Ygc2VsZWN0ZWRRdWV1ZXMpIHtcbiAgICAgIGVudHJpZXMucHVzaCguLi5xLnRvQXJyYXkoKSk7XG4gICAgfVxuXG4gICAgLy8gMy4gQXBwbHkgZmlsdGVycyBjb25qdW5jdGl2ZWx5XG4gICAgaWYgKG9wdGlvbnM/LmxldmVsKSB7XG4gICAgICBjb25zdCBtaW5Qcmlvcml0eSA9IExPR19MRVZFTF9QUklPUklUWVtvcHRpb25zLmxldmVsXTtcbiAgICAgIGVudHJpZXMgPSBlbnRyaWVzLmZpbHRlcihlID0+IExPR19MRVZFTF9QUklPUklUWVtlLmxldmVsXSA+PSBtaW5Qcmlvcml0eSk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy5zb3VyY2UpIHtcbiAgICAgIGNvbnN0IG5lZWRsZSA9IG9wdGlvbnMuc291cmNlLnRvTG93ZXJDYXNlKCk7XG4gICAgICBlbnRyaWVzID0gZW50cmllcy5maWx0ZXIoZSA9PiBlLnNvdXJjZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG5lZWRsZSkpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucz8ubWVzc2FnZSkge1xuICAgICAgY29uc3QgbmVlZGxlID0gb3B0aW9ucy5tZXNzYWdlLnRvTG93ZXJDYXNlKCk7XG4gICAgICBlbnRyaWVzID0gZW50cmllcy5maWx0ZXIoZSA9PiBlLm1lc3NhZ2UudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhuZWVkbGUpKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnM/LnNpbmNlKSB7XG4gICAgICBjb25zdCBzaW5jZSA9IG9wdGlvbnMuc2luY2U7XG4gICAgICBlbnRyaWVzID0gZW50cmllcy5maWx0ZXIoZSA9PiBlLnRpbWVzdGFtcCA+IHNpbmNlKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnM/LnVudGlsKSB7XG4gICAgICBjb25zdCB1bnRpbCA9IG9wdGlvbnMudW50aWw7XG4gICAgICBlbnRyaWVzID0gZW50cmllcy5maWx0ZXIoZSA9PiBlLnRpbWVzdGFtcCA8IHVudGlsKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnM/LmNvcnJlbGF0aW9uSWQpIHtcbiAgICAgIGNvbnN0IGNvcnJJZCA9IG9wdGlvbnMuY29ycmVsYXRpb25JZDtcbiAgICAgIGVudHJpZXMgPSBlbnRyaWVzLmZpbHRlcihlID0+IGUuY29ycmVsYXRpb25JZCA9PT0gY29ycklkKTtcbiAgICB9XG5cbiAgICAvLyA0LiBDb3VudCB0b3RhbCBiZWZvcmUgcGFnaW5hdGlvblxuICAgIGNvbnN0IHRvdGFsID0gZW50cmllcy5sZW5ndGg7XG5cbiAgICAvLyA1LiBTb3J0IG5ld2VzdC1maXJzdCAoZGVzY2VuZGluZyB0aW1lc3RhbXApXG4gICAgZW50cmllcy5zb3J0KChhLCBiKSA9PiAoYS50aW1lc3RhbXAgPiBiLnRpbWVzdGFtcCA/IC0xIDogYS50aW1lc3RhbXAgPCBiLnRpbWVzdGFtcCA/IDEgOiAwKSk7XG5cbiAgICAvLyA2LiBQYWdpbmF0ZVxuICAgIGVudHJpZXMgPSBlbnRyaWVzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgbGltaXQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVudHJpZXMsXG4gICAgICB0b3RhbCxcbiAgICAgIGhhc01vcmU6IG9mZnNldCArIGxpbWl0IDwgdG90YWwsXG4gICAgICBsaW1pdCxcbiAgICAgIG9mZnNldCxcbiAgICB9O1xuICB9XG5cbiAgZ2V0U3RhdHMoKTogUmVjb3JkPExvZ0NhdGVnb3J5LCB7IHNpemU6IG51bWJlcjsgY2FwYWNpdHk6IG51bWJlcjsgZXZpY3Rpb25zOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHN0YXRzID0ge30gYXMgUmVjb3JkPExvZ0NhdGVnb3J5LCB7IHNpemU6IG51bWJlcjsgY2FwYWNpdHk6IG51bWJlcjsgZXZpY3Rpb25zOiBudW1iZXIgfT47XG4gICAgZm9yIChjb25zdCBbY2F0ZWdvcnksIHF1ZXVlXSBvZiB0aGlzLnF1ZXVlcykge1xuICAgICAgc3RhdHNbY2F0ZWdvcnldID0ge1xuICAgICAgICBzaXplOiBxdWV1ZS5zaXplLFxuICAgICAgICBjYXBhY2l0eTogcXVldWUuY2FwYWNpdHksXG4gICAgICAgIGV2aWN0aW9uczogdGhpcy5ldmljdGlvbkNvdW50cy5nZXQoY2F0ZWdvcnkpID8/IDAsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gc3RhdHM7XG4gIH1cbn1cbiJdfQ==