@dollhousemcp/mcp-server 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,8 @@
2
2
  * Auto-generated file - DO NOT EDIT
3
3
  * Generated at build time by scripts/generate-version.js
4
4
  */
5
- export const PACKAGE_VERSION = '2.0.0';
6
- export const BUILD_TIMESTAMP = '2026-04-01T23:24:54.345Z';
5
+ export const PACKAGE_VERSION = '2.0.1';
6
+ export const BUILD_TIMESTAMP = '2026-04-02T00:00:54.478Z';
7
7
  export const BUILD_TYPE = 'npm';
8
8
  export const PACKAGE_NAME = '@dollhousemcp/mcp-server';
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZWQvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUMxRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEtBQUssQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGZpbGUgLSBETyBOT1QgRURJVFxuICogR2VuZXJhdGVkIGF0IGJ1aWxkIHRpbWUgYnkgc2NyaXB0cy9nZW5lcmF0ZS12ZXJzaW9uLmpzXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9ICcyLjAuMCc7XG5leHBvcnQgY29uc3QgQlVJTERfVElNRVNUQU1QID0gJzIwMjYtMDQtMDFUMjM6MjQ6NTQuMzQ1Wic7XG5leHBvcnQgY29uc3QgQlVJTERfVFlQRTogJ25wbScgfCAnZ2l0JyA9ICducG0nO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9ICdAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXInO1xuIl19
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZWQvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUMxRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEtBQUssQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGZpbGUgLSBETyBOT1QgRURJVFxuICogR2VuZXJhdGVkIGF0IGJ1aWxkIHRpbWUgYnkgc2NyaXB0cy9nZW5lcmF0ZS12ZXJzaW9uLmpzXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9ICcyLjAuMSc7XG5leHBvcnQgY29uc3QgQlVJTERfVElNRVNUQU1QID0gJzIwMjYtMDQtMDJUMDA6MDA6NTQuNDc4Wic7XG5leHBvcnQgY29uc3QgQlVJTERfVFlQRTogJ25wbScgfCAnZ2l0JyA9ICducG0nO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfTkFNRSA9ICdAZG9sbGhvdXNlbWNwL21jcC1zZXJ2ZXInO1xuIl19
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SSE-based real-time log viewer sink.
3
+ *
4
+ * Implements ILogSink and runs an opt-in Express HTTP server that:
5
+ * - Serves a browser-based log viewer at GET /
6
+ * - Streams log entries via SSE at GET /logs/stream
7
+ * - Exposes a JSON query endpoint at GET /logs (delegates to MemoryLogSink)
8
+ * - Provides a health endpoint at GET /health
9
+ *
10
+ * See docs/LOGGING-DESIGN.md §4.6 for the full design.
11
+ */
12
+ import type { ILogSink, UnifiedLogEntry } from '../types.js';
13
+ import type { MemoryLogSink } from './MemoryLogSink.js';
14
+ export interface SSELogSinkOptions {
15
+ port: number;
16
+ memorySink: MemoryLogSink;
17
+ }
18
+ export declare class SSELogSink implements ILogSink {
19
+ private readonly app;
20
+ private server;
21
+ private readonly clients;
22
+ private readonly memorySink;
23
+ private readonly port;
24
+ private readonly startTime;
25
+ constructor(options: SSELogSinkOptions);
26
+ write(entry: UnifiedLogEntry): void;
27
+ flush(): Promise<void>;
28
+ close(): Promise<void>;
29
+ start(): Promise<void>;
30
+ get clientCount(): number;
31
+ getPort(): number;
32
+ private setupRoutes;
33
+ private matchesFilter;
34
+ }
35
+ //# sourceMappingURL=SSELogSink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSELogSink.d.ts","sourceRoot":"","sources":["../../../src/logging/sinks/SSELogSink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAyB,MAAM,aAAa,CAAC;AAEpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,aAAa,CAAC;CAC3B;AAcD,qBAAa,UAAW,YAAW,QAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IACjD,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAE5B,OAAO,EAAE,iBAAiB;IAWtC,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAQ7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,OAAO,IAAI,MAAM;IAWjB,OAAO,CAAC,WAAW;IA4FnB,OAAO,CAAC,aAAa;CAkBtB"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * SSE-based real-time log viewer sink.
3
+ *
4
+ * Implements ILogSink and runs an opt-in Express HTTP server that:
5
+ * - Serves a browser-based log viewer at GET /
6
+ * - Streams log entries via SSE at GET /logs/stream
7
+ * - Exposes a JSON query endpoint at GET /logs (delegates to MemoryLogSink)
8
+ * - Provides a health endpoint at GET /health
9
+ *
10
+ * See docs/LOGGING-DESIGN.md §4.6 for the full design.
11
+ */
12
+ import express from 'express';
13
+ import { LOG_LEVEL_PRIORITY } from '../types.js';
14
+ import { getViewerHtml } from '../viewer/viewerHtml.js';
15
+ export class SSELogSink {
16
+ app;
17
+ server = null;
18
+ clients = new Set();
19
+ memorySink;
20
+ port;
21
+ startTime = Date.now();
22
+ constructor(options) {
23
+ this.port = options.port;
24
+ this.memorySink = options.memorySink;
25
+ this.app = express();
26
+ this.setupRoutes();
27
+ }
28
+ // ---------------------------------------------------------------------------
29
+ // ILogSink
30
+ // ---------------------------------------------------------------------------
31
+ write(entry) {
32
+ for (const client of this.clients) {
33
+ if (this.matchesFilter(entry, client.filter)) {
34
+ client.res.write(`data: ${JSON.stringify(entry)}\n\n`);
35
+ }
36
+ }
37
+ }
38
+ async flush() {
39
+ // No-op — SSE writes are immediate.
40
+ }
41
+ async close() {
42
+ // End all client connections
43
+ for (const client of this.clients) {
44
+ client.res.end();
45
+ }
46
+ this.clients.clear();
47
+ // Shut down HTTP server
48
+ if (this.server) {
49
+ await new Promise((resolve) => {
50
+ this.server.close(() => resolve());
51
+ });
52
+ this.server = null;
53
+ }
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Lifecycle
57
+ // ---------------------------------------------------------------------------
58
+ async start() {
59
+ return new Promise((resolve) => {
60
+ this.server = this.app.listen(this.port, '127.0.0.1', () => {
61
+ this.server.unref();
62
+ resolve();
63
+ });
64
+ });
65
+ }
66
+ get clientCount() {
67
+ return this.clients.size;
68
+ }
69
+ getPort() {
70
+ if (!this.server)
71
+ return this.port;
72
+ const addr = this.server.address();
73
+ if (addr && typeof addr === 'object')
74
+ return addr.port;
75
+ return this.port;
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // Routes
79
+ // ---------------------------------------------------------------------------
80
+ setupRoutes() {
81
+ // Viewer HTML
82
+ this.app.get('/', (_req, res) => {
83
+ const actualPort = this.getPort();
84
+ res.type('html').send(getViewerHtml(actualPort));
85
+ });
86
+ // SSE stream
87
+ this.app.get('/logs/stream', (req, res) => {
88
+ res.writeHead(200, {
89
+ 'Content-Type': 'text/event-stream',
90
+ 'Cache-Control': 'no-cache',
91
+ 'Connection': 'keep-alive',
92
+ });
93
+ res.write(':connected\n\n');
94
+ const filter = {};
95
+ if (typeof req.query['category'] === 'string' && req.query['category']) {
96
+ filter.category = req.query['category'];
97
+ }
98
+ if (typeof req.query['level'] === 'string' && req.query['level']) {
99
+ filter.level = req.query['level'];
100
+ }
101
+ if (typeof req.query['source'] === 'string' && req.query['source']) {
102
+ filter.source = req.query['source'];
103
+ }
104
+ if (typeof req.query['correlationId'] === 'string' && req.query['correlationId']) {
105
+ filter.correlationId = req.query['correlationId'];
106
+ }
107
+ const client = { res, filter };
108
+ this.clients.add(client);
109
+ // Backfill recent history so the viewer shows context on connect
110
+ const history = this.memorySink.query({ category: 'all', limit: 500 });
111
+ // Send oldest-first so the viewer displays in chronological order
112
+ const entries = history.entries.slice().reverse();
113
+ for (const entry of entries) {
114
+ res.write(`data: ${JSON.stringify(entry)}\n\n`);
115
+ }
116
+ req.on('close', () => {
117
+ this.clients.delete(client);
118
+ });
119
+ });
120
+ // JSON query (delegates to MemoryLogSink)
121
+ this.app.get('/logs', (req, res) => {
122
+ const options = {};
123
+ if (typeof req.query['category'] === 'string' && req.query['category']) {
124
+ options['category'] = req.query['category'];
125
+ }
126
+ if (typeof req.query['level'] === 'string' && req.query['level']) {
127
+ options['level'] = req.query['level'];
128
+ }
129
+ if (typeof req.query['source'] === 'string' && req.query['source']) {
130
+ options['source'] = req.query['source'];
131
+ }
132
+ if (typeof req.query['message'] === 'string' && req.query['message']) {
133
+ options['message'] = req.query['message'];
134
+ }
135
+ if (typeof req.query['limit'] === 'string') {
136
+ options['limit'] = parseInt(req.query['limit'], 10);
137
+ }
138
+ if (typeof req.query['offset'] === 'string') {
139
+ options['offset'] = parseInt(req.query['offset'], 10);
140
+ }
141
+ if (typeof req.query['since'] === 'string' && req.query['since']) {
142
+ options['since'] = req.query['since'];
143
+ }
144
+ if (typeof req.query['until'] === 'string' && req.query['until']) {
145
+ options['until'] = req.query['until'];
146
+ }
147
+ const result = this.memorySink.query(options);
148
+ res.json(result);
149
+ });
150
+ // Health
151
+ this.app.get('/health', (_req, res) => {
152
+ res.json({
153
+ status: 'ok',
154
+ clients: this.clientCount,
155
+ uptime: Math.floor((Date.now() - this.startTime) / 1000),
156
+ });
157
+ });
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Filter matching
161
+ // ---------------------------------------------------------------------------
162
+ matchesFilter(entry, filter) {
163
+ if (filter.category && entry.category !== filter.category) {
164
+ return false;
165
+ }
166
+ if (filter.level && LOG_LEVEL_PRIORITY[entry.level] < LOG_LEVEL_PRIORITY[filter.level]) {
167
+ return false;
168
+ }
169
+ if (filter.source) {
170
+ const needle = filter.source.toLowerCase();
171
+ if (!entry.source.toLowerCase().includes(needle)) {
172
+ return false;
173
+ }
174
+ }
175
+ if (filter.correlationId && entry.correlationId !== filter.correlationId) {
176
+ return false;
177
+ }
178
+ return true;
179
+ }
180
+ }
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU1NFTG9nU2luay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sb2dnaW5nL3NpbmtzL1NTRUxvZ1NpbmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUVILE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUk5QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFakQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBbUJ4RCxNQUFNLE9BQU8sVUFBVTtJQUNKLEdBQUcsQ0FBNkI7SUFDekMsTUFBTSxHQUFrQixJQUFJLENBQUM7SUFDcEIsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFhLENBQUM7SUFDL0IsVUFBVSxDQUFnQjtJQUMxQixJQUFJLENBQVM7SUFDYixTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBRXhDLFlBQVksT0FBMEI7UUFDcEMsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUNyQyxJQUFJLENBQUMsR0FBRyxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLFdBQVc7SUFDWCw4RUFBOEU7SUFFOUUsS0FBSyxDQUFDLEtBQXNCO1FBQzFCLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQVMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFD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Q0FBQztZQUNmLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsYUFBYSxJQUFJLEtBQUssQ0FBQyxhQUFhLEtBQUssTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pFLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTU0UtYmFzZWQgcmVhbC10aW1lIGxvZyB2aWV3ZXIgc2luay5cbiAqXG4gKiBJbXBsZW1lbnRzIElMb2dTaW5rIGFuZCBydW5zIGFuIG9wdC1pbiBFeHByZXNzIEhUVFAgc2VydmVyIHRoYXQ6XG4gKiAtIFNlcnZlcyBhIGJyb3dzZXItYmFzZWQgbG9nIHZpZXdlciBhdCBHRVQgL1xuICogLSBTdHJlYW1zIGxvZyBlbnRyaWVzIHZpYSBTU0UgYXQgR0VUIC9sb2dzL3N0cmVhbVxuICogLSBFeHBvc2VzIGEgSlNPTiBxdWVyeSBlbmRwb2ludCBhdCBHRVQgL2xvZ3MgKGRlbGVnYXRlcyB0byBNZW1vcnlMb2dTaW5rKVxuICogLSBQcm92aWRlcyBhIGhlYWx0aCBlbmRwb2ludCBhdCBHRVQgL2hlYWx0aFxuICpcbiAqIFNlZSBkb2NzL0xPR0dJTkctREVTSUdOLm1kIMKnNC42IGZvciB0aGUgZnVsbCBkZXNpZ24uXG4gKi9cblxuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHR5cGUgeyBJTG9nU2luaywgVW5pZmllZExvZ0VudHJ5LCBMb2dDYXRlZ29yeSwgTG9nTGV2ZWwgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBMT0dfTEVWRUxfUFJJT1JJVFkgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IE1lbW9yeUxvZ1NpbmsgfSBmcm9tICcuL01lbW9yeUxvZ1NpbmsuanMnO1xuaW1wb3J0IHsgZ2V0Vmlld2VySHRtbCB9IGZyb20gJy4uL3ZpZXdlci92aWV3ZXJIdG1sLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBTU0VMb2dTaW5rT3B0aW9ucyB7XG4gIHBvcnQ6IG51bWJlcjtcbiAgbWVtb3J5U2luazogTWVtb3J5TG9nU2luaztcbn1cblxuaW50ZXJmYWNlIFNTRUNsaWVudEZpbHRlciB7XG4gIGNhdGVnb3J5PzogTG9nQ2F0ZWdvcnk7XG4gIGxldmVsPzogTG9nTGV2ZWw7XG4gIHNvdXJjZT86IHN0cmluZztcbiAgY29ycmVsYXRpb25JZD86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFNTRUNsaWVudCB7XG4gIHJlczogUmVzcG9uc2U7XG4gIGZpbHRlcjogU1NFQ2xpZW50RmlsdGVyO1xufVxuXG5leHBvcnQgY2xhc3MgU1NFTG9nU2luayBpbXBsZW1lbnRzIElMb2dTaW5rIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhcHA6IFJldHVyblR5cGU8dHlwZW9mIGV4cHJlc3M+O1xuICBwcml2YXRlIHNlcnZlcjogU2VydmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50cyA9IG5ldyBTZXQ8U1NFQ2xpZW50PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG1lbW9yeVNpbms6IE1lbW9yeUxvZ1Npbms7XG4gIHByaXZhdGUgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU1NFTG9nU2lua09wdGlvbnMpIHtcbiAgICB0aGlzLnBvcnQgPSBvcHRpb25zLnBvcnQ7XG4gICAgdGhpcy5tZW1vcnlTaW5rID0gb3B0aW9ucy5tZW1vcnlTaW5rO1xuICAgIHRoaXMuYXBwID0gZXhwcmVzcygpO1xuICAgIHRoaXMuc2V0dXBSb3V0ZXMoKTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBJTG9nU2lua1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICB3cml0ZShlbnRyeTogVW5pZmllZExvZ0VudHJ5KTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBjbGllbnQgb2YgdGhpcy5jbGllbnRzKSB7XG4gICAgICBpZiAodGhpcy5tYXRjaGVzRmlsdGVyKGVudHJ5LCBjbGllbnQuZmlsdGVyKSkge1xuICAgICAgICBjbGllbnQucmVzLndyaXRlKGBkYXRhOiAke0pTT04uc3RyaW5naWZ5KGVudHJ5KX1cXG5cXG5gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBmbHVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBOby1vcCDigJQgU1NFIHdyaXRlcyBhcmUgaW1tZWRpYXRlLlxuICB9XG5cbiAgYXN5bmMgY2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gRW5kIGFsbCBjbGllbnQgY29ubmVjdGlvbnNcbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiB0aGlzLmNsaWVudHMpIHtcbiAgICAgIGNsaWVudC5yZXMuZW5kKCk7XG4gICAgfVxuICAgIHRoaXMuY2xpZW50cy5jbGVhcigpO1xuXG4gICAgLy8gU2h1dCBkb3duIEhUVFAgc2VydmVyXG4gICAgaWYgKHRoaXMuc2VydmVyKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICB0aGlzLnNlcnZlciEuY2xvc2UoKCkgPT4gcmVzb2x2ZSgpKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5zZXJ2ZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBMaWZlY3ljbGVcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICB0aGlzLnNlcnZlciA9IHRoaXMuYXBwLmxpc3Rlbih0aGlzLnBvcnQsICcxMjcuMC4wLjEnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VydmVyIS51bnJlZigpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBjbGllbnRDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNsaWVudHMuc2l6ZTtcbiAgfVxuXG4gIGdldFBvcnQoKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuc2VydmVyKSByZXR1cm4gdGhpcy5wb3J0O1xuICAgIGNvbnN0IGFkZHIgPSB0aGlzLnNlcnZlci5hZGRyZXNzKCk7XG4gICAgaWYgKGFkZHIgJiYgdHlwZW9mIGFkZHIgPT09ICdvYmplY3QnKSByZXR1cm4gYWRkci5wb3J0O1xuICAgIHJldHVybiB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gUm91dGVzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgc2V0dXBSb3V0ZXMoKTogdm9pZCB7XG4gICAgLy8gVmlld2VyIEhUTUxcbiAgICB0aGlzLmFwcC5nZXQoJy8nLCAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgYWN0dWFsUG9ydCA9IHRoaXMuZ2V0UG9ydCgpO1xuICAgICAgcmVzLnR5cGUoJ2h0bWwnKS5zZW5kKGdldFZpZXdlckh0bWwoYWN0dWFsUG9ydCkpO1xuICAgIH0pO1xuXG4gICAgLy8gU1NFIHN0cmVhbVxuICAgIHRoaXMuYXBwLmdldCgnL2xvZ3Mvc3RyZWFtJywgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgcmVzLndyaXRlSGVhZCgyMDAsIHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L2V2ZW50LXN0cmVhbScsXG4gICAgICAgICdDYWNoZS1Db250cm9sJzogJ25vLWNhY2hlJyxcbiAgICAgICAgJ0Nvbm5lY3Rpb24nOiAna2VlcC1hbGl2ZScsXG4gICAgICB9KTtcbiAgICAgIHJlcy53cml0ZSgnOmNvbm5lY3RlZFxcblxcbicpO1xuXG4gICAgICBjb25zdCBmaWx0ZXI6IFNTRUNsaWVudEZpbHRlciA9IHt9O1xuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbJ2NhdGVnb3J5J10gPT09ICdzdHJpbmcnICYmIHJlcS5xdWVyeVsnY2F0ZWdvcnknXSkge1xuICAgICAgICBmaWx0ZXIuY2F0ZWdvcnkgPSByZXEucXVlcnlbJ2NhdGVnb3J5J10gYXMgTG9nQ2F0ZWdvcnk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHJlcS5xdWVyeVsnbGV2ZWwnXSA9PT0gJ3N0cmluZycgJiYgcmVxLnF1ZXJ5WydsZXZlbCddKSB7XG4gICAgICAgIGZpbHRlci5sZXZlbCA9IHJlcS5xdWVyeVsnbGV2ZWwnXSBhcyBMb2dMZXZlbDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcmVxLnF1ZXJ5Wydzb3VyY2UnXSA9PT0gJ3N0cmluZycgJiYgcmVxLnF1ZXJ5Wydzb3VyY2UnXSkge1xuICAgICAgICBmaWx0ZXIuc291cmNlID0gcmVxLnF1ZXJ5Wydzb3VyY2UnXTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcmVxLnF1ZXJ5Wydjb3JyZWxhdGlvbklkJ10gPT09ICdzdHJpbmcnICYmIHJlcS5xdWVyeVsnY29ycmVsYXRpb25JZCddKSB7XG4gICAgICAgIGZpbHRlci5jb3JyZWxhdGlvbklkID0gcmVxLnF1ZXJ5Wydjb3JyZWxhdGlvbklkJ107XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNsaWVudDogU1NFQ2xpZW50ID0geyByZXMsIGZpbHRlciB9O1xuICAgICAgdGhpcy5jbGllbnRzLmFkZChjbGllbnQpO1xuXG4gICAgICAvLyBCYWNrZmlsbCByZWNlbnQgaGlzdG9yeSBzbyB0aGUgdmlld2VyIHNob3dzIGNvbnRleHQgb24gY29ubmVjdFxuICAgICAgY29uc3QgaGlzdG9yeSA9IHRoaXMubWVtb3J5U2luay5xdWVyeSh7IGNhdGVnb3J5OiAnYWxsJywgbGltaXQ6IDUwMCB9KTtcbiAgICAgIC8vIFNlbmQgb2xkZXN0LWZpcnN0IHNvIHRoZSB2aWV3ZXIgZGlzcGxheXMgaW4gY2hyb25vbG9naWNhbCBvcmRlclxuICAgICAgY29uc3QgZW50cmllcyA9IGhpc3RvcnkuZW50cmllcy5zbGljZSgpLnJldmVyc2UoKTtcbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICByZXMud3JpdGUoYGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkoZW50cnkpfVxcblxcbmApO1xuICAgICAgfVxuXG4gICAgICByZXEub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEpTT04gcXVlcnkgKGRlbGVnYXRlcyB0byBNZW1vcnlMb2dTaW5rKVxuICAgIHRoaXMuYXBwLmdldCgnL2xvZ3MnLCAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbJ2NhdGVnb3J5J10gPT09ICdzdHJpbmcnICYmIHJlcS5xdWVyeVsnY2F0ZWdvcnknXSkge1xuICAgICAgICBvcHRpb25zWydjYXRlZ29yeSddID0gcmVxLnF1ZXJ5WydjYXRlZ29yeSddO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbJ2xldmVsJ10gPT09ICdzdHJpbmcnICYmIHJlcS5xdWVyeVsnbGV2ZWwnXSkge1xuICAgICAgICBvcHRpb25zWydsZXZlbCddID0gcmVxLnF1ZXJ5WydsZXZlbCddO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbJ3NvdXJjZSddID09PSAnc3RyaW5nJyAmJiByZXEucXVlcnlbJ3NvdXJjZSddKSB7XG4gICAgICAgIG9wdGlvbnNbJ3NvdXJjZSddID0gcmVxLnF1ZXJ5Wydzb3VyY2UnXTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcmVxLnF1ZXJ5WydtZXNzYWdlJ10gPT09ICdzdHJpbmcnICYmIHJlcS5xdWVyeVsnbWVzc2FnZSddKSB7XG4gICAgICAgIG9wdGlvbnNbJ21lc3NhZ2UnXSA9IHJlcS5xdWVyeVsnbWVzc2FnZSddO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbJ2xpbWl0J10gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG9wdGlvbnNbJ2xpbWl0J10gPSBwYXJzZUludChyZXEucXVlcnlbJ2xpbWl0J10sIDEwKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcmVxLnF1ZXJ5WydvZmZzZXQnXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgb3B0aW9uc1snb2Zmc2V0J10gPSBwYXJzZUludChyZXEucXVlcnlbJ29mZnNldCddLCAxMCk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHJlcS5xdWVyeVsnc2luY2UnXSA9PT0gJ3N0cmluZycgJiYgcmVxLnF1ZXJ5WydzaW5jZSddKSB7XG4gICAgICAgIG9wdGlvbnNbJ3NpbmNlJ10gPSByZXEucXVlcnlbJ3NpbmNlJ107XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHJlcS5xdWVyeVsndW50aWwnXSA9PT0gJ3N0cmluZycgJiYgcmVxLnF1ZXJ5Wyd1bnRpbCddKSB7XG4gICAgICAgIG9wdGlvbnNbJ3VudGlsJ10gPSByZXEucXVlcnlbJ3VudGlsJ107XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMubWVtb3J5U2luay5xdWVyeShvcHRpb25zKTtcbiAgICAgIHJlcy5qc29uKHJlc3VsdCk7XG4gICAgfSk7XG5cbiAgICAvLyBIZWFsdGhcbiAgICB0aGlzLmFwcC5nZXQoJy9oZWFsdGgnLCAoX3JlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgICAgcmVzLmpzb24oe1xuICAgICAgICBzdGF0dXM6ICdvaycsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50Q291bnQsXG4gICAgICAgIHVwdGltZTogTWF0aC5mbG9vcigoRGF0ZS5ub3coKSAtIHRoaXMuc3RhcnRUaW1lKSAvIDEwMDApLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gRmlsdGVyIG1hdGNoaW5nXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgbWF0Y2hlc0ZpbHRlcihlbnRyeTogVW5pZmllZExvZ0VudHJ5LCBmaWx0ZXI6IFNTRUNsaWVudEZpbHRlcik6IGJvb2xlYW4ge1xuICAgIGlmIChmaWx0ZXIuY2F0ZWdvcnkgJiYgZW50cnkuY2F0ZWdvcnkgIT09IGZpbHRlci5jYXRlZ29yeSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZmlsdGVyLmxldmVsICYmIExPR19MRVZFTF9QUklPUklUWVtlbnRyeS5sZXZlbF0gPCBMT0dfTEVWRUxfUFJJT1JJVFlbZmlsdGVyLmxldmVsXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZmlsdGVyLnNvdXJjZSkge1xuICAgICAgY29uc3QgbmVlZGxlID0gZmlsdGVyLnNvdXJjZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKCFlbnRyeS5zb3VyY2UudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhuZWVkbGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGZpbHRlci5jb3JyZWxhdGlvbklkICYmIGVudHJ5LmNvcnJlbGF0aW9uSWQgIT09IGZpbHRlci5jb3JyZWxhdGlvbklkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Embedded HTML template for the DollhouseMCP Log Viewer.
3
+ *
4
+ * Returns a self-contained vanilla JS/CSS page that connects to the
5
+ * SSELogSink's /logs/stream endpoint via EventSource. See docs/LOGGING-DESIGN.md §4.6.
6
+ */
7
+ export declare function getViewerHtml(port: number): string;
8
+ //# sourceMappingURL=viewerHtml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewerHtml.d.ts","sourceRoot":"","sources":["../../../src/logging/viewer/viewerHtml.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoMlD"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Embedded HTML template for the DollhouseMCP Log Viewer.
3
+ *
4
+ * Returns a self-contained vanilla JS/CSS page that connects to the
5
+ * SSELogSink's /logs/stream endpoint via EventSource. See docs/LOGGING-DESIGN.md §4.6.
6
+ */
7
+ export function getViewerHtml(port) {
8
+ return /* html */ `<!DOCTYPE html>
9
+ <html lang="en">
10
+ <head>
11
+ <meta charset="utf-8">
12
+ <meta name="viewport" content="width=device-width,initial-scale=1">
13
+ <title>DollhouseMCP Log Viewer</title>
14
+ <style>
15
+ *{box-sizing:border-box;margin:0;padding:0}
16
+ body{background:#1a1a2e;color:#e0e0e0;font-family:'Cascadia Code','Fira Code',monospace;font-size:13px}
17
+ #controls{display:flex;gap:8px;padding:8px 12px;background:#16213e;border-bottom:1px solid #0f3460;align-items:center;flex-wrap:wrap}
18
+ #controls label{color:#94a3b8;font-size:12px}
19
+ #controls select,#controls input{background:#1a1a2e;color:#e0e0e0;border:1px solid #0f3460;border-radius:4px;padding:4px 8px;font-family:inherit;font-size:12px}
20
+ #controls select:focus,#controls input:focus{outline:none;border-color:#e94560}
21
+ button{background:#0f3460;color:#e0e0e0;border:1px solid #0f3460;border-radius:4px;padding:4px 12px;cursor:pointer;font-family:inherit;font-size:12px}
22
+ button:hover{background:#e94560;border-color:#e94560}
23
+ #status{margin-left:auto;font-size:11px;padding:2px 8px;border-radius:10px}
24
+ .connected{background:#064e3b;color:#6ee7b7}
25
+ .disconnected{background:#7f1d1d;color:#fca5a5}
26
+ .paused{background:#78350f;color:#fcd34d}
27
+ #log{overflow-y:auto;height:calc(100vh - 44px);padding:8px 12px}
28
+ .entry{padding:2px 0;white-space:pre-wrap;word-break:break-word;border-bottom:1px solid #1e293b}
29
+ .entry:hover{background:#16213e}
30
+ .lvl-error{color:#f87171}
31
+ .lvl-warn{color:#fbbf24}
32
+ .lvl-info{color:#60a5fa}
33
+ .lvl-debug{color:#9ca3af}
34
+ .ts{color:#64748b}
35
+ .cat{color:#a78bfa}
36
+ .src{color:#2dd4bf}
37
+ .cid{color:#f472b6;font-size:11px;display:inline-block;width:72px;text-align:right;margin-right:4px}
38
+ #search{margin-left:4px}
39
+ </style>
40
+ </head>
41
+ <body>
42
+ <div id="controls">
43
+ <label>Category
44
+ <select id="fCategory">
45
+ <option value="">all</option>
46
+ <option value="application">application</option>
47
+ <option value="security">security</option>
48
+ <option value="performance">performance</option>
49
+ <option value="telemetry">telemetry</option>
50
+ </select>
51
+ </label>
52
+ <label>Level
53
+ <select id="fLevel">
54
+ <option value="">all</option>
55
+ <option value="debug">debug</option>
56
+ <option value="info">info</option>
57
+ <option value="warn">warn</option>
58
+ <option value="error">error</option>
59
+ </select>
60
+ </label>
61
+ <label>Source <input id="fSource" placeholder="substring" size="14"></label>
62
+ <label>RequestId <input id="fCorrelationId" placeholder="correlationId" size="20"></label>
63
+ <label>Search <input id="search" placeholder="message filter" size="18"></label>
64
+ <button id="btnPause">Pause</button>
65
+ <button id="btnClear">Clear</button>
66
+ <span id="status" class="disconnected">disconnected</span>
67
+ </div>
68
+ <div id="log"></div>
69
+ <script>
70
+ (function(){
71
+ var BASE = 'http://127.0.0.1:${port}';
72
+ var MAX_ENTRIES = 1000;
73
+ var log = document.getElementById('log');
74
+ var status = document.getElementById('status');
75
+ var fCategory = document.getElementById('fCategory');
76
+ var fLevel = document.getElementById('fLevel');
77
+ var fSource = document.getElementById('fSource');
78
+ var fCorrelationId = document.getElementById('fCorrelationId');
79
+ var searchBox = document.getElementById('search');
80
+ var btnPause = document.getElementById('btnPause');
81
+ var btnClear = document.getElementById('btnClear');
82
+ var es = null;
83
+ var paused = false;
84
+ var buffer = [];
85
+
86
+ function escHtml(s){
87
+ var d = document.createElement('div');
88
+ d.appendChild(document.createTextNode(s));
89
+ return d.innerHTML;
90
+ }
91
+
92
+ function setStatus(s, cls){
93
+ status.textContent = s;
94
+ status.className = cls;
95
+ }
96
+
97
+
98
+
99
+ var LEVEL_ORDER = {debug:0, info:1, warn:2, error:3};
100
+
101
+ function matchesFilters(entry){
102
+ var cat = fCategory.value;
103
+ if(cat && entry.category !== cat) return false;
104
+ var lvl = fLevel.value;
105
+ if(lvl && (LEVEL_ORDER[entry.level]||0) < (LEVEL_ORDER[lvl]||0)) return false;
106
+ var src = fSource.value.toLowerCase();
107
+ if(src && (!entry.source || entry.source.toLowerCase().indexOf(src) === -1)) return false;
108
+ var cid = fCorrelationId.value;
109
+ if(cid && entry.correlationId !== cid) return false;
110
+ var needle = searchBox.value.toLowerCase();
111
+ if(needle && (!entry.message || entry.message.toLowerCase().indexOf(needle) === -1)) return false;
112
+ return true;
113
+ }
114
+
115
+ function refilter(){
116
+ var els = log.children;
117
+ for(var i = 0; i < els.length; i++){
118
+ var data = els[i]._entryData;
119
+ if(data){
120
+ els[i].style.display = matchesFilters(data) ? '' : 'none';
121
+ }
122
+ }
123
+ }
124
+
125
+ function addEntry(entry){
126
+ if(!matchesFilters(entry)) var hidden = true;
127
+
128
+ var el = document.createElement('div');
129
+ el.className = 'entry lvl-' + entry.level;
130
+ el._entryData = entry;
131
+ if(hidden) el.style.display = 'none';
132
+ var ts = entry.timestamp ? entry.timestamp.slice(11, 23) : '';
133
+ var cid = entry.correlationId ? entry.correlationId.slice(-8) : '';
134
+ el.innerHTML = '<span class="ts">' + escHtml(ts) + '</span> '
135
+ + '<span class="cid">' + escHtml(cid) + '</span> '
136
+ + '<span class="cat">[' + escHtml(entry.category) + ']</span> '
137
+ + '<span class="src">' + escHtml(entry.source) + '</span> '
138
+ + escHtml(entry.message);
139
+ log.appendChild(el);
140
+
141
+ while(log.children.length > MAX_ENTRIES){
142
+ log.removeChild(log.firstChild);
143
+ }
144
+ if(!hidden) log.scrollTop = log.scrollHeight;
145
+ }
146
+
147
+ function connect(){
148
+ if(es){ es.close(); }
149
+ es = new EventSource(BASE + '/logs/stream');
150
+ es.onopen = function(){ setStatus('connected', 'connected'); };
151
+ es.onmessage = function(e){
152
+ try{
153
+ var entry = JSON.parse(e.data);
154
+ if(paused){ buffer.push(entry); }
155
+ else { addEntry(entry); }
156
+ }catch(err){}
157
+ };
158
+ es.onerror = function(){ setStatus('disconnected', 'disconnected'); };
159
+ }
160
+
161
+ var filterTimer = null;
162
+ function onFilterChange(){
163
+ clearTimeout(filterTimer);
164
+ filterTimer = setTimeout(refilter, 50);
165
+ }
166
+
167
+ fCategory.addEventListener('change', onFilterChange);
168
+ fLevel.addEventListener('change', onFilterChange);
169
+ fSource.addEventListener('input', function(){
170
+ clearTimeout(filterTimer);
171
+ filterTimer = setTimeout(refilter, 400);
172
+ });
173
+ fCorrelationId.addEventListener('input', function(){
174
+ clearTimeout(filterTimer);
175
+ filterTimer = setTimeout(refilter, 400);
176
+ });
177
+ searchBox.addEventListener('input', function(){
178
+ clearTimeout(filterTimer);
179
+ filterTimer = setTimeout(refilter, 400);
180
+ });
181
+
182
+ btnPause.addEventListener('click', function(){
183
+ paused = !paused;
184
+ btnPause.textContent = paused ? 'Resume' : 'Pause';
185
+ if(paused){
186
+ setStatus('paused', 'paused');
187
+ } else {
188
+ setStatus('connected', 'connected');
189
+ buffer.forEach(addEntry);
190
+ buffer = [];
191
+ }
192
+ });
193
+
194
+ btnClear.addEventListener('click', function(){
195
+ log.innerHTML = '';
196
+ });
197
+
198
+ connect();
199
+ })();
200
+ </script>
201
+ </body>
202
+ </html>`;
203
+ }
204
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VySHRtbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9sb2dnaW5nL3ZpZXdlci92aWV3ZXJIdG1sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFZO0lBQ3hDLE9BQU8sVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7aUNBK0RhLElBQUk7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBbUk3QixDQUFDO0FBQ1QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRW1iZWRkZWQgSFRNTCB0ZW1wbGF0ZSBmb3IgdGhlIERvbGxob3VzZU1DUCBMb2cgVmlld2VyLlxuICpcbiAqIFJldHVybnMgYSBzZWxmLWNvbnRhaW5lZCB2YW5pbGxhIEpTL0NTUyBwYWdlIHRoYXQgY29ubmVjdHMgdG8gdGhlXG4gKiBTU0VMb2dTaW5rJ3MgL2xvZ3Mvc3RyZWFtIGVuZHBvaW50IHZpYSBFdmVudFNvdXJjZS4gU2VlIGRvY3MvTE9HR0lORy1ERVNJR04ubWQgwqc0LjYuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZpZXdlckh0bWwocG9ydDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIC8qIGh0bWwgKi8gYDwhRE9DVFlQRSBodG1sPlxuPGh0bWwgbGFuZz1cImVuXCI+XG48aGVhZD5cbjxtZXRhIGNoYXJzZXQ9XCJ1dGYtOFwiPlxuPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCxpbml0aWFsLXNjYWxlPTFcIj5cbjx0aXRsZT5Eb2xsaG91c2VNQ1AgTG9nIFZpZXdlcjwvdGl0bGU+XG48c3R5bGU+XG4qe2JveC1zaXppbmc6Ym9yZGVyLWJveDttYXJnaW46MDtwYWRkaW5nOjB9XG5ib2R5e2JhY2tncm91bmQ6IzFhMWEyZTtjb2xvcjojZTBlMGUwO2ZvbnQtZmFtaWx5OidDYXNjYWRpYSBDb2RlJywnRmlyYSBDb2RlJyxtb25vc3BhY2U7Zm9udC1zaXplOjEzcHh9XG4jY29udHJvbHN7ZGlzcGxheTpmbGV4O2dhcDo4cHg7cGFkZGluZzo4cHggMTJweDtiYWNrZ3JvdW5kOiMxNjIxM2U7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgIzBmMzQ2MDthbGlnbi1pdGVtczpjZW50ZXI7ZmxleC13cmFwOndyYXB9XG4jY29udHJvbHMgbGFiZWx7Y29sb3I6Izk0YTNiODtmb250LXNpemU6MTJweH1cbiNjb250cm9scyBzZWxlY3QsI2NvbnRyb2xzIGlucHV0e2JhY2tncm91bmQ6IzFhMWEyZTtjb2xvcjojZTBlMGUwO2JvcmRlcjoxcHggc29saWQgIzBmMzQ2MDtib3JkZXItcmFkaXVzOjRweDtwYWRkaW5nOjRweCA4cHg7Zm9udC1mYW1pbHk6aW5oZXJpdDtmb250LXNpemU6MTJweH1cbiNjb250cm9scyBzZWxlY3Q6Zm9jdXMsI2NvbnRyb2xzIGlucHV0OmZvY3Vze291dGxpbmU6bm9uZTtib3JkZXItY29sb3I6I2U5NDU2MH1cbmJ1dHRvbntiYWNrZ3JvdW5kOiMwZjM0NjA7Y29sb3I6I2UwZTBlMDtib3JkZXI6MXB4IHNvbGlkICMwZjM0NjA7Ym9yZGVyLXJhZGl1czo0cHg7cGFkZGluZzo0cHggMTJweDtjdXJzb3I6cG9pbnRlcjtmb250LWZhbWlseTppbmhlcml0O2ZvbnQtc2l6ZToxMnB4fVxuYnV0dG9uOmhvdmVye2JhY2tncm91bmQ6I2U5NDU2MDtib3JkZXItY29sb3I6I2U5NDU2MH1cbiNzdGF0dXN7bWFyZ2luLWxlZnQ6YXV0bztmb250LXNpemU6MTFweDtwYWRkaW5nOjJweCA4cHg7Ym9yZGVyLXJhZGl1czoxMHB4fVxuLmNvbm5lY3RlZHtiYWNrZ3JvdW5kOiMwNjRlM2I7Y29sb3I6IzZlZTdiN31cbi5kaXNjb25uZWN0ZWR7YmFja2dyb3VuZDojN2YxZDFkO2NvbG9yOiNmY2E1YTV9XG4ucGF1c2Vke2JhY2tncm91bmQ6Izc4MzUwZjtjb2xvcjojZmNkMzRkfVxuI2xvZ3tvdmVyZmxvdy15OmF1dG87aGVpZ2h0OmNhbGMoMTAwdmggLSA0NHB4KTtwYWRkaW5nOjhweCAxMnB4fVxuLmVudHJ5e3BhZGRpbmc6MnB4IDA7d2hpdGUtc3BhY2U6cHJlLXdyYXA7d29yZC1icmVhazpicmVhay13b3JkO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICMxZTI5M2J9XG4uZW50cnk6aG92ZXJ7YmFja2dyb3VuZDojMTYyMTNlfVxuLmx2bC1lcnJvcntjb2xvcjojZjg3MTcxfVxuLmx2bC13YXJue2NvbG9yOiNmYmJmMjR9XG4ubHZsLWluZm97Y29sb3I6IzYwYTVmYX1cbi5sdmwtZGVidWd7Y29sb3I6IzljYTNhZn1cbi50c3tjb2xvcjojNjQ3NDhifVxuLmNhdHtjb2xvcjojYTc4YmZhfVxuLnNyY3tjb2xvcjojMmRkNGJmfVxuLmNpZHtjb2xvcjojZjQ3MmI2O2ZvbnQtc2l6ZToxMXB4O2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjcycHg7dGV4dC1hbGlnbjpyaWdodDttYXJnaW4tcmlnaHQ6NHB4fVxuI3NlYXJjaHttYXJnaW4tbGVmdDo0cHh9XG48L3N0eWxlPlxuPC9oZWFkPlxuPGJvZHk+XG48ZGl2IGlkPVwiY29udHJvbHNcIj5cbiAgPGxhYmVsPkNhdGVnb3J5XG4gICAgPHNlbGVjdCBpZD1cImZDYXRlZ29yeVwiPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPmFsbDwvb3B0aW9uPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cImFwcGxpY2F0aW9uXCI+YXBwbGljYXRpb248L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9XCJzZWN1cml0eVwiPnNlY3VyaXR5PC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwicGVyZm9ybWFuY2VcIj5wZXJmb3JtYW5jZTwvb3B0aW9uPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cInRlbGVtZXRyeVwiPnRlbGVtZXRyeTwvb3B0aW9uPlxuICAgIDwvc2VsZWN0PlxuICA8L2xhYmVsPlxuICA8bGFiZWw+TGV2ZWxcbiAgICA8c2VsZWN0IGlkPVwiZkxldmVsXCI+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+YWxsPC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwiZGVidWdcIj5kZWJ1Zzwvb3B0aW9uPlxuICAgICAgPG9wdGlvbiB2YWx1ZT1cImluZm9cIj5pbmZvPC9vcHRpb24+XG4gICAgICA8b3B0aW9uIHZhbHVlPVwid2FyblwiPndhcm48L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9XCJlcnJvclwiPmVycm9yPC9vcHRpb24+XG4gICAgPC9zZWxlY3Q+XG4gIDwvbGFiZWw+XG4gIDxsYWJlbD5Tb3VyY2UgPGlucHV0IGlkPVwiZlNvdXJjZVwiIHBsYWNlaG9sZGVyPVwic3Vic3RyaW5nXCIgc2l6ZT1cIjE0XCI+PC9sYWJlbD5cbiAgPGxhYmVsPlJlcXVlc3RJZCA8aW5wdXQgaWQ9XCJmQ29ycmVsYXRpb25JZFwiIHBsYWNlaG9sZGVyPVwiY29ycmVsYXRpb25JZFwiIHNpemU9XCIyMFwiPjwvbGFiZWw+XG4gIDxsYWJlbD5TZWFyY2ggPGlucHV0IGlkPVwic2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJtZXNzYWdlIGZpbHRlclwiIHNpemU9XCIxOFwiPjwvbGFiZWw+XG4gIDxidXR0b24gaWQ9XCJidG5QYXVzZVwiPlBhdXNlPC9idXR0b24+XG4gIDxidXR0b24gaWQ9XCJidG5DbGVhclwiPkNsZWFyPC9idXR0b24+XG4gIDxzcGFuIGlkPVwic3RhdHVzXCIgY2xhc3M9XCJkaXNjb25uZWN0ZWRcIj5kaXNjb25uZWN0ZWQ8L3NwYW4+XG48L2Rpdj5cbjxkaXYgaWQ9XCJsb2dcIj48L2Rpdj5cbjxzY3JpcHQ+XG4oZnVuY3Rpb24oKXtcbiAgdmFyIEJBU0UgPSAnaHR0cDovLzEyNy4wLjAuMToke3BvcnR9JztcbiAgdmFyIE1BWF9FTlRSSUVTID0gMTAwMDtcbiAgdmFyIGxvZyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2cnKTtcbiAgdmFyIHN0YXR1cyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGF0dXMnKTtcbiAgdmFyIGZDYXRlZ29yeSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmQ2F0ZWdvcnknKTtcbiAgdmFyIGZMZXZlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmTGV2ZWwnKTtcbiAgdmFyIGZTb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZlNvdXJjZScpO1xuICB2YXIgZkNvcnJlbGF0aW9uSWQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZkNvcnJlbGF0aW9uSWQnKTtcbiAgdmFyIHNlYXJjaEJveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZWFyY2gnKTtcbiAgdmFyIGJ0blBhdXNlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2J0blBhdXNlJyk7XG4gIHZhciBidG5DbGVhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdidG5DbGVhcicpO1xuICB2YXIgZXMgPSBudWxsO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG4gIHZhciBidWZmZXIgPSBbXTtcblxuICBmdW5jdGlvbiBlc2NIdG1sKHMpe1xuICAgIHZhciBkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzKSk7XG4gICAgcmV0dXJuIGQuaW5uZXJIVE1MO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0U3RhdHVzKHMsIGNscyl7XG4gICAgc3RhdHVzLnRleHRDb250ZW50ID0gcztcbiAgICBzdGF0dXMuY2xhc3NOYW1lID0gY2xzO1xuICB9XG5cblxuXG4gIHZhciBMRVZFTF9PUkRFUiA9IHtkZWJ1ZzowLCBpbmZvOjEsIHdhcm46MiwgZXJyb3I6M307XG5cbiAgZnVuY3Rpb24gbWF0Y2hlc0ZpbHRlcnMoZW50cnkpe1xuICAgIHZhciBjYXQgPSBmQ2F0ZWdvcnkudmFsdWU7XG4gICAgaWYoY2F0ICYmIGVudHJ5LmNhdGVnb3J5ICE9PSBjYXQpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgbHZsID0gZkxldmVsLnZhbHVlO1xuICAgIGlmKGx2bCAmJiAoTEVWRUxfT1JERVJbZW50cnkubGV2ZWxdfHwwKSA8IChMRVZFTF9PUkRFUltsdmxdfHwwKSkgcmV0dXJuIGZhbHNlO1xuICAgIHZhciBzcmMgPSBmU291cmNlLnZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYoc3JjICYmICghZW50cnkuc291cmNlIHx8IGVudHJ5LnNvdXJjZS50b0xvd2VyQ2FzZSgpLmluZGV4T2Yoc3JjKSA9PT0gLTEpKSByZXR1cm4gZmFsc2U7XG4gICAgdmFyIGNpZCA9IGZDb3JyZWxhdGlvbklkLnZhbHVlO1xuICAgIGlmKGNpZCAmJiBlbnRyeS5jb3JyZWxhdGlvbklkICE9PSBjaWQpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgbmVlZGxlID0gc2VhcmNoQm94LnZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYobmVlZGxlICYmICghZW50cnkubWVzc2FnZSB8fCBlbnRyeS5tZXNzYWdlLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihuZWVkbGUpID09PSAtMSkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlZmlsdGVyKCl7XG4gICAgdmFyIGVscyA9IGxvZy5jaGlsZHJlbjtcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgZWxzLmxlbmd0aDsgaSsrKXtcbiAgICAgIHZhciBkYXRhID0gZWxzW2ldLl9lbnRyeURhdGE7XG4gICAgICBpZihkYXRhKXtcbiAgICAgICAgZWxzW2ldLnN0eWxlLmRpc3BsYXkgPSBtYXRjaGVzRmlsdGVycyhkYXRhKSA/ICcnIDogJ25vbmUnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEVudHJ5KGVudHJ5KXtcbiAgICBpZighbWF0Y2hlc0ZpbHRlcnMoZW50cnkpKSB2YXIgaGlkZGVuID0gdHJ1ZTtcblxuICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGVsLmNsYXNzTmFtZSA9ICdlbnRyeSBsdmwtJyArIGVudHJ5LmxldmVsO1xuICAgIGVsLl9lbnRyeURhdGEgPSBlbnRyeTtcbiAgICBpZihoaWRkZW4pIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgdmFyIHRzID0gZW50cnkudGltZXN0YW1wID8gZW50cnkudGltZXN0YW1wLnNsaWNlKDExLCAyMykgOiAnJztcbiAgICB2YXIgY2lkID0gZW50cnkuY29ycmVsYXRpb25JZCA/IGVudHJ5LmNvcnJlbGF0aW9uSWQuc2xpY2UoLTgpIDogJyc7XG4gICAgZWwuaW5uZXJIVE1MID0gJzxzcGFuIGNsYXNzPVwidHNcIj4nICsgZXNjSHRtbCh0cykgKyAnPC9zcGFuPiAnXG4gICAgICArICc8c3BhbiBjbGFzcz1cImNpZFwiPicgKyBlc2NIdG1sKGNpZCkgKyAnPC9zcGFuPiAnXG4gICAgICArICc8c3BhbiBjbGFzcz1cImNhdFwiPlsnICsgZXNjSHRtbChlbnRyeS5jYXRlZ29yeSkgKyAnXTwvc3Bhbj4gJ1xuICAgICAgKyAnPHNwYW4gY2xhc3M9XCJzcmNcIj4nICsgZXNjSHRtbChlbnRyeS5zb3VyY2UpICsgJzwvc3Bhbj4gJ1xuICAgICAgKyBlc2NIdG1sKGVudHJ5Lm1lc3NhZ2UpO1xuICAgIGxvZy5hcHBlbmRDaGlsZChlbCk7XG5cbiAgICB3aGlsZShsb2cuY2hpbGRyZW4ubGVuZ3RoID4gTUFYX0VOVFJJRVMpe1xuICAgICAgbG9nLnJlbW92ZUNoaWxkKGxvZy5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgaWYoIWhpZGRlbikgbG9nLnNjcm9sbFRvcCA9IGxvZy5zY3JvbGxIZWlnaHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjb25uZWN0KCl7XG4gICAgaWYoZXMpeyBlcy5jbG9zZSgpOyB9XG4gICAgZXMgPSBuZXcgRXZlbnRTb3VyY2UoQkFTRSArICcvbG9ncy9zdHJlYW0nKTtcbiAgICBlcy5vbm9wZW4gPSBmdW5jdGlvbigpeyBzZXRTdGF0dXMoJ2Nvbm5lY3RlZCcsICdjb25uZWN0ZWQnKTsgfTtcbiAgICBlcy5vbm1lc3NhZ2UgPSBmdW5jdGlvbihlKXtcbiAgICAgIHRyeXtcbiAgICAgICAgdmFyIGVudHJ5ID0gSlNPTi5wYXJzZShlLmRhdGEpO1xuICAgICAgICBpZihwYXVzZWQpeyBidWZmZXIucHVzaChlbnRyeSk7IH1cbiAgICAgICAgZWxzZSB7IGFkZEVudHJ5KGVudHJ5KTsgfVxuICAgICAgfWNhdGNoKGVycil7fVxuICAgIH07XG4gICAgZXMub25lcnJvciA9IGZ1bmN0aW9uKCl7IHNldFN0YXR1cygnZGlzY29ubmVjdGVkJywgJ2Rpc2Nvbm5lY3RlZCcpOyB9O1xuICB9XG5cbiAgdmFyIGZpbHRlclRpbWVyID0gbnVsbDtcbiAgZnVuY3Rpb24gb25GaWx0ZXJDaGFuZ2UoKXtcbiAgICBjbGVhclRpbWVvdXQoZmlsdGVyVGltZXIpO1xuICAgIGZpbHRlclRpbWVyID0gc2V0VGltZW91dChyZWZpbHRlciwgNTApO1xuICB9XG5cbiAgZkNhdGVnb3J5LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIG9uRmlsdGVyQ2hhbmdlKTtcbiAgZkxldmVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIG9uRmlsdGVyQ2hhbmdlKTtcbiAgZlNvdXJjZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKCl7XG4gICAgY2xlYXJUaW1lb3V0KGZpbHRlclRpbWVyKTtcbiAgICBmaWx0ZXJUaW1lciA9IHNldFRpbWVvdXQocmVmaWx0ZXIsIDQwMCk7XG4gIH0pO1xuICBmQ29ycmVsYXRpb25JZC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKCl7XG4gICAgY2xlYXJUaW1lb3V0KGZpbHRlclRpbWVyKTtcbiAgICBmaWx0ZXJUaW1lciA9IHNldFRpbWVvdXQocmVmaWx0ZXIsIDQwMCk7XG4gIH0pO1xuICBzZWFyY2hCb3guYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCBmdW5jdGlvbigpe1xuICAgIGNsZWFyVGltZW91dChmaWx0ZXJUaW1lcik7XG4gICAgZmlsdGVyVGltZXIgPSBzZXRUaW1lb3V0KHJlZmlsdGVyLCA0MDApO1xuICB9KTtcblxuICBidG5QYXVzZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7XG4gICAgcGF1c2VkID0gIXBhdXNlZDtcbiAgICBidG5QYXVzZS50ZXh0Q29udGVudCA9IHBhdXNlZCA/ICdSZXN1bWUnIDogJ1BhdXNlJztcbiAgICBpZihwYXVzZWQpe1xuICAgICAgc2V0U3RhdHVzKCdwYXVzZWQnLCAncGF1c2VkJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldFN0YXR1cygnY29ubmVjdGVkJywgJ2Nvbm5lY3RlZCcpO1xuICAgICAgYnVmZmVyLmZvckVhY2goYWRkRW50cnkpO1xuICAgICAgYnVmZmVyID0gW107XG4gICAgfVxuICB9KTtcblxuICBidG5DbGVhci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKCl7XG4gICAgbG9nLmlubmVySFRNTCA9ICcnO1xuICB9KTtcblxuICBjb25uZWN0KCk7XG59KSgpO1xuPC9zY3JpcHQ+XG48L2JvZHk+XG48L2h0bWw+YDtcbn1cbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dollhousemcp/mcp-server",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "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.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.DollhouseMCP/mcp-server",
4
4
  "title": "DollhouseMCP",
5
5
  "description": "OSS to create Personas, Skills, Templates, Agents, and Memories to customize your AI experience.",
6
- "version": "2.0.0",
6
+ "version": "2.0.1",
7
7
  "homepage": "https://dollhousemcp.com",
8
8
  "repository": {
9
9
  "type": "git",
@@ -29,7 +29,7 @@
29
29
  {
30
30
  "registryType": "npm",
31
31
  "identifier": "@dollhousemcp/mcp-server",
32
- "version": "2.0.0",
32
+ "version": "2.0.1",
33
33
  "transport": {
34
34
  "type": "stdio"
35
35
  }