@dollhousemcp/mcp-server 2.0.0-rc.6 → 2.0.0
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.
- package/CHANGELOG.md +52 -61
- package/README.github.md +2 -2
- package/README.md +2 -2
- package/README.md.backup +284 -224
- package/README.npm.md +2 -2
- package/dist/cache/LRUCache.d.ts +3 -0
- package/dist/cache/LRUCache.d.ts.map +1 -1
- package/dist/cache/LRUCache.js +36 -26
- package/dist/config/env.d.ts +14 -4
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +20 -6
- package/dist/di/Container.d.ts +21 -0
- package/dist/di/Container.d.ts.map +1 -1
- package/dist/di/Container.js +250 -53
- package/dist/elements/BaseElement.d.ts.map +1 -1
- package/dist/elements/BaseElement.js +5 -10
- package/dist/elements/base/BaseElementManager.d.ts +22 -0
- package/dist/elements/base/BaseElementManager.d.ts.map +1 -1
- package/dist/elements/base/BaseElementManager.js +47 -7
- package/dist/elements/memories/Memory.d.ts +1 -0
- package/dist/elements/memories/Memory.d.ts.map +1 -1
- package/dist/elements/memories/Memory.js +12 -8
- package/dist/elements/memories/MemoryManager.d.ts.map +1 -1
- package/dist/elements/memories/MemoryManager.js +23 -42
- package/dist/elements/memories/MemorySearchIndex.js +2 -2
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.d.ts.map +1 -1
- package/dist/generated/version.js +3 -3
- package/dist/handlers/EnhancedIndexHandler.js +6 -6
- package/dist/handlers/element-crud/listElements.d.ts +2 -0
- package/dist/handlers/element-crud/listElements.d.ts.map +1 -1
- package/dist/handlers/element-crud/listElements.js +3 -1
- package/dist/handlers/mcp-aql/Gatekeeper.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/Gatekeeper.js +23 -17
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +14 -0
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +110 -14
- package/dist/handlers/mcp-aql/OperationRouter.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationRouter.js +13 -1
- package/dist/handlers/mcp-aql/OperationSchema.d.ts +7 -0
- package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +52 -1
- package/dist/handlers/mcp-aql/evaluatePermission.d.ts +53 -0
- package/dist/handlers/mcp-aql/evaluatePermission.d.ts.map +1 -0
- package/dist/handlers/mcp-aql/evaluatePermission.js +132 -0
- package/dist/handlers/mcp-aql/policies/ToolClassification.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.js +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/logging/LogHooks.js +11 -11
- package/dist/logging/LogManager.d.ts +0 -2
- package/dist/logging/LogManager.d.ts.map +1 -1
- package/dist/logging/LogManager.js +1 -3
- package/dist/logging/sinks/MemoryLogSink.d.ts +2 -0
- package/dist/logging/sinks/MemoryLogSink.d.ts.map +1 -1
- package/dist/logging/sinks/MemoryLogSink.js +12 -3
- package/dist/logging/types.d.ts +0 -2
- package/dist/logging/types.d.ts.map +1 -1
- package/dist/logging/types.js +1 -1
- package/dist/metrics/GatekeeperMetricsTracker.d.ts +32 -0
- package/dist/metrics/GatekeeperMetricsTracker.d.ts.map +1 -0
- package/dist/metrics/GatekeeperMetricsTracker.js +42 -0
- package/dist/metrics/MetricsManager.d.ts +47 -0
- package/dist/metrics/MetricsManager.d.ts.map +1 -0
- package/dist/metrics/MetricsManager.js +232 -0
- package/dist/metrics/OperationMetricsTracker.d.ts +32 -0
- package/dist/metrics/OperationMetricsTracker.d.ts.map +1 -0
- package/dist/metrics/OperationMetricsTracker.js +53 -0
- package/dist/metrics/collectors/DefaultElementProviderCollector.d.ts +27 -0
- package/dist/metrics/collectors/DefaultElementProviderCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/DefaultElementProviderCollector.js +69 -0
- package/dist/metrics/collectors/FileLockManagerCollector.d.ts +16 -0
- package/dist/metrics/collectors/FileLockManagerCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/FileLockManagerCollector.js +51 -0
- package/dist/metrics/collectors/GatekeeperMetricsCollector.d.ts +16 -0
- package/dist/metrics/collectors/GatekeeperMetricsCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/GatekeeperMetricsCollector.js +76 -0
- package/dist/metrics/collectors/LRUCacheCollector.d.ts +18 -0
- package/dist/metrics/collectors/LRUCacheCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/LRUCacheCollector.js +95 -0
- package/dist/metrics/collectors/OperationMetricsCollector.d.ts +16 -0
- package/dist/metrics/collectors/OperationMetricsCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/OperationMetricsCollector.js +80 -0
- package/dist/metrics/collectors/OperationalTelemetryCollector.d.ts +17 -0
- package/dist/metrics/collectors/OperationalTelemetryCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/OperationalTelemetryCollector.js +26 -0
- package/dist/metrics/collectors/PerformanceMonitorCollector.d.ts +14 -0
- package/dist/metrics/collectors/PerformanceMonitorCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/PerformanceMonitorCollector.js +141 -0
- package/dist/metrics/collectors/SecurityMonitorCollector.d.ts +21 -0
- package/dist/metrics/collectors/SecurityMonitorCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/SecurityMonitorCollector.js +56 -0
- package/dist/metrics/collectors/SecurityTelemetryCollector.d.ts +15 -0
- package/dist/metrics/collectors/SecurityTelemetryCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/SecurityTelemetryCollector.js +112 -0
- package/dist/metrics/collectors/TriggerMetricsTrackerCollector.d.ts +16 -0
- package/dist/metrics/collectors/TriggerMetricsTrackerCollector.d.ts.map +1 -0
- package/dist/metrics/collectors/TriggerMetricsTrackerCollector.js +26 -0
- package/dist/metrics/collectors/index.d.ts +11 -0
- package/dist/metrics/collectors/index.d.ts.map +1 -0
- package/dist/metrics/collectors/index.js +11 -0
- package/dist/metrics/sinks/MemoryMetricsSink.d.ts +22 -0
- package/dist/metrics/sinks/MemoryMetricsSink.d.ts.map +1 -0
- package/dist/metrics/sinks/MemoryMetricsSink.js +121 -0
- package/dist/metrics/types.d.ts +98 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +24 -0
- package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
- package/dist/portfolio/DefaultElementProvider.js +1 -7
- package/dist/portfolio/EnhancedIndexManager.d.ts.map +1 -1
- package/dist/portfolio/EnhancedIndexManager.js +18 -18
- package/dist/portfolio/NLPScoringManager.d.ts.map +1 -1
- package/dist/portfolio/NLPScoringManager.js +5 -9
- package/dist/portfolio/PortfolioIndexManager.js +2 -2
- package/dist/portfolio/RelationshipManager.js +2 -2
- package/dist/portfolio/VerbTriggerManager.d.ts.map +1 -1
- package/dist/portfolio/VerbTriggerManager.js +5 -19
- package/dist/portfolio/config/IndexConfig.d.ts.map +1 -1
- package/dist/portfolio/config/IndexConfig.js +1 -12
- package/dist/portfolio/enhanced-index/ElementDefinitionBuilder.d.ts.map +1 -1
- package/dist/portfolio/enhanced-index/ElementDefinitionBuilder.js +3 -15
- package/dist/portfolio/enhanced-index/SemanticRelationshipService.d.ts.map +1 -1
- package/dist/portfolio/enhanced-index/SemanticRelationshipService.js +2 -16
- package/dist/portfolio/types/RelationshipTypes.d.ts.map +1 -1
- package/dist/portfolio/types/RelationshipTypes.js +3 -17
- package/dist/security/audit/config/suppressions.d.ts.map +1 -1
- package/dist/security/audit/config/suppressions.js +36 -8
- package/dist/security/constants.d.ts.map +1 -1
- package/dist/security/constants.js +10 -6
- package/dist/security/fileLockManager.d.ts.map +1 -1
- package/dist/security/fileLockManager.js +8 -6
- package/dist/security/secureYamlParser.d.ts.map +1 -1
- package/dist/security/secureYamlParser.js +1 -13
- package/dist/security/securityMonitor.d.ts +2 -1
- package/dist/security/securityMonitor.d.ts.map +1 -1
- package/dist/security/securityMonitor.js +14 -3
- package/dist/security/telemetry/SecurityTelemetry.d.ts +16 -0
- package/dist/security/telemetry/SecurityTelemetry.d.ts.map +1 -1
- package/dist/security/telemetry/SecurityTelemetry.js +30 -2
- package/dist/security/tokenManager.d.ts +3 -0
- package/dist/security/tokenManager.d.ts.map +1 -1
- package/dist/security/tokenManager.js +13 -5
- package/dist/security/validation/BackgroundValidator.d.ts.map +1 -1
- package/dist/security/validation/BackgroundValidator.js +7 -7
- package/dist/server/startup.d.ts.map +1 -1
- package/dist/server/startup.js +8 -24
- package/dist/server/tools/MCPAQLTools.js +4 -1
- package/dist/services/ActivationStore.d.ts.map +1 -1
- package/dist/services/ActivationStore.js +9 -3
- package/dist/services/FileWatchService.d.ts +1 -0
- package/dist/services/FileWatchService.d.ts.map +1 -1
- package/dist/services/FileWatchService.js +83 -48
- package/dist/services/MetadataService.d.ts.map +1 -1
- package/dist/services/MetadataService.js +7 -2
- package/dist/services/query/ElementQueryService.d.ts.map +1 -1
- package/dist/services/query/ElementQueryService.js +1 -41
- package/dist/services/query/PaginationService.d.ts.map +1 -1
- package/dist/services/query/PaginationService.js +1 -14
- package/dist/services/query/SortService.d.ts.map +1 -1
- package/dist/services/query/SortService.js +1 -6
- package/dist/services/validation/ValidationService.d.ts.map +1 -1
- package/dist/services/validation/ValidationService.js +3 -8
- package/dist/storage/ElementStorageLayer.d.ts.map +1 -1
- package/dist/storage/ElementStorageLayer.js +5 -2
- package/dist/storage/MemoryStorageLayer.d.ts.map +1 -1
- package/dist/storage/MemoryStorageLayer.js +5 -2
- package/dist/telemetry/OperationalTelemetry.js +2 -2
- package/dist/utils/EventDeduplicator.d.ts +44 -0
- package/dist/utils/EventDeduplicator.d.ts.map +1 -0
- package/dist/utils/EventDeduplicator.js +93 -0
- package/dist/utils/FileLock.d.ts.map +1 -1
- package/dist/utils/FileLock.js +1 -9
- package/dist/utils/PerformanceMonitor.d.ts.map +1 -1
- package/dist/utils/PerformanceMonitor.js +5 -5
- package/dist/utils/SlidingWindowRateLimiter.d.ts +13 -0
- package/dist/utils/SlidingWindowRateLimiter.d.ts.map +1 -0
- package/dist/utils/SlidingWindowRateLimiter.js +23 -0
- package/dist/web/console/IngestRoutes.d.ts +84 -0
- package/dist/web/console/IngestRoutes.d.ts.map +1 -0
- package/dist/web/console/IngestRoutes.js +252 -0
- package/dist/web/console/LeaderElection.d.ts +89 -0
- package/dist/web/console/LeaderElection.d.ts.map +1 -0
- package/dist/web/console/LeaderElection.js +205 -0
- package/dist/web/console/LeaderForwardingSink.d.ts +61 -0
- package/dist/web/console/LeaderForwardingSink.d.ts.map +1 -0
- package/dist/web/console/LeaderForwardingSink.js +197 -0
- package/dist/web/console/SessionNames.d.ts +46 -0
- package/dist/web/console/SessionNames.d.ts.map +1 -0
- package/dist/web/console/SessionNames.js +257 -0
- package/dist/web/console/UnifiedConsole.d.ts +64 -0
- package/dist/web/console/UnifiedConsole.d.ts.map +1 -0
- package/dist/web/console/UnifiedConsole.js +119 -0
- package/dist/web/contentPipeline.d.ts +58 -0
- package/dist/web/contentPipeline.d.ts.map +1 -0
- package/dist/web/contentPipeline.js +112 -0
- package/dist/web/portDiscovery.d.ts +58 -0
- package/dist/web/portDiscovery.d.ts.map +1 -0
- package/dist/web/portDiscovery.js +143 -0
- package/dist/web/public/app.js +148 -60
- package/dist/web/public/logs.js +638 -0
- package/dist/web/public/metrics.js +682 -0
- package/dist/web/public/permissions.js +394 -0
- package/dist/web/public/sessions.js +369 -0
- package/dist/web/routes/healthRoutes.d.ts +16 -0
- package/dist/web/routes/healthRoutes.d.ts.map +1 -0
- package/dist/web/routes/healthRoutes.js +29 -0
- package/dist/web/routes/logRoutes.d.ts +18 -0
- package/dist/web/routes/logRoutes.d.ts.map +1 -0
- package/dist/web/routes/logRoutes.js +126 -0
- package/dist/web/routes/metricsRoutes.d.ts +17 -0
- package/dist/web/routes/metricsRoutes.d.ts.map +1 -0
- package/dist/web/routes/metricsRoutes.js +90 -0
- package/dist/web/routes/permissionRoutes.d.ts +16 -0
- package/dist/web/routes/permissionRoutes.d.ts.map +1 -0
- package/dist/web/routes/permissionRoutes.js +133 -0
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +309 -339
- package/dist/web/server.d.ts +21 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +42 -4
- package/dist/web/sinks/WebSSELogSink.d.ts +15 -0
- package/dist/web/sinks/WebSSELogSink.d.ts.map +1 -0
- package/dist/web/sinks/WebSSELogSink.js +22 -0
- package/dist/web/sinks/WebSSEMetricsSink.d.ts +16 -0
- package/dist/web/sinks/WebSSEMetricsSink.d.ts.map +1 -0
- package/dist/web/sinks/WebSSEMetricsSink.js +23 -0
- package/package.json +2 -2
- package/server.json +2 -2
- package/dist/constants/version.d.ts +0 -3
- package/dist/constants/version.d.ts.map +0 -1
- package/dist/constants/version.js +0 -4
- package/dist/logging/sinks/SSELogSink.d.ts +0 -35
- package/dist/logging/sinks/SSELogSink.d.ts.map +0 -1
- package/dist/logging/sinks/SSELogSink.js +0 -181
- package/dist/logging/viewer/viewerHtml.d.ts +0 -8
- package/dist/logging/viewer/viewerHtml.d.ts.map +0 -1
- package/dist/logging/viewer/viewerHtml.js +0 -204
- package/dist/web/public/public/app.js +0 -1878
package/dist/web/public/app.js
CHANGED
|
@@ -173,11 +173,19 @@ function safeParseYaml(content) {
|
|
|
173
173
|
|
|
174
174
|
// ── Type filter chips ──────────────────────────────────────────────────────
|
|
175
175
|
|
|
176
|
+
/** Elements filtered by source toggle only (no type/topic/search). */
|
|
177
|
+
function getSourceFilteredElements() {
|
|
178
|
+
if (activeSource === 'collection') return allElements.filter(el => !el._local);
|
|
179
|
+
if (activeSource === 'portfolio') return allElements.filter(el => el._local);
|
|
180
|
+
return allElements;
|
|
181
|
+
}
|
|
182
|
+
|
|
176
183
|
function renderTypeFilters() {
|
|
177
184
|
const container = document.getElementById('type-filters');
|
|
178
185
|
if (!container) return;
|
|
179
186
|
|
|
180
|
-
const
|
|
187
|
+
const sourceFiltered = getSourceFilteredElements();
|
|
188
|
+
const typeCounts = sourceFiltered.reduce((acc, el) => {
|
|
181
189
|
acc[el.type] = (acc[el.type] || 0) + 1;
|
|
182
190
|
return acc;
|
|
183
191
|
}, {});
|
|
@@ -186,7 +194,7 @@ function safeParseYaml(content) {
|
|
|
186
194
|
|
|
187
195
|
const isAllActive = activeTypes.size === 0;
|
|
188
196
|
container.innerHTML = types.map(type => {
|
|
189
|
-
const count = type === 'all' ?
|
|
197
|
+
const count = type === 'all' ? sourceFiltered.length : typeCounts[type];
|
|
190
198
|
const isActive = type === 'all' ? isAllActive : activeTypes.has(type);
|
|
191
199
|
return `<button
|
|
192
200
|
class="type-filter${isActive ? ' active' : ''}"
|
|
@@ -253,8 +261,9 @@ function safeParseYaml(content) {
|
|
|
253
261
|
const container = document.getElementById('topic-filters');
|
|
254
262
|
if (!container) return;
|
|
255
263
|
|
|
264
|
+
const sourceFiltered = getSourceFilteredElements();
|
|
256
265
|
const topicCounts = {};
|
|
257
|
-
|
|
266
|
+
sourceFiltered.forEach(el => {
|
|
258
267
|
const topic = getTopicForElement(el);
|
|
259
268
|
if (topic) topicCounts[topic] = (topicCounts[topic] || 0) + 1;
|
|
260
269
|
});
|
|
@@ -264,7 +273,7 @@ function safeParseYaml(content) {
|
|
|
264
273
|
|
|
265
274
|
container.hidden = false;
|
|
266
275
|
container.innerHTML = topics.map(topic => {
|
|
267
|
-
const count = topic === 'all' ?
|
|
276
|
+
const count = topic === 'all' ? sourceFiltered.length : topicCounts[topic];
|
|
268
277
|
const isActive = topic === activeTopic;
|
|
269
278
|
return `<button
|
|
270
279
|
class="topic-filter${isActive ? ' active' : ''}"
|
|
@@ -356,9 +365,10 @@ function safeParseYaml(content) {
|
|
|
356
365
|
const pageItems = filteredElements.slice(pageStart, pageEnd);
|
|
357
366
|
|
|
358
367
|
if (countEl) {
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
368
|
+
const sourceTotal = getSourceFilteredElements().length;
|
|
369
|
+
const base = total === sourceTotal
|
|
370
|
+
? `${sourceTotal} elements`
|
|
371
|
+
: `${total} of ${sourceTotal} elements`;
|
|
362
372
|
const pageNote = totalPages > 1 ? ` · page ${currentPage} of ${totalPages}` : '';
|
|
363
373
|
countEl.textContent = base + pageNote;
|
|
364
374
|
}
|
|
@@ -708,19 +718,25 @@ function safeParseYaml(content) {
|
|
|
708
718
|
document.body.classList.add('modal-open');
|
|
709
719
|
body.focus(); // focus body so arrow/Page/Home/End keys scroll content natively
|
|
710
720
|
|
|
711
|
-
// Fetch
|
|
721
|
+
// Fetch element content — structured JSON for local, raw text for collection
|
|
712
722
|
try {
|
|
713
|
-
let content;
|
|
723
|
+
let content; // raw file content (for Raw view, Copy, Download)
|
|
724
|
+
let structured; // { metadata, body, type, validation } when available
|
|
725
|
+
|
|
714
726
|
if (element._content) {
|
|
715
727
|
content = element._content;
|
|
716
728
|
} else if (element._local) {
|
|
717
729
|
const res = await fetch(`/api/elements/${element.path}`);
|
|
718
730
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
719
|
-
|
|
731
|
+
const data = await res.json();
|
|
732
|
+
structured = data;
|
|
733
|
+
content = data.raw;
|
|
720
734
|
} else {
|
|
721
|
-
const res = await fetch(
|
|
735
|
+
const res = await fetch(`/api/collection/content/${element.path}`);
|
|
722
736
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
723
|
-
|
|
737
|
+
const data = await res.json();
|
|
738
|
+
structured = data;
|
|
739
|
+
content = data.raw;
|
|
724
740
|
}
|
|
725
741
|
|
|
726
742
|
const renderBtn = modal.querySelector('#btn-render');
|
|
@@ -729,6 +745,11 @@ function safeParseYaml(content) {
|
|
|
729
745
|
if (modalShowRaw) {
|
|
730
746
|
body.innerHTML = `<pre class="element-source"><code class="element-code language-yaml">${escapeHtml(content)}</code></pre>`;
|
|
731
747
|
if (globalThis.hljs) body.querySelectorAll('pre code').forEach(b => hljs.highlightElement(b));
|
|
748
|
+
} else if (structured) {
|
|
749
|
+
body.innerHTML = renderStructuredDetail(structured);
|
|
750
|
+
body.querySelectorAll('pre code').forEach(b => {
|
|
751
|
+
if (globalThis.hljs) hljs.highlightElement(b);
|
|
752
|
+
});
|
|
732
753
|
} else {
|
|
733
754
|
body.innerHTML = renderDetailView(content, element.type);
|
|
734
755
|
body.querySelectorAll('pre code').forEach(b => {
|
|
@@ -1304,27 +1325,15 @@ function safeParseYaml(content) {
|
|
|
1304
1325
|
return html;
|
|
1305
1326
|
}
|
|
1306
1327
|
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
// Portfolio memories are pure YAML — jsyaml.load succeeds.
|
|
1310
|
-
// Collection memories are markdown-with-frontmatter — jsyaml.load throws on the
|
|
1311
|
-
// second `---` document marker, so we fall through to the standard renderer below.
|
|
1312
|
-
try {
|
|
1313
|
-
const parsed = safeParseYaml(content);
|
|
1314
|
-
if (parsed && typeof parsed === 'object') return renderMemoryView(content);
|
|
1315
|
-
} catch { /* not pure YAML — fall through */ }
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
const { frontmatter: fm, body } = parseFrontmatter(content);
|
|
1328
|
+
/** Render common metadata sections (created, author, tags, etc.) shared by both renderers */
|
|
1329
|
+
function renderCommonMetadata(fm, type) {
|
|
1319
1330
|
let html = '';
|
|
1320
1331
|
|
|
1321
|
-
// ── Created date — prominent header line ──
|
|
1322
1332
|
const createdVal = fm.created || fm.created_date;
|
|
1323
1333
|
if (createdVal) {
|
|
1324
1334
|
html += `<div class="detail-created"><span class="detail-created-label">Created</span><span class="detail-created-value">${escapeHtml(formatDate(createdVal))}</span></div>`;
|
|
1325
1335
|
}
|
|
1326
1336
|
|
|
1327
|
-
// ── Core metadata ──
|
|
1328
1337
|
const coreFields = [
|
|
1329
1338
|
detailField('Author', fm.author),
|
|
1330
1339
|
detailField('Version', fm.version ? `v${fm.version}` : null),
|
|
@@ -1335,68 +1344,103 @@ function safeParseYaml(content) {
|
|
|
1335
1344
|
].filter(Boolean).join('');
|
|
1336
1345
|
if (coreFields) html += detailSection('Details', coreFields);
|
|
1337
1346
|
|
|
1338
|
-
// ── Tags ──
|
|
1339
1347
|
if (Array.isArray(fm.tags) && fm.tags.length) {
|
|
1340
1348
|
html += detailSection('Tags', detailPillList(fm.tags, 'pill-tag'));
|
|
1341
1349
|
}
|
|
1342
|
-
|
|
1343
|
-
// ── Triggers (personas) ──
|
|
1344
1350
|
if (Array.isArray(fm.triggers) && fm.triggers.length) {
|
|
1345
1351
|
html += detailSection('Trigger words', detailPillList(fm.triggers, 'pill-trigger'));
|
|
1346
1352
|
}
|
|
1347
1353
|
|
|
1348
|
-
|
|
1349
|
-
const compTypes = ['personas','skills','tools','templates','prompts','memories'];
|
|
1350
|
-
const compEntries = compTypes
|
|
1351
|
-
.filter(k => Array.isArray(fm[k]) && fm[k].length)
|
|
1352
|
-
.map(k => `<div class="detail-field"><span class="detail-label">${capitalize(k)}</span><span class="detail-value">${detailPillList(fm[k])}</span></div>`)
|
|
1353
|
-
.join('');
|
|
1354
|
-
if (compEntries) html += detailSection('Components', compEntries);
|
|
1355
|
-
|
|
1356
|
-
// ── Ensemble coordination ──
|
|
1354
|
+
html += renderComponentsSections(fm);
|
|
1357
1355
|
if (fm.coordination_strategy) html += detailSection('Coordination', `<p class="detail-prose">${escapeHtml(fm.coordination_strategy)}</p>`);
|
|
1356
|
+
html += renderUseCases(fm);
|
|
1358
1357
|
|
|
1359
|
-
// ── Use cases ──
|
|
1360
|
-
if (Array.isArray(fm.use_cases) && fm.use_cases.length) {
|
|
1361
|
-
const useCaseItems = fm.use_cases.map(u => `<li>${escapeHtml(u)}</li>`).join('');
|
|
1362
|
-
html += detailSection('Use cases', `<ul class="detail-list">${useCaseItems}</ul>`);
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
// ── Instructions (all element types) ──
|
|
1366
1358
|
if (fm.instructions && type !== 'agent' && type !== 'ensemble') {
|
|
1367
|
-
// Agents and ensembles render instructions in their own sections
|
|
1368
1359
|
html += detailSection('Instructions', renderInstructions(fm.instructions));
|
|
1369
1360
|
}
|
|
1370
|
-
|
|
1371
|
-
// ── Gatekeeper (all element types) ──
|
|
1372
1361
|
if (fm.gatekeeper && typeof fm.gatekeeper === 'object' && type !== 'agent' && type !== 'ensemble') {
|
|
1373
1362
|
html += renderGatekeeperSection(fm.gatekeeper);
|
|
1374
1363
|
}
|
|
1375
1364
|
|
|
1376
|
-
|
|
1377
|
-
|
|
1365
|
+
return html;
|
|
1366
|
+
}
|
|
1378
1367
|
|
|
1379
|
-
|
|
1380
|
-
|
|
1368
|
+
/** Render components section (ensembles) */
|
|
1369
|
+
function renderComponentsSections(fm) {
|
|
1370
|
+
const compTypes = ['personas','skills','tools','templates','prompts','memories'];
|
|
1371
|
+
const compEntries = compTypes
|
|
1372
|
+
.filter(k => Array.isArray(fm[k]) && fm[k].length)
|
|
1373
|
+
.map(k => `<div class="detail-field"><span class="detail-label">${capitalize(k)}</span><span class="detail-value">${detailPillList(fm[k])}</span></div>`)
|
|
1374
|
+
.join('');
|
|
1375
|
+
return compEntries ? detailSection('Components', compEntries) : '';
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
/** Render use cases section */
|
|
1379
|
+
function renderUseCases(fm) {
|
|
1380
|
+
if (!Array.isArray(fm.use_cases) || !fm.use_cases.length) return '';
|
|
1381
|
+
const items = fm.use_cases.map(u => `<li>${escapeHtml(u)}</li>`).join('');
|
|
1382
|
+
return detailSection('Use cases', `<ul class="detail-list">${items}</ul>`);
|
|
1383
|
+
}
|
|
1381
1384
|
|
|
1382
|
-
|
|
1385
|
+
/** Render type-specific sections (parameters, agent, ensemble, proficiency) */
|
|
1386
|
+
function renderTypeSpecificSections(fm, type) {
|
|
1387
|
+
let html = '';
|
|
1388
|
+
html += renderDetailParameters(fm);
|
|
1389
|
+
html += renderDetailVariables(fm);
|
|
1383
1390
|
if (fm.proficiency_levels && typeof fm.proficiency_levels === 'object') {
|
|
1384
1391
|
const levels = Object.entries(fm.proficiency_levels)
|
|
1385
1392
|
.map(([lvl, desc]) => detailField(capitalize(lvl), desc)).join('');
|
|
1386
1393
|
if (levels) html += detailSection('Proficiency levels', levels);
|
|
1387
1394
|
}
|
|
1395
|
+
if (type === 'agent') html += renderAgentSection(fm);
|
|
1396
|
+
if (type === 'ensemble') html += renderEnsembleSection(fm);
|
|
1397
|
+
return html;
|
|
1398
|
+
}
|
|
1388
1399
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1400
|
+
/**
|
|
1401
|
+
* Render element detail from pre-parsed structured JSON.
|
|
1402
|
+
* The server has already validated and parsed the YAML — no client-side
|
|
1403
|
+
* re-parsing needed. Uses the same rendering helpers as renderDetailView.
|
|
1404
|
+
*/
|
|
1405
|
+
function renderStructuredDetail(data) {
|
|
1406
|
+
const { metadata: fm, body, type } = data;
|
|
1407
|
+
if (!fm || typeof fm !== 'object') {
|
|
1408
|
+
return `<pre class="element-source"><code class="element-code">${escapeHtml(data.raw || JSON.stringify(data))}</code></pre>`;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
if (type === 'memory') {
|
|
1412
|
+
return renderMemoryView(data.raw);
|
|
1392
1413
|
}
|
|
1393
1414
|
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1415
|
+
let html = '';
|
|
1416
|
+
|
|
1417
|
+
if (data.validation?.status === 'warn') {
|
|
1418
|
+
html += `<div class="detail-validation-warn">Security scan: ${escapeHtml(data.validation?.reason || 'warning')}</div>`;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
html += renderCommonMetadata(fm, type);
|
|
1422
|
+
html += renderTypeSpecificSections(fm, type);
|
|
1423
|
+
html += renderDetailExtra(fm, body || '');
|
|
1424
|
+
|
|
1425
|
+
return html || `<pre class="element-source"><code class="element-code">${escapeHtml(data.raw || '')}</code></pre>`;
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
function renderDetailView(content, type) { // NOSONAR - sequential independent metadata sections; complexity score is inflated by &&-guards on array existence checks
|
|
1429
|
+
if (type === 'memory') {
|
|
1430
|
+
// Portfolio memories are pure YAML — jsyaml.load succeeds.
|
|
1431
|
+
// Collection memories are markdown-with-frontmatter — jsyaml.load throws on the
|
|
1432
|
+
// second `---` document marker, so we fall through to the standard renderer below.
|
|
1433
|
+
try {
|
|
1434
|
+
const parsed = safeParseYaml(content);
|
|
1435
|
+
if (parsed && typeof parsed === 'object') return renderMemoryView(content);
|
|
1436
|
+
} catch { /* not pure YAML — fall through */ }
|
|
1397
1437
|
}
|
|
1398
1438
|
|
|
1399
|
-
|
|
1439
|
+
const { frontmatter: fm, body } = parseFrontmatter(content);
|
|
1440
|
+
let html = '';
|
|
1441
|
+
|
|
1442
|
+
html += renderCommonMetadata(fm, type);
|
|
1443
|
+
html += renderTypeSpecificSections(fm, type);
|
|
1400
1444
|
html += renderDetailExtra(fm, body);
|
|
1401
1445
|
|
|
1402
1446
|
return html || `<pre class="element-source"><code class="element-code">${escapeHtml(content)}</code></pre>`;
|
|
@@ -1865,6 +1909,8 @@ function safeParseYaml(content) {
|
|
|
1865
1909
|
b.classList.toggle('active', on);
|
|
1866
1910
|
b.setAttribute('aria-pressed', on);
|
|
1867
1911
|
});
|
|
1912
|
+
renderTypeFilters();
|
|
1913
|
+
renderTopicFilters();
|
|
1868
1914
|
applyFilters();
|
|
1869
1915
|
});
|
|
1870
1916
|
}
|
|
@@ -1872,6 +1918,48 @@ function safeParseYaml(content) {
|
|
|
1872
1918
|
// Portfolio button
|
|
1873
1919
|
document.getElementById('btn-portfolio')?.addEventListener('click', loadLocalPortfolio);
|
|
1874
1920
|
|
|
1921
|
+
// ── Tab switching ─────────────────────────────────────────────────────────
|
|
1922
|
+
const consoleTabs = document.getElementById('console-tabs');
|
|
1923
|
+
const tabInits = { logs: false, metrics: false, permissions: false };
|
|
1924
|
+
|
|
1925
|
+
if (consoleTabs) {
|
|
1926
|
+
consoleTabs.addEventListener('click', (e) => {
|
|
1927
|
+
const btn = e.target.closest('.console-tab');
|
|
1928
|
+
if (!btn) return;
|
|
1929
|
+
const tab = btn.dataset.tab;
|
|
1930
|
+
if (!tab) return;
|
|
1931
|
+
|
|
1932
|
+
// Update active tab button
|
|
1933
|
+
consoleTabs.querySelectorAll('.console-tab').forEach(b => b.classList.remove('active'));
|
|
1934
|
+
btn.classList.add('active');
|
|
1935
|
+
|
|
1936
|
+
// Show/hide panels
|
|
1937
|
+
document.querySelectorAll('.tab-panel').forEach(p => {
|
|
1938
|
+
p.hidden = p.id !== 'tab-' + tab;
|
|
1939
|
+
if (p.id === 'tab-' + tab) p.classList.add('active');
|
|
1940
|
+
else p.classList.remove('active');
|
|
1941
|
+
});
|
|
1942
|
+
|
|
1943
|
+
lazyInitTab(tab, tabInits);
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
function lazyInitTab(tab, tabInits) {
|
|
1948
|
+
const dc = globalThis.DollhouseConsole;
|
|
1949
|
+
if (tab === 'logs' && dc?.logs) {
|
|
1950
|
+
if (!tabInits.logs) { tabInits.logs = true; dc.logs.init(); }
|
|
1951
|
+
else if (dc.logs.refresh) { dc.logs.refresh(); }
|
|
1952
|
+
}
|
|
1953
|
+
if (tab === 'metrics' && dc?.metrics) {
|
|
1954
|
+
if (!tabInits.metrics) { tabInits.metrics = true; dc.metrics.init(); }
|
|
1955
|
+
else if (dc.metrics.refresh) { dc.metrics.refresh(); }
|
|
1956
|
+
}
|
|
1957
|
+
if (tab === 'permissions' && dc?.permissions) {
|
|
1958
|
+
if (!tabInits.permissions) { tabInits.permissions = true; dc.permissions.init(); }
|
|
1959
|
+
else if (dc.permissions.refresh) { dc.permissions.refresh(); }
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1875
1963
|
init();
|
|
1876
1964
|
});
|
|
1877
1965
|
|