@dollhousemcp/mcp-server 2.0.17 → 2.0.19
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 +10 -0
- package/dist/elements/BaseElement.d.ts +1 -0
- package/dist/elements/BaseElement.d.ts.map +1 -1
- package/dist/elements/BaseElement.js +7 -1
- package/dist/elements/agents/AgentManager.js +2 -2
- package/dist/elements/base/ElementFileOperations.js +2 -2
- package/dist/elements/ensembles/EnsembleManager.js +3 -3
- package/dist/elements/memories/MemoryManager.js +2 -2
- package/dist/elements/skills/SkillManager.js +2 -2
- package/dist/elements/templates/TemplateManager.js +2 -2
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/ElementCRUDHandler.d.ts +30 -0
- package/dist/handlers/ElementCRUDHandler.d.ts.map +1 -1
- package/dist/handlers/ElementCRUDHandler.js +142 -2
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts +4 -0
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +132 -14
- 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.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +17 -1
- package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/AgentToolPolicyTranslator.js +2 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts +9 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.js +64 -4
- package/dist/handlers/mcp-aql/policies/OperationPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/OperationPolicies.js +6 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ToolClassification.js +2 -1
- package/dist/handlers/strategies/AgentActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/AgentActivationStrategy.js +5 -1
- package/dist/handlers/strategies/BaseActivationStrategy.d.ts +1 -0
- package/dist/handlers/strategies/BaseActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/BaseActivationStrategy.js +15 -1
- package/dist/handlers/strategies/EnsembleActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/EnsembleActivationStrategy.js +5 -1
- package/dist/handlers/strategies/MemoryActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/MemoryActivationStrategy.js +5 -1
- package/dist/handlers/strategies/PersonaActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/PersonaActivationStrategy.js +5 -1
- package/dist/handlers/strategies/SkillActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/SkillActivationStrategy.js +5 -1
- package/dist/handlers/strategies/TemplateActivationStrategy.d.ts.map +1 -1
- package/dist/handlers/strategies/TemplateActivationStrategy.js +7 -2
- package/dist/persona/PersonaElement.js +2 -2
- package/dist/server/tools/MCPAQLTools.js +2 -1
- package/dist/services/SerializationService.d.ts.map +1 -1
- package/dist/services/SerializationService.js +7 -1
- package/dist/types/elements/IElement.d.ts +9 -0
- package/dist/types/elements/IElement.d.ts.map +1 -1
- package/dist/types/elements/IElement.js +1 -1
- package/dist/web/console/IngestRoutes.d.ts +6 -0
- package/dist/web/console/IngestRoutes.d.ts.map +1 -1
- package/dist/web/console/IngestRoutes.js +38 -9
- package/dist/web/console/LeaderElection.d.ts +39 -0
- package/dist/web/console/LeaderElection.d.ts.map +1 -1
- package/dist/web/console/LeaderElection.js +147 -29
- package/dist/web/console/LeaderForwardingSink.d.ts.map +1 -1
- package/dist/web/console/LeaderForwardingSink.js +5 -1
- package/dist/web/console/PromotionManager.d.ts.map +1 -1
- package/dist/web/console/PromotionManager.js +3 -11
- package/dist/web/public/app.js +62 -1
- package/dist/web/public/index.html +19 -17
- package/dist/web/public/permissions.css +190 -2
- package/dist/web/public/permissions.js +171 -30
- package/dist/web/public/sessions.js +111 -0
- package/dist/web/public/setup.js +131 -60
- package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
- package/dist/web/routes/permissionRoutes.js +77 -5
- package/dist/web/routes/setupRoutes.d.ts.map +1 -1
- package/dist/web/routes/setupRoutes.js +16 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +12 -10
- package/package.json +1 -1
- package/scripts/pretooluse-dollhouse.sh +39 -1
- package/server.json +2 -2
|
@@ -23,11 +23,121 @@
|
|
|
23
23
|
var SESSION_POLL_INTERVAL = getConfiguredNumber('sessionPollIntervalMs', 5000);
|
|
24
24
|
var SESSION_FILTER_INJECTION_RETRY_INTERVAL = getConfiguredNumber('sessionFilterInjectionRetryIntervalMs', 500);
|
|
25
25
|
var SESSION_FILTER_INJECTION_MAX_RETRIES = getConfiguredNumber('sessionFilterInjectionMaxRetries', 20);
|
|
26
|
+
var LEADER_RELOAD_DEBOUNCE_MS = getConfiguredNumber('leaderReloadDebounceMs', 150);
|
|
26
27
|
var sessions = [];
|
|
27
28
|
var policySessions = [];
|
|
28
29
|
var filterSessionId = '';
|
|
29
30
|
var dropdownBuilt = false;
|
|
30
31
|
var lastSessionKey = ''; // tracks session list identity to avoid unnecessary rebuilds
|
|
32
|
+
var lastReloadTargetVersion = '';
|
|
33
|
+
var pendingLeaderReloadTimer = null;
|
|
34
|
+
|
|
35
|
+
function parseSemver(version) {
|
|
36
|
+
if (typeof version !== 'string') return null;
|
|
37
|
+
var trimmed = version.trim();
|
|
38
|
+
var match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(trimmed);
|
|
39
|
+
if (!match) return null;
|
|
40
|
+
return {
|
|
41
|
+
normalized: trimmed,
|
|
42
|
+
major: parseInt(match[1], 10) || 0,
|
|
43
|
+
minor: parseInt(match[2], 10) || 0,
|
|
44
|
+
patch: parseInt(match[3], 10) || 0,
|
|
45
|
+
prerelease: match[4] ? match[4].split('.') : [],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function normalizeSemver(version) {
|
|
50
|
+
var parsed = parseSemver(version);
|
|
51
|
+
return parsed ? parsed.normalized : '';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function comparePrereleaseParts(partsA, partsB) {
|
|
55
|
+
var maxLength = Math.max(partsA.length, partsB.length);
|
|
56
|
+
if (!maxLength) return 0;
|
|
57
|
+
for (var i = 0; i < maxLength; i++) {
|
|
58
|
+
var a = partsA[i];
|
|
59
|
+
var b = partsB[i];
|
|
60
|
+
if (a === undefined) return -1;
|
|
61
|
+
if (b === undefined) return 1;
|
|
62
|
+
|
|
63
|
+
var aIsNumeric = /^\d+$/.test(a);
|
|
64
|
+
var bIsNumeric = /^\d+$/.test(b);
|
|
65
|
+
if (aIsNumeric && bIsNumeric) {
|
|
66
|
+
var aNumber = parseInt(a, 10);
|
|
67
|
+
var bNumber = parseInt(b, 10);
|
|
68
|
+
if (aNumber < bNumber) return -1;
|
|
69
|
+
if (aNumber > bNumber) return 1;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (aIsNumeric) return -1;
|
|
74
|
+
if (bIsNumeric) return 1;
|
|
75
|
+
|
|
76
|
+
var lexical = a.localeCompare(b);
|
|
77
|
+
if (lexical !== 0) return lexical;
|
|
78
|
+
}
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function compareSemver(versionA, versionB) {
|
|
83
|
+
var a = parseSemver(versionA);
|
|
84
|
+
var b = parseSemver(versionB);
|
|
85
|
+
if (!a && !b) return 0;
|
|
86
|
+
if (!a) return -1;
|
|
87
|
+
if (!b) return 1;
|
|
88
|
+
var versionKeys = ['major', 'minor', 'patch'];
|
|
89
|
+
for (var i = 0; i < versionKeys.length; i++) {
|
|
90
|
+
var key = versionKeys[i];
|
|
91
|
+
var aPart = a[key];
|
|
92
|
+
var bPart = b[key];
|
|
93
|
+
if (aPart < bPart) return -1;
|
|
94
|
+
if (aPart > bPart) return 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (!a.prerelease.length && b.prerelease.length) return 1;
|
|
98
|
+
if (a.prerelease.length && !b.prerelease.length) return -1;
|
|
99
|
+
return comparePrereleaseParts(a.prerelease, b.prerelease);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getCurrentConsoleVersion() {
|
|
103
|
+
var dc = window.DollhouseConsole;
|
|
104
|
+
if (dc && typeof dc.currentServerVersion === 'string') {
|
|
105
|
+
return normalizeSemver(dc.currentServerVersion);
|
|
106
|
+
}
|
|
107
|
+
var meta = document.querySelector('meta[name="dollhouse-server-version"]');
|
|
108
|
+
return normalizeSemver(meta ? meta.getAttribute('content') || '' : '');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Schedule a cache-busted reload when the session poller observes that a
|
|
113
|
+
* newer MCP leader is serving the console than the version loaded in this tab.
|
|
114
|
+
* A small debounce lets rapid leadership churn settle so the browser reloads
|
|
115
|
+
* directly into the newest compatible leader rather than bouncing through
|
|
116
|
+
* intermediate versions.
|
|
117
|
+
*
|
|
118
|
+
* @param {Array<Record<string, unknown>>} list
|
|
119
|
+
*/
|
|
120
|
+
function maybeForceReloadForNewLeader(list) {
|
|
121
|
+
var dc = window.DollhouseConsole;
|
|
122
|
+
if (!dc || typeof dc.forceReload !== 'function' || !Array.isArray(list)) return;
|
|
123
|
+
var currentVersion = getCurrentConsoleVersion();
|
|
124
|
+
var leader = list.find(function(session) {
|
|
125
|
+
return session && session.status === 'active' && session.isLeader && session.kind === 'mcp';
|
|
126
|
+
});
|
|
127
|
+
if (!leader) return;
|
|
128
|
+
var leaderVersion = normalizeSemver(leader.serverVersion);
|
|
129
|
+
if (!leaderVersion) return;
|
|
130
|
+
if (compareSemver(leaderVersion, currentVersion) <= 0) return;
|
|
131
|
+
if (lastReloadTargetVersion === leaderVersion) return;
|
|
132
|
+
if (pendingLeaderReloadTimer) {
|
|
133
|
+
clearTimeout(pendingLeaderReloadTimer);
|
|
134
|
+
}
|
|
135
|
+
lastReloadTargetVersion = leaderVersion;
|
|
136
|
+
pendingLeaderReloadTimer = setTimeout(function() {
|
|
137
|
+
pendingLeaderReloadTimer = null;
|
|
138
|
+
dc.forceReload('leader-upgraded', leaderVersion);
|
|
139
|
+
}, LEADER_RELOAD_DEBOUNCE_MS);
|
|
140
|
+
}
|
|
31
141
|
|
|
32
142
|
function formatUptime(startedAt) {
|
|
33
143
|
if (!startedAt) return '';
|
|
@@ -535,6 +645,7 @@
|
|
|
535
645
|
}).then(function(data) {
|
|
536
646
|
if (data && data.sessions) {
|
|
537
647
|
sessions = data.sessions;
|
|
648
|
+
maybeForceReloadForNewLeader(sessions);
|
|
538
649
|
updateSessionIndicator();
|
|
539
650
|
updateSessionFilterOptions();
|
|
540
651
|
clearSessionsError();
|
package/dist/web/public/setup.js
CHANGED
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
const PLATFORMS = [
|
|
19
19
|
// Claude Desktop & Claude Code panels are handwritten in HTML (unique structure)
|
|
20
20
|
{ id: 'claude-desktop', rootKey: 'mcpServers' },
|
|
21
|
-
{ id: 'claude-code', rootKey: 'mcpServers', cli: 'claude',
|
|
21
|
+
{ id: 'claude-code', rootKey: 'mcpServers', cli: 'claude', hookCommand: `bash ${HOOK_BASE_SCRIPT_PATH}`, hookConfigPath: '<code>~/.claude/settings.json</code>' },
|
|
22
22
|
// These panels are generated from this data by renderGeneratedPanels()
|
|
23
|
-
{ id: 'cursor', rootKey: 'mcpServers', installClient: 'cursor', openClient: 'cursor', configPath: '<code>.cursor/mcp.json</code> in your project, or <code>~/.cursor/mcp.json</code> for all projects', hint: 'Or configure via Settings > MCP Servers in the Cursor UI.',
|
|
24
|
-
{ id: 'vscode', rootKey: 'servers', installClient: 'vscode', configPath: '<code>.vscode/mcp.json</code> in your workspace', hint: 'VS Code uses <code>"servers"</code>, not <code>"mcpServers"</code>.',
|
|
25
|
-
{ id: 'codex', rootKey: 'mcpServers', installClient: 'codex', openClient: 'codex', cli: 'codex', toml: true, tomlPath: '<code>~/.codex/config.toml</code> (Codex uses TOML, not JSON)',
|
|
26
|
-
{ id: 'gemini', rootKey: 'mcpServers', installClient: 'gemini-cli', openClient: 'gemini-cli', cli: 'gemini', configPath: '<code>~/.gemini/settings.json</code> or <code>.gemini/settings.json</code> in your project',
|
|
27
|
-
{ id: 'windsurf', rootKey: 'mcpServers', installClient: 'windsurf', openClient: 'windsurf', configPath: '<code>~/.codeium/windsurf/mcp_config.json</code>', hint: 'Or click the MCPs icon in the Cascade panel > Configure.',
|
|
23
|
+
{ id: 'cursor', rootKey: 'mcpServers', installClient: 'cursor', openClient: 'cursor', configPath: '<code>.cursor/mcp.json</code> in your project, or <code>~/.cursor/mcp.json</code> for all projects', hint: 'Or configure via Settings > MCP Servers in the Cursor UI.', hookCommand: `bash ${HOOKS_DIR}/pretooluse-cursor.sh`, hookConfigPath: '<code>.cursor/hooks.json</code> in your project, or <code>~/.cursor/hooks.json</code> for all projects' },
|
|
24
|
+
{ id: 'vscode', rootKey: 'servers', installClient: 'vscode', configPath: '<code>.vscode/mcp.json</code> in your workspace', hint: 'VS Code uses <code>"servers"</code>, not <code>"mcpServers"</code>.', hookCommand: `bash ${HOOKS_DIR}/pretooluse-vscode.sh`, hookConfigPath: '<code>~/.copilot/hooks/dollhouse-permissions.json</code> plus <code>chat.hookFilesLocations</code> in VS Code user settings' },
|
|
25
|
+
{ id: 'codex', rootKey: 'mcpServers', installClient: 'codex', openClient: 'codex', cli: 'codex', toml: true, tomlPath: '<code>~/.codex/config.toml</code> (Codex uses TOML, not JSON)', hookCommand: `bash ${HOOKS_DIR}/pretooluse-codex.sh`, hookConfigPath: '<code>~/.codex/hooks.json</code> and <code>~/.codex/config.toml</code>' },
|
|
26
|
+
{ id: 'gemini', rootKey: 'mcpServers', installClient: 'gemini-cli', openClient: 'gemini-cli', cli: 'gemini', configPath: '<code>~/.gemini/settings.json</code> or <code>.gemini/settings.json</code> in your project', hookCommand: `bash ${HOOKS_DIR}/pretooluse-gemini.sh`, hookConfigPath: '<code>~/.gemini/settings.json</code> or <code>.gemini/settings.json</code> in your project' },
|
|
27
|
+
{ id: 'windsurf', rootKey: 'mcpServers', installClient: 'windsurf', openClient: 'windsurf', configPath: '<code>~/.codeium/windsurf/mcp_config.json</code>', hint: 'Or click the MCPs icon in the Cascade panel > Configure.', hookCommand: `bash ${HOOKS_DIR}/pretooluse-windsurf.sh`, hookConfigPath: '<code>~/.codeium/windsurf/hooks.json</code> or <code>.windsurf/hooks.json</code> in your project' },
|
|
28
28
|
{ id: 'cline', rootKey: 'mcpServers', installClient: 'cline', openClient: 'cline', configPath: 'Cline stores MCP servers in <code>cline_mcp_settings.json</code> inside its extension settings. Use Configure Now or open the file directly.' },
|
|
29
29
|
{ id: 'lmstudio', rootKey: 'mcpServers', installClient: 'lmstudio', openClient: 'lmstudio', configPath: '<code>~/.lmstudio/mcp.json</code> (or open via Program tab > Install > Edit mcp.json)', hint: 'Restart LM Studio after saving.' },
|
|
30
30
|
];
|
|
@@ -888,6 +888,7 @@ codex_hooks = true`;
|
|
|
888
888
|
'claude': 'claude-desktop',
|
|
889
889
|
'claude-code': 'claude-code',
|
|
890
890
|
'cursor': 'cursor',
|
|
891
|
+
'cline': 'cline',
|
|
891
892
|
'windsurf': 'windsurf',
|
|
892
893
|
'lmstudio': 'lmstudio',
|
|
893
894
|
'gemini-cli': 'gemini',
|
|
@@ -965,32 +966,29 @@ codex_hooks = true`;
|
|
|
965
966
|
}
|
|
966
967
|
};
|
|
967
968
|
|
|
968
|
-
const
|
|
969
|
-
'claude-desktop':
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
cline: 'Cline',
|
|
977
|
-
lmstudio: 'LM Studio',
|
|
978
|
-
};
|
|
979
|
-
|
|
980
|
-
const VERIFIED_PERMISSION_PLATFORMS = {
|
|
969
|
+
const PERMISSION_SUPPORT_MATRIX = {
|
|
970
|
+
'claude-desktop': {
|
|
971
|
+
label: 'Claude Desktop',
|
|
972
|
+
supportLevel: 'unsupported',
|
|
973
|
+
statusTag: 'coming soon',
|
|
974
|
+
badgeClass: 'unsupported',
|
|
975
|
+
limitation: 'Claude Desktop can host DollhouseMCP, but this release does not ship a native permissions setup flow for it yet.',
|
|
976
|
+
},
|
|
981
977
|
'claude-code': {
|
|
982
978
|
label: 'Claude Code',
|
|
979
|
+
supportLevel: 'full_native',
|
|
983
980
|
statusTag: 'claude code',
|
|
981
|
+
badgeClass: 'verified',
|
|
984
982
|
configPath: '<code>~/.claude/settings.json</code>',
|
|
985
983
|
scriptPath: HOOK_BASE_SCRIPT_PATH,
|
|
986
984
|
settingsBlock: CLAUDE_CODE_HOOK_SETTINGS,
|
|
985
|
+
limitation: 'Claude Code has the full native permission-hook path in this release.',
|
|
987
986
|
},
|
|
988
|
-
};
|
|
989
|
-
|
|
990
|
-
const PARTIAL_PERMISSION_PLATFORMS = {
|
|
991
987
|
gemini: {
|
|
992
988
|
label: 'Gemini CLI',
|
|
989
|
+
supportLevel: 'partial_native',
|
|
993
990
|
statusTag: 'allow / deny',
|
|
991
|
+
badgeClass: 'manual',
|
|
994
992
|
configPath: '<code>~/.gemini/settings.json</code> or <code>.gemini/settings.json</code> in your project',
|
|
995
993
|
scriptPath: `${HOOKS_DIR}/pretooluse-gemini.sh`,
|
|
996
994
|
settingsBlock: GEMINI_HOOK_SETTINGS,
|
|
@@ -998,7 +996,9 @@ codex_hooks = true`;
|
|
|
998
996
|
},
|
|
999
997
|
cursor: {
|
|
1000
998
|
label: 'Cursor',
|
|
999
|
+
supportLevel: 'partial_native',
|
|
1001
1000
|
statusTag: 'native hooks',
|
|
1001
|
+
badgeClass: 'manual',
|
|
1002
1002
|
configPath: '<code>.cursor/hooks.json</code> in your project, or <code>~/.cursor/hooks.json</code> for all projects',
|
|
1003
1003
|
scriptPath: `${HOOKS_DIR}/pretooluse-cursor.sh`,
|
|
1004
1004
|
settingsBlock: CURSOR_HOOK_SETTINGS,
|
|
@@ -1006,7 +1006,9 @@ codex_hooks = true`;
|
|
|
1006
1006
|
},
|
|
1007
1007
|
vscode: {
|
|
1008
1008
|
label: 'VS Code',
|
|
1009
|
+
supportLevel: 'partial_native',
|
|
1009
1010
|
statusTag: 'native hooks',
|
|
1011
|
+
badgeClass: 'manual',
|
|
1010
1012
|
configPath: '<code>~/.copilot/hooks/dollhouse-permissions.json</code> and VS Code user settings',
|
|
1011
1013
|
scriptPath: `${HOOKS_DIR}/pretooluse-vscode.sh`,
|
|
1012
1014
|
settingsBlock: VSCODE_HOOK_SETTINGS,
|
|
@@ -1017,7 +1019,9 @@ codex_hooks = true`;
|
|
|
1017
1019
|
},
|
|
1018
1020
|
windsurf: {
|
|
1019
1021
|
label: 'Windsurf',
|
|
1022
|
+
supportLevel: 'partial_native',
|
|
1020
1023
|
statusTag: 'allow / deny',
|
|
1024
|
+
badgeClass: 'manual',
|
|
1021
1025
|
configPath: '<code>~/.codeium/windsurf/hooks.json</code> or <code>.windsurf/hooks.json</code> in your project',
|
|
1022
1026
|
scriptPath: `${HOOKS_DIR}/pretooluse-windsurf.sh`,
|
|
1023
1027
|
settingsBlock: WINDSURF_HOOK_SETTINGS,
|
|
@@ -1025,20 +1029,46 @@ codex_hooks = true`;
|
|
|
1025
1029
|
},
|
|
1026
1030
|
codex: {
|
|
1027
1031
|
label: 'Codex',
|
|
1032
|
+
supportLevel: 'partial_native',
|
|
1028
1033
|
statusTag: 'bash only',
|
|
1034
|
+
badgeClass: 'manual',
|
|
1029
1035
|
configPath: '<code>~/.codex/hooks.json</code> and <code>~/.codex/config.toml</code>',
|
|
1030
1036
|
scriptPath: `${HOOKS_DIR}/pretooluse-codex.sh`,
|
|
1031
1037
|
settingsBlock: CODEX_HOOK_SETTINGS,
|
|
1032
1038
|
featureBlock: CODEX_HOOK_FEATURES_TOML,
|
|
1033
1039
|
limitation: 'Codex currently only supports native PreToolUse hooks for Bash, so this turns on Bash permission guardrails only.',
|
|
1034
1040
|
},
|
|
1041
|
+
cline: {
|
|
1042
|
+
label: 'Cline',
|
|
1043
|
+
supportLevel: 'mcp_only',
|
|
1044
|
+
statusTag: 'mcp only',
|
|
1045
|
+
badgeClass: 'manual',
|
|
1046
|
+
limitation: 'Cline MCP setup is supported here, but native permission-hook automation is still incomplete in this release.',
|
|
1047
|
+
},
|
|
1048
|
+
lmstudio: {
|
|
1049
|
+
label: 'LM Studio',
|
|
1050
|
+
supportLevel: 'mcp_only',
|
|
1051
|
+
statusTag: 'mcp only',
|
|
1052
|
+
badgeClass: 'manual',
|
|
1053
|
+
limitation: 'LM Studio MCP setup is supported here, but permission enforcement currently relies on LM Studio built-in confirmations or a future fallback adapter.',
|
|
1054
|
+
},
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
const getPermissionSupport = (platformId, detected) => {
|
|
1058
|
+
if (detected?.support) {
|
|
1059
|
+
return {
|
|
1060
|
+
...PERMISSION_SUPPORT_MATRIX[platformId],
|
|
1061
|
+
supportLevel: detected.support.level || PERMISSION_SUPPORT_MATRIX[platformId]?.supportLevel,
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
return PERMISSION_SUPPORT_MATRIX[platformId];
|
|
1035
1065
|
};
|
|
1036
1066
|
|
|
1037
|
-
const
|
|
1067
|
+
const getFullNativePermissionStatusCopy = (support, detected) => {
|
|
1038
1068
|
if (detected?.hookInstalled) {
|
|
1039
1069
|
return {
|
|
1040
1070
|
tone: 'info',
|
|
1041
|
-
titleText: `${
|
|
1071
|
+
titleText: `${support.label} permission enforcement is enabled.`,
|
|
1042
1072
|
messageText: 'No further changes are needed here unless you want to reinstall the hook settings.',
|
|
1043
1073
|
};
|
|
1044
1074
|
}
|
|
@@ -1046,44 +1076,60 @@ codex_hooks = true`;
|
|
|
1046
1076
|
if (detected?.installed) {
|
|
1047
1077
|
return {
|
|
1048
1078
|
tone: 'warning',
|
|
1049
|
-
titleText: `${
|
|
1050
|
-
messageText: `DollhouseMCP is configured as an MCP server. Use Configure Now below to also install the ${
|
|
1079
|
+
titleText: `${support.label} is connected for this client.`,
|
|
1080
|
+
messageText: `DollhouseMCP is configured as an MCP server. Use Configure Now below to also install the ${support.label} permission hook.`,
|
|
1051
1081
|
};
|
|
1052
1082
|
}
|
|
1053
1083
|
|
|
1054
1084
|
return {
|
|
1055
1085
|
tone: 'info',
|
|
1056
|
-
titleText: `${
|
|
1057
|
-
messageText: `First connect DollhouseMCP using Auto-updating or Pinned version, then use Configure Now below to install the ${
|
|
1086
|
+
titleText: `${support.label} permissions are not configured yet.`,
|
|
1087
|
+
messageText: `First connect DollhouseMCP using Auto-updating or Pinned version, then use Configure Now below to install the ${support.label} permission hook.`,
|
|
1058
1088
|
};
|
|
1059
1089
|
};
|
|
1060
1090
|
|
|
1061
|
-
const getPartialPermissionStatusCopy = (
|
|
1062
|
-
const activationLabel =
|
|
1091
|
+
const getPartialPermissionStatusCopy = (support, detected) => {
|
|
1092
|
+
const activationLabel = support.label === 'Codex' ? 'Bash guardrails' : 'permission hooks';
|
|
1063
1093
|
if (detected?.hookInstalled) {
|
|
1064
1094
|
return {
|
|
1065
1095
|
tone: 'info',
|
|
1066
|
-
titleText: `${
|
|
1067
|
-
messageText:
|
|
1096
|
+
titleText: `${support.label} ${activationLabel} are enabled.`,
|
|
1097
|
+
messageText: support.limitation,
|
|
1068
1098
|
};
|
|
1069
1099
|
}
|
|
1070
1100
|
|
|
1071
1101
|
if (detected?.installed) {
|
|
1072
1102
|
return {
|
|
1073
1103
|
tone: 'warning',
|
|
1074
|
-
titleText: `${
|
|
1075
|
-
messageText: `DollhouseMCP is configured as an MCP server. Use Configure Now below to turn on ${
|
|
1104
|
+
titleText: `${support.label} is connected for this client.`,
|
|
1105
|
+
messageText: `DollhouseMCP is configured as an MCP server. Use Configure Now below to turn on ${support.label}'s native ${activationLabel}.`,
|
|
1076
1106
|
};
|
|
1077
1107
|
}
|
|
1078
1108
|
|
|
1079
1109
|
return {
|
|
1080
1110
|
tone: 'info',
|
|
1081
|
-
titleText: `${
|
|
1082
|
-
messageText: `First connect DollhouseMCP using Auto-updating or Pinned version, then use Configure Now below to install ${
|
|
1111
|
+
titleText: `${support.label} ${activationLabel} are not configured yet.`,
|
|
1112
|
+
messageText: `First connect DollhouseMCP using Auto-updating or Pinned version, then use Configure Now below to install ${support.label}'s native ${activationLabel}.`,
|
|
1083
1113
|
};
|
|
1084
1114
|
};
|
|
1085
1115
|
|
|
1086
|
-
const
|
|
1116
|
+
const getMcpOnlyPermissionStatusCopy = (support, detected) => {
|
|
1117
|
+
if (detected?.installed) {
|
|
1118
|
+
return {
|
|
1119
|
+
tone: 'warning',
|
|
1120
|
+
titleText: `${support.label} is connected for this client.`,
|
|
1121
|
+
messageText: `${support.limitation} This release keeps that client in the MCP and fallback lane for now.`,
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
return {
|
|
1126
|
+
tone: 'info',
|
|
1127
|
+
titleText: `${support.label} supports MCP setup in this release.`,
|
|
1128
|
+
messageText: `${support.limitation} Use Auto-updating or Pinned version above to connect DollhouseMCP first.`,
|
|
1129
|
+
};
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
const getManualPermissionStatusCopy = (support, detected) => {
|
|
1087
1133
|
if (detected?.hookAssetsPrepared) {
|
|
1088
1134
|
return {
|
|
1089
1135
|
tone: 'info',
|
|
@@ -1106,32 +1152,40 @@ codex_hooks = true`;
|
|
|
1106
1152
|
};
|
|
1107
1153
|
};
|
|
1108
1154
|
|
|
1109
|
-
const getUnsupportedPermissionStatusCopy = (
|
|
1155
|
+
const getUnsupportedPermissionStatusCopy = (support, detected) => ({
|
|
1110
1156
|
tone: detected?.installed ? 'warning' : 'neutral',
|
|
1111
|
-
titleText: `Permissions & security tools are unavailable for ${
|
|
1157
|
+
titleText: `Permissions & security tools are unavailable for ${support.label} right now.`,
|
|
1112
1158
|
messageText: detected?.installed
|
|
1113
1159
|
? 'DollhouseMCP is connected for this client, but this release does not include a supported permissions setup flow here yet.'
|
|
1114
|
-
:
|
|
1160
|
+
: support.limitation,
|
|
1115
1161
|
});
|
|
1116
1162
|
|
|
1117
1163
|
const getPermissionStatusCopy = (platformId, detected) => {
|
|
1118
|
-
const
|
|
1119
|
-
if (
|
|
1120
|
-
return
|
|
1164
|
+
const support = getPermissionSupport(platformId, detected);
|
|
1165
|
+
if (!support) {
|
|
1166
|
+
return getUnsupportedPermissionStatusCopy({
|
|
1167
|
+
label: 'this client',
|
|
1168
|
+
limitation: 'This release does not include a supported permissions setup flow for this client yet.',
|
|
1169
|
+
}, detected);
|
|
1121
1170
|
}
|
|
1122
1171
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
return getPartialPermissionStatusCopy(partial, detected);
|
|
1172
|
+
if (support.supportLevel === 'full_native') {
|
|
1173
|
+
return getFullNativePermissionStatusCopy(support, detected);
|
|
1126
1174
|
}
|
|
1127
1175
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
return getManualPermissionStatusCopy(detected);
|
|
1176
|
+
if (support.supportLevel === 'partial_native') {
|
|
1177
|
+
return getPartialPermissionStatusCopy(support, detected);
|
|
1131
1178
|
}
|
|
1132
1179
|
|
|
1133
|
-
|
|
1134
|
-
|
|
1180
|
+
if (support.supportLevel === 'mcp_only') {
|
|
1181
|
+
return getMcpOnlyPermissionStatusCopy(support, detected);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
if (support.supportLevel === 'manual') {
|
|
1185
|
+
return getManualPermissionStatusCopy(support, detected);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
return getUnsupportedPermissionStatusCopy(support, detected);
|
|
1135
1189
|
};
|
|
1136
1190
|
|
|
1137
1191
|
const updatePermissionStatus = (panel, platformId, detected) => {
|
|
@@ -1418,24 +1472,41 @@ codex_hooks = true`;
|
|
|
1418
1472
|
</div>`;
|
|
1419
1473
|
};
|
|
1420
1474
|
|
|
1475
|
+
const renderMcpOnlyPermissionSection = (support) => `<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1476
|
+
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge--${support.badgeClass}">${support.statusTag}</span></h3>
|
|
1477
|
+
<div class="setup-permission-status" data-state="info">
|
|
1478
|
+
<strong class="setup-permission-status-title"></strong>
|
|
1479
|
+
<p class="setup-permission-status-msg"></p>
|
|
1480
|
+
</div>
|
|
1481
|
+
<p class="setup-hint">${support.limitation}</p>
|
|
1482
|
+
</div>`;
|
|
1483
|
+
|
|
1421
1484
|
const renderPermissionSection = (p) => {
|
|
1422
|
-
const
|
|
1485
|
+
const support = getPermissionSupport(p.id);
|
|
1423
1486
|
const configPath = p.hookConfigPath || p.configPath || p.tomlPath || 'this client’s user configuration';
|
|
1424
1487
|
|
|
1425
|
-
if (
|
|
1426
|
-
return
|
|
1488
|
+
if (!support) {
|
|
1489
|
+
return '';
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
if (support.supportLevel === 'full_native') {
|
|
1493
|
+
return renderVerifiedPermissionSection(p, support);
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
if (support.supportLevel === 'partial_native') {
|
|
1497
|
+
return renderPartialPermissionSection(p, support);
|
|
1427
1498
|
}
|
|
1428
1499
|
|
|
1429
|
-
if (
|
|
1430
|
-
return
|
|
1500
|
+
if (support.supportLevel === 'mcp_only') {
|
|
1501
|
+
return renderMcpOnlyPermissionSection(support);
|
|
1431
1502
|
}
|
|
1432
1503
|
|
|
1433
|
-
if (
|
|
1504
|
+
if (support.supportLevel === 'manual') {
|
|
1434
1505
|
const platformName = p.id === 'gemini' ? 'gemini' : p.id;
|
|
1435
1506
|
const wrapperFilename = `pretooluse-${platformName}.sh`;
|
|
1436
1507
|
const wrapperScript = buildHookWrapperScript(platformName);
|
|
1437
1508
|
return `<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1438
|
-
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge
|
|
1509
|
+
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge--${support.badgeClass}">${support.statusTag}</span></h3>
|
|
1439
1510
|
<div class="setup-permission-status" data-state="info">
|
|
1440
1511
|
<strong class="setup-permission-status-title"></strong>
|
|
1441
1512
|
<p class="setup-permission-status-msg"></p>
|
|
@@ -1453,7 +1524,7 @@ codex_hooks = true`;
|
|
|
1453
1524
|
}
|
|
1454
1525
|
|
|
1455
1526
|
return `<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1456
|
-
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge
|
|
1527
|
+
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge--${support.badgeClass}">${support.statusTag}</span></h3>
|
|
1457
1528
|
<div class="setup-permission-status" data-state="neutral">
|
|
1458
1529
|
<strong class="setup-permission-status-title"></strong>
|
|
1459
1530
|
<p class="setup-permission-status-msg"></p>
|
|
@@ -1467,7 +1538,7 @@ codex_hooks = true`;
|
|
|
1467
1538
|
|
|
1468
1539
|
intro.innerHTML = `<div class="setup-permissions-note">
|
|
1469
1540
|
<strong>Permissions & Security</strong>
|
|
1470
|
-
<p>Use this mode to turn on permission enforcement for supported clients. Claude Code is fully guided in this release
|
|
1541
|
+
<p>Use this mode to turn on permission enforcement for supported clients. Claude Code is fully guided in this release. Gemini CLI, Cursor, VS Code, Windsurf, and Codex have native partial support, while Cline and LM Studio stay in the MCP and fallback lane for now. Other clients will be marked as coming soon.</p>
|
|
1471
1542
|
</div>`;
|
|
1472
1543
|
};
|
|
1473
1544
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionRoutes.d.ts","sourceRoot":"","sources":["../../../src/web/routes/permissionRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"permissionRoutes.d.ts","sourceRoot":"","sources":["../../../src/web/routes/permissionRoutes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AA+Q7E;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CA0IrF"}
|