@dollhousemcp/mcp-server 2.0.9 → 2.0.10
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/dist/elements/ensembles/Ensemble.d.ts +9 -0
- package/dist/elements/ensembles/Ensemble.d.ts.map +1 -1
- package/dist/elements/ensembles/Ensemble.js +71 -4
- 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/mcp-aql/IntrospectionResolver.d.ts +57 -0
- package/dist/handlers/mcp-aql/IntrospectionResolver.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/IntrospectionResolver.js +181 -2
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +8 -0
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +32 -6
- package/dist/handlers/mcp-aql/OperationRouter.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationRouter.js +6 -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 +120 -8
- package/dist/handlers/mcp-aql/SchemaDispatcher.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/SchemaDispatcher.js +11 -1
- package/dist/handlers/mcp-aql/types.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/types.js +11 -1
- package/dist/index.js +19 -1
- package/dist/server/tools/MCPAQLTools.d.ts.map +1 -1
- package/dist/server/tools/MCPAQLTools.js +7 -1
- package/dist/web/public/app.js +118 -7
- package/dist/web/public/dollhouse-logo.png +0 -0
- package/dist/web/public/index.html +5 -2
- package/dist/web/public/logs.js +56 -1
- package/dist/web/public/metrics.js +32 -1
- package/dist/web/public/setup.css +79 -0
- package/dist/web/public/setup.js +90 -0
- package/dist/web/public/styles.css +3 -1
- package/dist/web/server.d.ts +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +14 -3
- package/package.json +2 -2
- package/server.json +2 -2
package/dist/web/public/app.js
CHANGED
|
@@ -1796,6 +1796,17 @@ function safeParseYaml(content) {
|
|
|
1796
1796
|
}
|
|
1797
1797
|
}
|
|
1798
1798
|
|
|
1799
|
+
// ── URL parameter helpers ────────────────────────────────────────────────
|
|
1800
|
+
|
|
1801
|
+
/**
|
|
1802
|
+
* Map sort + order URL params to the select value format used by the UI.
|
|
1803
|
+
*/
|
|
1804
|
+
function mapSortParams(sort = 'name', order = 'asc') {
|
|
1805
|
+
if (sort === 'name') return `name-${order}`;
|
|
1806
|
+
if (sort === 'updated' || sort === 'created') return `date-${order}`;
|
|
1807
|
+
return `${sort}-${order}`;
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1799
1810
|
// ── Event wiring ───────────────────────────────────────────────────────────
|
|
1800
1811
|
|
|
1801
1812
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -1941,14 +1952,114 @@ function safeParseYaml(content) {
|
|
|
1941
1952
|
});
|
|
1942
1953
|
};
|
|
1943
1954
|
|
|
1955
|
+
/**
|
|
1956
|
+
* Parse the URL hash into tab name and query parameters.
|
|
1957
|
+
* Supports fragment-query pattern: #tab?key=value&key=value
|
|
1958
|
+
* @returns {{ tab: string, params: URLSearchParams }}
|
|
1959
|
+
*/
|
|
1960
|
+
function getTabAndParams() {
|
|
1961
|
+
const raw = globalThis.location.hash.replace('#', '');
|
|
1962
|
+
// Guard against excessively long URLs (browser limit ~2048 chars)
|
|
1963
|
+
if (raw.length > 2048) return { tab: '', params: new URLSearchParams() };
|
|
1964
|
+
const qIdx = raw.indexOf('?');
|
|
1965
|
+
if (qIdx === -1) return { tab: raw, params: new URLSearchParams() };
|
|
1966
|
+
return {
|
|
1967
|
+
tab: raw.substring(0, qIdx),
|
|
1968
|
+
params: new URLSearchParams(raw.substring(qIdx + 1)),
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
// Expose for other scripts (logs.js, metrics.js, permissions.js)
|
|
1973
|
+
globalThis.DollhouseConsole = globalThis.DollhouseConsole || {};
|
|
1974
|
+
globalThis.DollhouseConsole.getUrlParams = () => getTabAndParams().params;
|
|
1975
|
+
|
|
1976
|
+
/**
|
|
1977
|
+
* Apply URL params to the portfolio tab.
|
|
1978
|
+
* Reads q, type, name, sort, order, active, category, author, page.
|
|
1979
|
+
*/
|
|
1980
|
+
function applyPortfolioParams(params) {
|
|
1981
|
+
if (!params || params.toString() === '') return;
|
|
1982
|
+
|
|
1983
|
+
applyPortfolioSearch(params);
|
|
1984
|
+
applyPortfolioTypeFilter(params);
|
|
1985
|
+
applyPortfolioSort(params);
|
|
1986
|
+
|
|
1987
|
+
// active — filter to active elements only
|
|
1988
|
+
if (params.get('active') === 'true') {
|
|
1989
|
+
activeSource = 'portfolio';
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
// page
|
|
1993
|
+
const page = params.get('page');
|
|
1994
|
+
if (page) {
|
|
1995
|
+
currentPage = Math.max(1, Number.parseInt(page, 10) || 1);
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
applyFilters();
|
|
1999
|
+
applyPortfolioNameNavigation(params);
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
function applyPortfolioSearch(params) {
|
|
2003
|
+
const q = params.get('q');
|
|
2004
|
+
if (!q) return;
|
|
2005
|
+
const searchInput = document.getElementById('search-input');
|
|
2006
|
+
if (searchInput) {
|
|
2007
|
+
searchInput.value = q;
|
|
2008
|
+
searchQuery = q.toLowerCase();
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
function applyPortfolioTypeFilter(params) {
|
|
2013
|
+
const type = params.get('type');
|
|
2014
|
+
if (!type) return;
|
|
2015
|
+
activeTypes.clear();
|
|
2016
|
+
activeTypes.add(type);
|
|
2017
|
+
document.querySelectorAll('.type-btn').forEach(btn => {
|
|
2018
|
+
btn.classList.toggle('active', btn.dataset.type === type);
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
function applyPortfolioSort(params) {
|
|
2023
|
+
const sort = params.get('sort');
|
|
2024
|
+
const order = params.get('order');
|
|
2025
|
+
if (!sort && !order) return;
|
|
2026
|
+
const sortSelect = document.getElementById('sort-select');
|
|
2027
|
+
if (sortSelect) {
|
|
2028
|
+
const mapped = mapSortParams(sort, order);
|
|
2029
|
+
sortSelect.value = mapped;
|
|
2030
|
+
activeSort = mapped;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
function applyPortfolioNameNavigation(params) {
|
|
2035
|
+
const name = params.get('name');
|
|
2036
|
+
if (!name) return;
|
|
2037
|
+
requestAnimationFrame(() => {
|
|
2038
|
+
const card = document.querySelector(`[data-element-name="${CSS.escape(name)}"]`);
|
|
2039
|
+
if (card) {
|
|
2040
|
+
card.click();
|
|
2041
|
+
card.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
2042
|
+
}
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
2045
|
+
|
|
1944
2046
|
// Tab selection priority: URL hash > localStorage > first-visit setup > portfolio default
|
|
1945
2047
|
function applyHashTab() {
|
|
1946
|
-
const hashTab =
|
|
2048
|
+
const { tab: hashTab, params } = getTabAndParams();
|
|
1947
2049
|
if (hashTab && document.getElementById('tab-' + hashTab)) {
|
|
1948
2050
|
switchToTab(hashTab);
|
|
1949
|
-
lazyInitTab(hashTab, tabInits);
|
|
2051
|
+
lazyInitTab(hashTab, tabInits, params);
|
|
1950
2052
|
localStorage.setItem(TAB_KEY, hashTab);
|
|
1951
|
-
|
|
2053
|
+
|
|
2054
|
+
// Apply tab-specific URL params
|
|
2055
|
+
if (hashTab === 'portfolio') {
|
|
2056
|
+
applyPortfolioParams(params);
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
// Clean hash but preserve it for bookmarkability if params were present
|
|
2060
|
+
if (params.toString() === '') {
|
|
2061
|
+
history.replaceState(null, '', globalThis.location.pathname);
|
|
2062
|
+
}
|
|
1952
2063
|
return true;
|
|
1953
2064
|
}
|
|
1954
2065
|
return false;
|
|
@@ -1981,18 +2092,18 @@ function safeParseYaml(content) {
|
|
|
1981
2092
|
});
|
|
1982
2093
|
}
|
|
1983
2094
|
|
|
1984
|
-
function lazyInitTab(tab, tabInits) {
|
|
2095
|
+
function lazyInitTab(tab, tabInits, params) {
|
|
1985
2096
|
const dc = globalThis.DollhouseConsole;
|
|
1986
2097
|
if (tab === 'logs' && dc?.logs) {
|
|
1987
|
-
if (!tabInits.logs) { tabInits.logs = true; dc.logs.init(); }
|
|
2098
|
+
if (!tabInits.logs) { tabInits.logs = true; dc.logs.init(params); }
|
|
1988
2099
|
else if (dc.logs.refresh) { dc.logs.refresh(); }
|
|
1989
2100
|
}
|
|
1990
2101
|
if (tab === 'metrics' && dc?.metrics) {
|
|
1991
|
-
if (!tabInits.metrics) { tabInits.metrics = true; dc.metrics.init(); }
|
|
2102
|
+
if (!tabInits.metrics) { tabInits.metrics = true; dc.metrics.init(params); }
|
|
1992
2103
|
else if (dc.metrics.refresh) { dc.metrics.refresh(); }
|
|
1993
2104
|
}
|
|
1994
2105
|
if (tab === 'permissions' && dc?.permissions) {
|
|
1995
|
-
if (!tabInits.permissions) { tabInits.permissions = true; dc.permissions.init(); }
|
|
2106
|
+
if (!tabInits.permissions) { tabInits.permissions = true; dc.permissions.init(params); }
|
|
1996
2107
|
else if (dc.permissions.refresh) { dc.permissions.refresh(); }
|
|
1997
2108
|
}
|
|
1998
2109
|
}
|
|
Binary file
|
|
@@ -23,8 +23,11 @@
|
|
|
23
23
|
|
|
24
24
|
<header class="site-header">
|
|
25
25
|
<div class="header-brand">
|
|
26
|
-
<
|
|
27
|
-
<
|
|
26
|
+
<img src="dollhouse-logo.png" alt="DollhouseMCP" class="header-logo" width="32" height="32">
|
|
27
|
+
<div class="header-brand-text">
|
|
28
|
+
<h1 class="site-title">DollhouseMCP</h1>
|
|
29
|
+
<p class="site-tagline">Management Console</p>
|
|
30
|
+
</div>
|
|
28
31
|
</div>
|
|
29
32
|
<div class="header-right">
|
|
30
33
|
<nav class="console-tabs" id="console-tabs" aria-label="Console tabs">
|
package/dist/web/public/logs.js
CHANGED
|
@@ -58,12 +58,16 @@
|
|
|
58
58
|
},
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
function initLogViewer() {
|
|
61
|
+
function initLogViewer(urlParams) {
|
|
62
62
|
const container = document.getElementById('log-viewer-root');
|
|
63
63
|
if (!container || container.dataset.initialized === 'true') return;
|
|
64
64
|
container.dataset.initialized = 'true';
|
|
65
65
|
|
|
66
66
|
buildDOM(container);
|
|
67
|
+
|
|
68
|
+
// Apply URL params before binding events and connecting SSE
|
|
69
|
+
if (urlParams) applyLogUrlParams(urlParams);
|
|
70
|
+
|
|
67
71
|
bindEvents();
|
|
68
72
|
connectSSE();
|
|
69
73
|
|
|
@@ -73,6 +77,57 @@
|
|
|
73
77
|
});
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Parse a comma-separated level string and return the minimum valid level.
|
|
82
|
+
* @param {string} levelParam - e.g., "error,warn" or "info"
|
|
83
|
+
* @returns {string|null} The minimum valid level, or null if none valid
|
|
84
|
+
*/
|
|
85
|
+
function parseMinLevel(levelParam) {
|
|
86
|
+
const levelOrder = ['debug', 'info', 'warn', 'error'];
|
|
87
|
+
const levels = levelParam.split(',')
|
|
88
|
+
.map(l => l.trim().toLowerCase())
|
|
89
|
+
.filter(l => levelOrder.includes(l));
|
|
90
|
+
if (levels.length === 0) return null;
|
|
91
|
+
return levels.reduce((min, l) =>
|
|
92
|
+
levelOrder.indexOf(l) < levelOrder.indexOf(min) ? l : min
|
|
93
|
+
, levels[0]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Apply URL parameters to log viewer state.
|
|
98
|
+
* Supports: level, category, source, q (message search), correlationId, tail
|
|
99
|
+
* @param {URLSearchParams} params
|
|
100
|
+
*/
|
|
101
|
+
/** Apply a single string URL param to a filter variable and optional DOM element. */
|
|
102
|
+
function applyStringParam(params, key, setter, element) {
|
|
103
|
+
const val = params.get(key);
|
|
104
|
+
if (!val) return;
|
|
105
|
+
setter(val);
|
|
106
|
+
if (element) element.value = val;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function applyLogUrlParams(params) {
|
|
110
|
+
if (!params || params.toString() === '') return;
|
|
111
|
+
|
|
112
|
+
const level = params.get('level');
|
|
113
|
+
if (level) {
|
|
114
|
+
const minLevel = parseMinLevel(level);
|
|
115
|
+
if (minLevel) {
|
|
116
|
+
filterLevel = minLevel;
|
|
117
|
+
if (levelSelect) levelSelect.value = minLevel;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
applyStringParam(params, 'category', v => { filterCategory = v; }, categorySelect);
|
|
122
|
+
applyStringParam(params, 'source', v => { filterSource = v; }, sourceInput);
|
|
123
|
+
applyStringParam(params, 'q', v => { filterMessage = v; }, searchInput);
|
|
124
|
+
|
|
125
|
+
const cid = params.get('correlationId');
|
|
126
|
+
if (cid) filterCorrelationId = cid;
|
|
127
|
+
|
|
128
|
+
if (params.get('tail') === 'false') autoScroll = false;
|
|
129
|
+
}
|
|
130
|
+
|
|
76
131
|
function destroyLogViewer() {
|
|
77
132
|
if (eventSource) {
|
|
78
133
|
eventSource.close();
|
|
@@ -34,11 +34,14 @@
|
|
|
34
34
|
},
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
function initMetrics() {
|
|
37
|
+
function initMetrics(urlParams) {
|
|
38
38
|
const container = document.getElementById('metrics-dashboard-root');
|
|
39
39
|
if (!container || container.dataset.initialized === 'true') return;
|
|
40
40
|
container.dataset.initialized = 'true';
|
|
41
41
|
|
|
42
|
+
// Apply URL params before building DOM
|
|
43
|
+
if (urlParams) applyMetricsUrlParams(urlParams);
|
|
44
|
+
|
|
42
45
|
uPlotAvailable = typeof globalThis.uPlot !== 'undefined'; // NOSONAR — typeof is the safe check for optional globals that may not be loaded
|
|
43
46
|
buildDOM(container);
|
|
44
47
|
bindEvents();
|
|
@@ -46,6 +49,34 @@
|
|
|
46
49
|
pollTimer = setInterval(fetchLatest, POLL_INTERVAL_MS);
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Apply URL parameters to metrics dashboard state.
|
|
54
|
+
* Supports: since (time range), refresh (poll interval)
|
|
55
|
+
* @param {URLSearchParams} params
|
|
56
|
+
*/
|
|
57
|
+
function applyMetricsUrlParams(params) {
|
|
58
|
+
if (!params || params.toString() === '') return;
|
|
59
|
+
|
|
60
|
+
const since = params.get('since');
|
|
61
|
+
if (since && TIME_RANGES[since]) {
|
|
62
|
+
activeRange = since;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const refresh = params.get('refresh');
|
|
66
|
+
if (refresh) {
|
|
67
|
+
const interval = Number.parseInt(refresh, 10);
|
|
68
|
+
// Cap between 1-300 seconds to prevent excessive or unreasonable polling
|
|
69
|
+
if (interval > 0) {
|
|
70
|
+
const capped = Math.min(Math.max(interval, 1), 300);
|
|
71
|
+
if (pollTimer) clearInterval(pollTimer);
|
|
72
|
+
pollTimer = setInterval(fetchLatest, capped * 1000);
|
|
73
|
+
} else if (interval === 0 && pollTimer) {
|
|
74
|
+
clearInterval(pollTimer);
|
|
75
|
+
pollTimer = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
49
80
|
function destroyMetrics() {
|
|
50
81
|
if (pollTimer) {
|
|
51
82
|
clearInterval(pollTimer);
|
|
@@ -646,3 +646,82 @@
|
|
|
646
646
|
flex-direction: column;
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
|
+
|
|
650
|
+
/* ── Completion banner ────────────────────────────────────────────────── */
|
|
651
|
+
|
|
652
|
+
.setup-completion-banner {
|
|
653
|
+
margin: 1.5rem 0 2rem;
|
|
654
|
+
padding: 1.5rem 2rem;
|
|
655
|
+
border-radius: 12px;
|
|
656
|
+
background: color-mix(in srgb, #22c55e 8%, var(--surface-1));
|
|
657
|
+
border: 2px solid color-mix(in srgb, #22c55e 40%, var(--line));
|
|
658
|
+
text-align: center;
|
|
659
|
+
animation: completionFadeIn 0.4s ease-out;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
@keyframes completionFadeIn {
|
|
663
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
664
|
+
to { opacity: 1; transform: translateY(0); }
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
.setup-completion-icon {
|
|
668
|
+
font-size: 2.5rem;
|
|
669
|
+
color: #22c55e;
|
|
670
|
+
line-height: 1;
|
|
671
|
+
margin-bottom: 0.5rem;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.setup-completion-banner h3 {
|
|
675
|
+
margin: 0 0 0.5rem;
|
|
676
|
+
font-size: 1.3rem;
|
|
677
|
+
color: var(--text-1);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
.setup-completion-banner > p {
|
|
681
|
+
margin: 0 0 1rem;
|
|
682
|
+
color: var(--text-2);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.setup-completion-steps {
|
|
686
|
+
display: flex;
|
|
687
|
+
flex-direction: column;
|
|
688
|
+
gap: 0.75rem;
|
|
689
|
+
max-width: 28rem;
|
|
690
|
+
margin: 1.25rem auto;
|
|
691
|
+
text-align: left;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.setup-completion-step {
|
|
695
|
+
display: flex;
|
|
696
|
+
align-items: center;
|
|
697
|
+
gap: 0.75rem;
|
|
698
|
+
color: var(--text-1);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.setup-completion-step-num {
|
|
702
|
+
display: inline-flex;
|
|
703
|
+
align-items: center;
|
|
704
|
+
justify-content: center;
|
|
705
|
+
width: 1.6rem;
|
|
706
|
+
height: 1.6rem;
|
|
707
|
+
border-radius: 50%;
|
|
708
|
+
background: color-mix(in srgb, #22c55e 20%, var(--surface-1));
|
|
709
|
+
border: 1px solid color-mix(in srgb, #22c55e 40%, var(--line));
|
|
710
|
+
font-size: 0.8rem;
|
|
711
|
+
font-weight: 700;
|
|
712
|
+
color: #22c55e;
|
|
713
|
+
flex-shrink: 0;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.setup-completion-terminal-hint {
|
|
717
|
+
margin-top: 1.25rem;
|
|
718
|
+
font-size: 0.85rem;
|
|
719
|
+
color: var(--text-3);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.setup-completion-terminal-hint code {
|
|
723
|
+
background: var(--surface-2);
|
|
724
|
+
padding: 0.15rem 0.4rem;
|
|
725
|
+
border-radius: 4px;
|
|
726
|
+
font-size: 0.8rem;
|
|
727
|
+
}
|
package/dist/web/public/setup.js
CHANGED
|
@@ -358,6 +358,9 @@
|
|
|
358
358
|
: 'Restart the application to activate.';
|
|
359
359
|
status.classList.add('is-success');
|
|
360
360
|
}
|
|
361
|
+
|
|
362
|
+
// Show the completion banner after any successful install
|
|
363
|
+
showCompletionBanner(client);
|
|
361
364
|
} catch (err) {
|
|
362
365
|
btn.textContent = originalText;
|
|
363
366
|
btn.disabled = false;
|
|
@@ -369,6 +372,93 @@
|
|
|
369
372
|
}
|
|
370
373
|
};
|
|
371
374
|
|
|
375
|
+
// ── Completion banner ────────────────────────────────────────────────
|
|
376
|
+
|
|
377
|
+
/** Friendly display names for install clients */
|
|
378
|
+
const CLIENT_DISPLAY_NAMES = {
|
|
379
|
+
'claude-desktop': 'Claude Desktop',
|
|
380
|
+
'claude-code': 'Claude Code',
|
|
381
|
+
'cursor': 'Cursor',
|
|
382
|
+
'vscode': 'VS Code',
|
|
383
|
+
'codex': 'Codex',
|
|
384
|
+
'gemini-cli': 'Gemini CLI',
|
|
385
|
+
'windsurf': 'Windsurf',
|
|
386
|
+
'cline': 'Cline',
|
|
387
|
+
'lmstudio': 'LM Studio',
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
/** Track which clients have been successfully installed this session */
|
|
391
|
+
const installedClients = [];
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Show or update the completion banner after successful install.
|
|
395
|
+
* Tracks all installed clients and updates the banner text to reflect
|
|
396
|
+
* every client that was configured in this session.
|
|
397
|
+
*/
|
|
398
|
+
const showCompletionBanner = (client) => {
|
|
399
|
+
const clientName = CLIENT_DISPLAY_NAMES[client] || client;
|
|
400
|
+
|
|
401
|
+
// Track this client (avoid duplicates from re-installs)
|
|
402
|
+
if (!installedClients.includes(clientName)) {
|
|
403
|
+
installedClients.push(clientName);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const clientList = installedClients.length === 1
|
|
407
|
+
? `<strong>${installedClients[0]}</strong>`
|
|
408
|
+
: installedClients.slice(0, -1).map(c => `<strong>${c}</strong>`).join(', ')
|
|
409
|
+
+ ` and <strong>${installedClients.at(-1)}</strong>`;
|
|
410
|
+
|
|
411
|
+
const restartList = installedClients.length === 1
|
|
412
|
+
? `Restart <strong>${installedClients[0]}</strong> to activate DollhouseMCP`
|
|
413
|
+
: `Restart any of your configured clients to activate DollhouseMCP`;
|
|
414
|
+
|
|
415
|
+
const configuredWord = installedClients.length === 1 ? 'has' : 'have';
|
|
416
|
+
|
|
417
|
+
const bannerHTML = `
|
|
418
|
+
<div class="setup-completion-icon">✓</div>
|
|
419
|
+
<h3>You're all set!</h3>
|
|
420
|
+
<p>${clientList} ${configuredWord} been configured with DollhouseMCP.</p>
|
|
421
|
+
<div class="setup-completion-steps">
|
|
422
|
+
<div class="setup-completion-step">
|
|
423
|
+
<span class="setup-completion-step-num">1</span>
|
|
424
|
+
<span>Close this browser tab</span>
|
|
425
|
+
</div>
|
|
426
|
+
<div class="setup-completion-step">
|
|
427
|
+
<span class="setup-completion-step-num">2</span>
|
|
428
|
+
<span>${restartList}</span>
|
|
429
|
+
</div>
|
|
430
|
+
<div class="setup-completion-step">
|
|
431
|
+
<span class="setup-completion-step-num">3</span>
|
|
432
|
+
<span>Start a conversation and ask: <em>"What DollhouseMCP tools do you have?"</em></span>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
<p class="setup-completion-terminal-hint">In the terminal, type <code>q</code> to exit the installer.</p>
|
|
436
|
+
`;
|
|
437
|
+
|
|
438
|
+
const existing = document.getElementById('setup-completion-banner');
|
|
439
|
+
if (existing) {
|
|
440
|
+
// Update the existing banner with the new client list
|
|
441
|
+
existing.innerHTML = bannerHTML;
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// First install — create and insert the banner
|
|
446
|
+
const banner = document.createElement('div');
|
|
447
|
+
banner.id = 'setup-completion-banner';
|
|
448
|
+
banner.className = 'setup-completion-banner';
|
|
449
|
+
banner.innerHTML = bannerHTML;
|
|
450
|
+
|
|
451
|
+
const setupContent = document.querySelector('.setup-content');
|
|
452
|
+
const heroSection = setupContent?.querySelector('.setup-hero');
|
|
453
|
+
if (setupContent && heroSection) {
|
|
454
|
+
heroSection.after(banner);
|
|
455
|
+
} else if (setupContent) {
|
|
456
|
+
setupContent.prepend(banner);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
banner.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
460
|
+
};
|
|
461
|
+
|
|
372
462
|
const initInstallButtons = () => {
|
|
373
463
|
document.querySelectorAll('.setup-install-btn').forEach((btn) => {
|
|
374
464
|
btn.addEventListener('click', () => handleInstallClick(btn));
|
|
@@ -166,7 +166,9 @@ p, li { max-width: 69ch; }
|
|
|
166
166
|
pointer-events: none;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
.header-brand { display: flex; flex-direction:
|
|
169
|
+
.header-brand { display: flex; flex-direction: row; align-items: center; gap: 0.6rem; }
|
|
170
|
+
.header-brand-text { display: flex; flex-direction: column; gap: 0.05rem; }
|
|
171
|
+
.header-logo { width: 32px; height: 32px; flex-shrink: 0; }
|
|
170
172
|
|
|
171
173
|
.site-title {
|
|
172
174
|
font-family: var(--font-heading);
|
package/dist/web/server.d.ts
CHANGED
|
@@ -89,5 +89,5 @@ export declare function startWebServer(options: WebServerOptions): Promise<WebSe
|
|
|
89
89
|
* @param port - Port to bind to (default: 3939)
|
|
90
90
|
* @returns Result with URL, server status, and browser open status
|
|
91
91
|
*/
|
|
92
|
-
export declare function openPortfolioBrowser(portfolioDir: string, port?: number, mcpAqlHandler?: MCPAQLHandler, tab?: string): Promise<BrowserOpenResult>;
|
|
92
|
+
export declare function openPortfolioBrowser(portfolioDir: string, port?: number, mcpAqlHandler?: MCPAQLHandler, tab?: string, urlParams?: Record<string, string>): Promise<BrowserOpenResult>;
|
|
93
93
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/web/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAa/E,qEAAqE;AACrE,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,kFAAkF;IAClF,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6FAA6F;IAC7F,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,OAAO,SAAS,EAAE,MAAM,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,GAAG,CAAC,EAAE,OAAO,SAAS,EAAE,OAAO,CAAC;IAChC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,qBAAqB,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9E,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,qBAAqB,EAAE,cAAc,KAAK,IAAI,CAAC;CACtF;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,cAAc,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;IACvB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsCD;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAa/E,qEAAqE;AACrE,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,kFAAkF;IAClF,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6FAA6F;IAC7F,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,OAAO,SAAS,EAAE,MAAM,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,GAAG,CAAC,EAAE,OAAO,SAAS,EAAE,OAAO,CAAC;IAChC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,qBAAqB,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9E,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,qBAAqB,EAAE,cAAc,KAAK,IAAI,CAAC;CACtF;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,cAAc,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAC;IACvB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAsCD;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmLxF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkC3L"}
|