@dollhousemcp/mcp-server 2.0.16 → 2.0.17
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 +6 -0
- package/README.md.backup +18 -0
- package/dist/elements/base/BaseElementManager.d.ts.map +1 -1
- package/dist/elements/base/BaseElementManager.js +17 -1
- package/dist/elements/memories/MemoryManager.d.ts.map +1 -1
- package/dist/elements/memories/MemoryManager.js +13 -2
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/element-crud/createElement.d.ts.map +1 -1
- package/dist/handlers/element-crud/createElement.js +6 -2
- package/dist/handlers/element-crud/editElement.d.ts.map +1 -1
- package/dist/handlers/element-crud/editElement.js +6 -2
- package/dist/handlers/element-crud/helpers.d.ts +2 -0
- package/dist/handlers/element-crud/helpers.d.ts.map +1 -1
- package/dist/handlers/element-crud/helpers.js +21 -2
- package/dist/handlers/mcp-aql/IntrospectionResolver.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/IntrospectionResolver.js +34 -7
- package/dist/handlers/mcp-aql/MCPAQLHandler.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/MCPAQLHandler.js +19 -4
- package/dist/handlers/mcp-aql/OperationSchema.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/OperationSchema.js +3 -2
- package/dist/handlers/mcp-aql/evaluatePermission.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/evaluatePermission.js +2 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts +8 -0
- package/dist/handlers/mcp-aql/policies/ElementPolicies.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/policies/ElementPolicies.js +26 -1
- package/dist/utils/permissionHooks.d.ts +39 -3
- package/dist/utils/permissionHooks.d.ts.map +1 -1
- package/dist/utils/permissionHooks.js +651 -74
- package/dist/web/public/permissions.js +38 -26
- package/dist/web/public/setup.js +367 -94
- package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
- package/dist/web/routes/permissionRoutes.js +32 -13
- package/dist/web/routes/setupRoutes.d.ts +1 -0
- package/dist/web/routes/setupRoutes.d.ts.map +1 -1
- package/dist/web/routes/setupRoutes.js +113 -41
- package/package.json +3 -1
- package/scripts/pretooluse-vscode.sh +163 -0
- package/scripts/pretooluse-windsurf.sh +166 -4
- package/server.json +2 -2
package/dist/web/public/setup.js
CHANGED
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
{ id: 'claude-desktop', rootKey: 'mcpServers' },
|
|
21
21
|
{ id: 'claude-code', rootKey: 'mcpServers', cli: 'claude', hookSupport: 'verified', 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.', hookSupport: '
|
|
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)', hookSupport: '
|
|
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', hookSupport: '
|
|
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.', hookSupport: '
|
|
28
|
-
{ id: 'cline', rootKey: 'mcpServers', installClient: 'cline', configPath: '<code>cline_mcp_settings.json</code>
|
|
29
|
-
{ id: 'lmstudio', rootKey: 'mcpServers', openClient: 'lmstudio',
|
|
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.', hookSupport: 'partial', 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>.', hookSupport: 'partial', 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)', hookSupport: 'partial', 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', hookSupport: 'partial', 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.', hookSupport: 'partial', hookCommand: `bash ${HOOKS_DIR}/pretooluse-windsurf.sh`, hookConfigPath: '<code>~/.codeium/windsurf/hooks.json</code> or <code>.windsurf/hooks.json</code> in your project' },
|
|
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
|
+
{ 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
|
];
|
|
31
31
|
|
|
32
32
|
const HOOK_BASE_SCRIPT = `#!/bin/bash
|
|
@@ -82,6 +82,94 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
82
82
|
}
|
|
83
83
|
}`;
|
|
84
84
|
|
|
85
|
+
const GEMINI_HOOK_SETTINGS = `{
|
|
86
|
+
"hooks": {
|
|
87
|
+
"BeforeTool": [
|
|
88
|
+
{
|
|
89
|
+
"matcher": ".*",
|
|
90
|
+
"hooks": [
|
|
91
|
+
{
|
|
92
|
+
"type": "command",
|
|
93
|
+
"command": "bash ${HOOKS_DIR}/pretooluse-gemini.sh"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
}`;
|
|
100
|
+
|
|
101
|
+
const CODEX_HOOK_SETTINGS = `{
|
|
102
|
+
"hooks": {
|
|
103
|
+
"PreToolUse": [
|
|
104
|
+
{
|
|
105
|
+
"matcher": "Bash",
|
|
106
|
+
"hooks": [
|
|
107
|
+
{
|
|
108
|
+
"type": "command",
|
|
109
|
+
"command": "bash ${HOOKS_DIR}/pretooluse-codex.sh",
|
|
110
|
+
"statusMessage": "Checking Bash permissions"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
}`;
|
|
117
|
+
|
|
118
|
+
const CURSOR_HOOK_SETTINGS = `{
|
|
119
|
+
"version": 1,
|
|
120
|
+
"hooks": {
|
|
121
|
+
"preToolUse": [
|
|
122
|
+
{
|
|
123
|
+
"type": "command",
|
|
124
|
+
"command": "bash ${HOOKS_DIR}/pretooluse-cursor.sh",
|
|
125
|
+
"matcher": ".*"
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
}`;
|
|
130
|
+
|
|
131
|
+
const VSCODE_HOOK_SETTINGS = `{
|
|
132
|
+
"hooks": {
|
|
133
|
+
"PreToolUse": [
|
|
134
|
+
{
|
|
135
|
+
"matcher": "*",
|
|
136
|
+
"hooks": [
|
|
137
|
+
{
|
|
138
|
+
"type": "command",
|
|
139
|
+
"command": "bash ${HOOKS_DIR}/pretooluse-vscode.sh"
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
}`;
|
|
146
|
+
|
|
147
|
+
const VSCODE_HOOK_LOCATIONS_SETTINGS = `{
|
|
148
|
+
"chat.hookFilesLocations": {
|
|
149
|
+
"~/.copilot/hooks": true
|
|
150
|
+
}
|
|
151
|
+
}`;
|
|
152
|
+
|
|
153
|
+
const WINDSURF_HOOK_SETTINGS = `{
|
|
154
|
+
"hooks": {
|
|
155
|
+
"pre_run_command": [
|
|
156
|
+
{
|
|
157
|
+
"type": "command",
|
|
158
|
+
"command": "bash ${HOOKS_DIR}/pretooluse-windsurf.sh"
|
|
159
|
+
}
|
|
160
|
+
],
|
|
161
|
+
"pre_mcp_tool_use": [
|
|
162
|
+
{
|
|
163
|
+
"type": "command",
|
|
164
|
+
"command": "bash ${HOOKS_DIR}/pretooluse-windsurf.sh"
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
}`;
|
|
169
|
+
|
|
170
|
+
const CODEX_HOOK_FEATURES_TOML = `[features]
|
|
171
|
+
codex_hooks = true`;
|
|
172
|
+
|
|
85
173
|
/** Build a JSON config block for a given npx command string */
|
|
86
174
|
function jsonConfig(rootKey, npxCmd) {
|
|
87
175
|
const parts = npxCmd.split(' ');
|
|
@@ -459,6 +547,32 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
459
547
|
: `${msg}. Try the manual config below.`;
|
|
460
548
|
};
|
|
461
549
|
|
|
550
|
+
const buildInstallPayload = (client) => {
|
|
551
|
+
const payload = { client };
|
|
552
|
+
if (currentMethod === 'global' && pinnedVersion && pinnedVersion !== 'latest') {
|
|
553
|
+
payload.version = pinnedVersion;
|
|
554
|
+
} else if (currentChannel !== 'latest') {
|
|
555
|
+
payload.channel = currentChannel;
|
|
556
|
+
}
|
|
557
|
+
return payload;
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
const applyInstallSuccessState = (btn, status, data, verified) => {
|
|
561
|
+
btn.textContent = 'Installed';
|
|
562
|
+
btn.classList.remove('is-loading');
|
|
563
|
+
btn.classList.add('is-success');
|
|
564
|
+
if (!status) return;
|
|
565
|
+
|
|
566
|
+
if (data.hookInstall?.supported && !data.hookInstall?.configured && data.hookInstall?.assetsPrepared) {
|
|
567
|
+
status.textContent = 'Configured MCP server. Dollhouse hook assets were also prepared; finish manual permission setup in Permissions & Security.';
|
|
568
|
+
} else {
|
|
569
|
+
status.textContent = verified
|
|
570
|
+
? 'Verified — config written. Restart the application to activate.'
|
|
571
|
+
: 'Restart the application to activate.';
|
|
572
|
+
}
|
|
573
|
+
status.classList.add('is-success');
|
|
574
|
+
};
|
|
575
|
+
|
|
462
576
|
/** Handle Configure Now button click */
|
|
463
577
|
const handleInstallClick = async (btn) => {
|
|
464
578
|
const client = btn.dataset.installClient;
|
|
@@ -476,17 +590,10 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
476
590
|
}
|
|
477
591
|
|
|
478
592
|
try {
|
|
479
|
-
const payload = { client };
|
|
480
|
-
if (currentMethod === 'global' && pinnedVersion && pinnedVersion !== 'latest') {
|
|
481
|
-
payload.version = pinnedVersion;
|
|
482
|
-
} else if (currentChannel !== 'latest') {
|
|
483
|
-
payload.channel = currentChannel;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
593
|
const res = await DollhouseAuth.apiFetch('/api/setup/install', {
|
|
487
594
|
method: 'POST',
|
|
488
595
|
headers: { 'Content-Type': 'application/json' },
|
|
489
|
-
body: JSON.stringify(
|
|
596
|
+
body: JSON.stringify(buildInstallPayload(client)),
|
|
490
597
|
});
|
|
491
598
|
|
|
492
599
|
const data = await res.json();
|
|
@@ -500,16 +607,7 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
500
607
|
await fetchDetection();
|
|
501
608
|
updateDetectionState();
|
|
502
609
|
const verified = detectedConfigs[clientToPlatformReverse[client]]?.installed;
|
|
503
|
-
|
|
504
|
-
btn.textContent = 'Installed';
|
|
505
|
-
btn.classList.remove('is-loading');
|
|
506
|
-
btn.classList.add('is-success');
|
|
507
|
-
if (status) {
|
|
508
|
-
status.textContent = verified
|
|
509
|
-
? 'Verified — config written. Restart the application to activate.'
|
|
510
|
-
: 'Restart the application to activate.';
|
|
511
|
-
status.classList.add('is-success');
|
|
512
|
-
}
|
|
610
|
+
applyInstallSuccessState(btn, status, data, verified);
|
|
513
611
|
|
|
514
612
|
// Show the completion banner after any successful install
|
|
515
613
|
showCompletionBanner(client);
|
|
@@ -572,7 +670,7 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
572
670
|
btn.classList.add('is-success');
|
|
573
671
|
|
|
574
672
|
if (status) {
|
|
575
|
-
status.textContent =
|
|
673
|
+
status.textContent = data.hookInstall?.message || 'Permissions are enabled. Restart the client if it is already running.';
|
|
576
674
|
status.classList.add('is-success');
|
|
577
675
|
}
|
|
578
676
|
} catch (err) {
|
|
@@ -879,58 +977,163 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
879
977
|
lmstudio: 'LM Studio',
|
|
880
978
|
};
|
|
881
979
|
|
|
882
|
-
const
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
980
|
+
const VERIFIED_PERMISSION_PLATFORMS = {
|
|
981
|
+
'claude-code': {
|
|
982
|
+
label: 'Claude Code',
|
|
983
|
+
statusTag: 'claude code',
|
|
984
|
+
configPath: '<code>~/.claude/settings.json</code>',
|
|
985
|
+
scriptPath: HOOK_BASE_SCRIPT_PATH,
|
|
986
|
+
settingsBlock: CLAUDE_CODE_HOOK_SETTINGS,
|
|
987
|
+
},
|
|
988
|
+
};
|
|
891
989
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
990
|
+
const PARTIAL_PERMISSION_PLATFORMS = {
|
|
991
|
+
gemini: {
|
|
992
|
+
label: 'Gemini CLI',
|
|
993
|
+
statusTag: 'allow / deny',
|
|
994
|
+
configPath: '<code>~/.gemini/settings.json</code> or <code>.gemini/settings.json</code> in your project',
|
|
995
|
+
scriptPath: `${HOOKS_DIR}/pretooluse-gemini.sh`,
|
|
996
|
+
settingsBlock: GEMINI_HOOK_SETTINGS,
|
|
997
|
+
limitation: 'Gemini CLI exposes native BeforeTool hooks, but it does not support an ask/confirm response path. Confirmation-style policies currently degrade to deny.',
|
|
998
|
+
},
|
|
999
|
+
cursor: {
|
|
1000
|
+
label: 'Cursor',
|
|
1001
|
+
statusTag: 'native hooks',
|
|
1002
|
+
configPath: '<code>.cursor/hooks.json</code> in your project, or <code>~/.cursor/hooks.json</code> for all projects',
|
|
1003
|
+
scriptPath: `${HOOKS_DIR}/pretooluse-cursor.sh`,
|
|
1004
|
+
settingsBlock: CURSOR_HOOK_SETTINGS,
|
|
1005
|
+
limitation: 'Cursor exposes native hooks, but its permission handling still needs broader runtime verification across allow and ask decisions.',
|
|
1006
|
+
},
|
|
1007
|
+
vscode: {
|
|
1008
|
+
label: 'VS Code',
|
|
1009
|
+
statusTag: 'native hooks',
|
|
1010
|
+
configPath: '<code>~/.copilot/hooks/dollhouse-permissions.json</code> and VS Code user settings',
|
|
1011
|
+
scriptPath: `${HOOKS_DIR}/pretooluse-vscode.sh`,
|
|
1012
|
+
settingsBlock: VSCODE_HOOK_SETTINGS,
|
|
1013
|
+
featureBlock: VSCODE_HOOK_LOCATIONS_SETTINGS,
|
|
1014
|
+
featureHeading: '2. Enable <code>~/.copilot/hooks</code> in VS Code user settings',
|
|
1015
|
+
featureCopyLabel: 'Copy VS Code hookFilesLocations settings',
|
|
1016
|
+
limitation: 'VS Code exposes native PreToolUse hooks, but it ignores matcher values and uses tool names that differ from Claude Code. This adapter normalizes the common built-in tools we know about.',
|
|
1017
|
+
},
|
|
1018
|
+
windsurf: {
|
|
1019
|
+
label: 'Windsurf',
|
|
1020
|
+
statusTag: 'allow / deny',
|
|
1021
|
+
configPath: '<code>~/.codeium/windsurf/hooks.json</code> or <code>.windsurf/hooks.json</code> in your project',
|
|
1022
|
+
scriptPath: `${HOOKS_DIR}/pretooluse-windsurf.sh`,
|
|
1023
|
+
settingsBlock: WINDSURF_HOOK_SETTINGS,
|
|
1024
|
+
limitation: 'Windsurf exposes native pre-run and pre-MCP hooks, but they are binary allow-or-block hooks. Confirmation-style policies currently degrade to block.',
|
|
1025
|
+
},
|
|
1026
|
+
codex: {
|
|
1027
|
+
label: 'Codex',
|
|
1028
|
+
statusTag: 'bash only',
|
|
1029
|
+
configPath: '<code>~/.codex/hooks.json</code> and <code>~/.codex/config.toml</code>',
|
|
1030
|
+
scriptPath: `${HOOKS_DIR}/pretooluse-codex.sh`,
|
|
1031
|
+
settingsBlock: CODEX_HOOK_SETTINGS,
|
|
1032
|
+
featureBlock: CODEX_HOOK_FEATURES_TOML,
|
|
1033
|
+
limitation: 'Codex currently only supports native PreToolUse hooks for Bash, so this turns on Bash permission guardrails only.',
|
|
1034
|
+
},
|
|
1035
|
+
};
|
|
899
1036
|
|
|
1037
|
+
const getVerifiedPermissionStatusCopy = (verified, detected) => {
|
|
1038
|
+
if (detected?.hookInstalled) {
|
|
900
1039
|
return {
|
|
901
1040
|
tone: 'info',
|
|
902
|
-
titleText:
|
|
903
|
-
messageText: '
|
|
1041
|
+
titleText: `${verified.label} permission enforcement is enabled.`,
|
|
1042
|
+
messageText: 'No further changes are needed here unless you want to reinstall the hook settings.',
|
|
904
1043
|
};
|
|
905
1044
|
}
|
|
906
1045
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
};
|
|
915
|
-
}
|
|
1046
|
+
if (detected?.installed) {
|
|
1047
|
+
return {
|
|
1048
|
+
tone: 'warning',
|
|
1049
|
+
titleText: `${verified.label} is connected for this client.`,
|
|
1050
|
+
messageText: `DollhouseMCP is configured as an MCP server. Use Configure Now below to also install the ${verified.label} permission hook.`,
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
916
1053
|
|
|
1054
|
+
return {
|
|
1055
|
+
tone: 'info',
|
|
1056
|
+
titleText: `${verified.label} permissions are not configured yet.`,
|
|
1057
|
+
messageText: `First connect DollhouseMCP using Auto-updating or Pinned version, then use Configure Now below to install the ${verified.label} permission hook.`,
|
|
1058
|
+
};
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
const getPartialPermissionStatusCopy = (partial, detected) => {
|
|
1062
|
+
const activationLabel = partial.label === 'Codex' ? 'Bash guardrails' : 'permission hooks';
|
|
1063
|
+
if (detected?.hookInstalled) {
|
|
917
1064
|
return {
|
|
918
1065
|
tone: 'info',
|
|
919
|
-
titleText:
|
|
920
|
-
messageText:
|
|
1066
|
+
titleText: `${partial.label} ${activationLabel} are enabled.`,
|
|
1067
|
+
messageText: partial.limitation,
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
if (detected?.installed) {
|
|
1072
|
+
return {
|
|
1073
|
+
tone: 'warning',
|
|
1074
|
+
titleText: `${partial.label} is connected for this client.`,
|
|
1075
|
+
messageText: `DollhouseMCP is configured as an MCP server. Use Configure Now below to turn on ${partial.label}'s native ${activationLabel}.`,
|
|
921
1076
|
};
|
|
922
1077
|
}
|
|
923
1078
|
|
|
924
|
-
const platformLabel = PERMISSION_PLATFORM_LABELS[platformId] || 'this client';
|
|
925
1079
|
return {
|
|
926
|
-
tone:
|
|
927
|
-
titleText:
|
|
928
|
-
messageText:
|
|
929
|
-
? 'DollhouseMCP is connected for this client, but this release does not include a supported permissions setup flow here yet.'
|
|
930
|
-
: 'This release does not include a supported permissions setup flow for this client yet.',
|
|
1080
|
+
tone: 'info',
|
|
1081
|
+
titleText: `${partial.label} ${activationLabel} are not configured yet.`,
|
|
1082
|
+
messageText: `First connect DollhouseMCP using Auto-updating or Pinned version, then use Configure Now below to install ${partial.label}'s native ${activationLabel}.`,
|
|
931
1083
|
};
|
|
932
1084
|
};
|
|
933
1085
|
|
|
1086
|
+
const getManualPermissionStatusCopy = (detected) => {
|
|
1087
|
+
if (detected?.hookAssetsPrepared) {
|
|
1088
|
+
return {
|
|
1089
|
+
tone: 'info',
|
|
1090
|
+
titleText: 'Hook bridge files are already prepared for this client.',
|
|
1091
|
+
messageText: 'Finish the client-specific hook registration below to turn on permission enforcement.',
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
if (detected?.installed) {
|
|
1095
|
+
return {
|
|
1096
|
+
tone: 'warning',
|
|
1097
|
+
titleText: 'DollhouseMCP is connected for this client.',
|
|
1098
|
+
messageText: 'DollhouseMCP is configured here, but permission enforcement is separate. Use the manual hook steps below to turn it on for this client.',
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
return {
|
|
1103
|
+
tone: 'info',
|
|
1104
|
+
titleText: 'Manual permissions setup is available for this client.',
|
|
1105
|
+
messageText: 'Use the steps below if you want to turn on permission enforcement for this client manually.',
|
|
1106
|
+
};
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
const getUnsupportedPermissionStatusCopy = (platformLabel, detected) => ({
|
|
1110
|
+
tone: detected?.installed ? 'warning' : 'neutral',
|
|
1111
|
+
titleText: `Permissions & security tools are unavailable for ${platformLabel} right now.`,
|
|
1112
|
+
messageText: detected?.installed
|
|
1113
|
+
? 'DollhouseMCP is connected for this client, but this release does not include a supported permissions setup flow here yet.'
|
|
1114
|
+
: 'This release does not include a supported permissions setup flow for this client yet.',
|
|
1115
|
+
});
|
|
1116
|
+
|
|
1117
|
+
const getPermissionStatusCopy = (platformId, detected) => {
|
|
1118
|
+
const verified = VERIFIED_PERMISSION_PLATFORMS[platformId];
|
|
1119
|
+
if (verified) {
|
|
1120
|
+
return getVerifiedPermissionStatusCopy(verified, detected);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
const partial = PARTIAL_PERMISSION_PLATFORMS[platformId];
|
|
1124
|
+
if (partial) {
|
|
1125
|
+
return getPartialPermissionStatusCopy(partial, detected);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
const support = PLATFORMS.find((platform) => platform.id === platformId)?.hookSupport || 'unsupported';
|
|
1129
|
+
if (support === 'manual') {
|
|
1130
|
+
return getManualPermissionStatusCopy(detected);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
const platformLabel = PERMISSION_PLATFORM_LABELS[platformId] || 'this client';
|
|
1134
|
+
return getUnsupportedPermissionStatusCopy(platformLabel, detected);
|
|
1135
|
+
};
|
|
1136
|
+
|
|
934
1137
|
const updatePermissionStatus = (panel, platformId, detected) => {
|
|
935
1138
|
const status = panel?.querySelector('.setup-permission-status');
|
|
936
1139
|
if (!status) return;
|
|
@@ -950,6 +1153,7 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
950
1153
|
const panel = document.getElementById('setup-panel-' + platformId);
|
|
951
1154
|
const tabBtn = document.getElementById('setup-tab-' + platformId);
|
|
952
1155
|
updatePermissionStatus(panel, platformId, detected);
|
|
1156
|
+
updatePermissionInstallButton(panel?.querySelector('.setup-permission-install-btn'), detected);
|
|
953
1157
|
|
|
954
1158
|
if (!detected?.installed) return;
|
|
955
1159
|
|
|
@@ -958,7 +1162,6 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
958
1162
|
updateDetectionNotice(panel?.querySelector('.setup-installed-notice'), matches);
|
|
959
1163
|
updateDetectionBadge(tabBtn?.querySelector('.setup-tab-badge'), matches);
|
|
960
1164
|
updateDetectionButton(panel?.querySelector('.setup-install-btn'), matches);
|
|
961
|
-
updatePermissionInstallButton(panel?.querySelector('.setup-permission-install-btn'), detected);
|
|
962
1165
|
|
|
963
1166
|
// Refresh the "Current config" code block with the latest detected config
|
|
964
1167
|
if (detected.currentConfig && panel) {
|
|
@@ -1120,41 +1323,111 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
1120
1323
|
return html;
|
|
1121
1324
|
};
|
|
1122
1325
|
|
|
1123
|
-
const
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1326
|
+
const buildPartialAutoHint = (p, partial) => {
|
|
1327
|
+
const base = partial.limitation;
|
|
1328
|
+
if (p.id === 'codex') {
|
|
1329
|
+
return `${base} This automatic path writes the shared hook bridge, updates <code>~/.codex/hooks.json</code>, and enables <code>features.codex_hooks</code> in <code>~/.codex/config.toml</code>.`;
|
|
1330
|
+
}
|
|
1331
|
+
if (p.id === 'vscode') {
|
|
1332
|
+
return `${base} This automatic path writes the shared hook bridge, creates <code>~/.copilot/hooks/dollhouse-permissions.json</code>, and enables <code>~/.copilot/hooks</code> in VS Code's <code>chat.hookFilesLocations</code> setting.`;
|
|
1333
|
+
}
|
|
1334
|
+
return `${base} This automatic path writes the shared hook bridge and updates ${partial.configPath}.`;
|
|
1335
|
+
};
|
|
1126
1336
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1337
|
+
const buildPartialFeatureHeading = (p, partial) => {
|
|
1338
|
+
if (partial.featureHeading) return partial.featureHeading;
|
|
1339
|
+
if (p.id === 'codex') return '2. Enable Codex hooks in <code>~/.codex/config.toml</code>';
|
|
1340
|
+
return '2. Add the additional client settings';
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
const renderVerifiedPermissionSection = (p, verified) => {
|
|
1344
|
+
const permissionInstallClient = p.installClient || p.id;
|
|
1345
|
+
return `<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1346
|
+
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge--verified">${verified.statusTag}</span></h3>
|
|
1347
|
+
<div class="setup-permission-status" data-state="info">
|
|
1348
|
+
<strong class="setup-permission-status-title"></strong>
|
|
1349
|
+
<p class="setup-permission-status-msg"></p>
|
|
1350
|
+
</div>
|
|
1351
|
+
<div class="setup-install-row">
|
|
1352
|
+
<button class="setup-btn setup-btn-primary setup-permission-install-btn" type="button" data-permission-install-client="${permissionInstallClient}">Configure Now</button>
|
|
1353
|
+
<span class="setup-install-status" data-permission-install-status="${permissionInstallClient}"></span>
|
|
1354
|
+
</div>
|
|
1355
|
+
<p class="setup-hint">This writes the shared hook bridge assets and updates ${verified.configPath} automatically.</p>
|
|
1356
|
+
</div>
|
|
1357
|
+
<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1358
|
+
<details class="setup-manual-fallback">
|
|
1359
|
+
<summary>Manual fallback</summary>
|
|
1360
|
+
<div class="setup-manual-fallback-body">
|
|
1361
|
+
<h4>1. Save the shared hook bridge once</h4>
|
|
1362
|
+
<p>Save this file as <code>${HOOK_BASE_SCRIPT_PATH}</code>, then make it executable with <code>chmod +x ${HOOK_BASE_SCRIPT_PATH}</code>.</p>
|
|
1363
|
+
<div class="setup-code-block"><button class="setup-copy-btn" type="button" data-copy-text='${escapeAttr(HOOK_BASE_SCRIPT)}' aria-label="Copy shared hook bridge">Copy</button>
|
|
1364
|
+
<pre><code>${escapeHtml(HOOK_BASE_SCRIPT)}</code></pre>
|
|
1365
|
+
</div>
|
|
1366
|
+
<h4>2. Add the ${verified.label} hook settings</h4>
|
|
1367
|
+
<p>Add this block to ${verified.configPath} so ${verified.label} can call the hook bridge before tool use.</p>
|
|
1368
|
+
<div class="setup-code-block"><button class="setup-copy-btn" type="button" data-copy-text='${escapeAttr(verified.settingsBlock)}' aria-label="Copy ${verified.label} hook settings">Copy</button>
|
|
1369
|
+
<pre><code>${escapeHtml(verified.settingsBlock)}</code></pre>
|
|
1370
|
+
</div>
|
|
1371
|
+
<p class="setup-hint">Command hook target: <code>${verified.scriptPath}</code></p>
|
|
1137
1372
|
</div>
|
|
1138
|
-
|
|
1373
|
+
</details>
|
|
1374
|
+
</div>`;
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
const renderPartialPermissionSection = (p, partial) => {
|
|
1378
|
+
const permissionInstallClient = p.installClient || p.id;
|
|
1379
|
+
const autoHint = buildPartialAutoHint(p, partial);
|
|
1380
|
+
const featureHeading = buildPartialFeatureHeading(p, partial);
|
|
1381
|
+
const featureSection = partial.featureBlock
|
|
1382
|
+
? `<h4>${featureHeading}</h4>
|
|
1383
|
+
<div class="setup-code-block"><button class="setup-copy-btn" type="button" data-copy-text='${escapeAttr(partial.featureBlock)}' aria-label="${escapeAttr(partial.featureCopyLabel || `Copy ${partial.label} settings`)}">Copy</button>
|
|
1384
|
+
<pre><code>${escapeHtml(partial.featureBlock)}</code></pre>
|
|
1385
|
+
</div>`
|
|
1386
|
+
: '';
|
|
1387
|
+
const stepNumber = partial.featureBlock ? '3' : '2';
|
|
1388
|
+
|
|
1389
|
+
return `<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1390
|
+
<h3>Permissions & Security <span class="setup-support-badge setup-support-badge--manual">${partial.statusTag}</span></h3>
|
|
1391
|
+
<div class="setup-permission-status" data-state="info">
|
|
1392
|
+
<strong class="setup-permission-status-title"></strong>
|
|
1393
|
+
<p class="setup-permission-status-msg"></p>
|
|
1394
|
+
</div>
|
|
1395
|
+
<div class="setup-install-row">
|
|
1396
|
+
<button class="setup-btn setup-btn-primary setup-permission-install-btn" type="button" data-permission-install-client="${permissionInstallClient}">Configure Now</button>
|
|
1397
|
+
<span class="setup-install-status" data-permission-install-status="${permissionInstallClient}"></span>
|
|
1139
1398
|
</div>
|
|
1140
|
-
<
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
<
|
|
1150
|
-
<p>Add this block to ${configPath} so Claude Code can call the hook bridge before tool use.</p>
|
|
1151
|
-
<div class="setup-code-block"><button class="setup-copy-btn" type="button" data-copy-text='${escapeAttr(CLAUDE_CODE_HOOK_SETTINGS)}' aria-label="Copy Claude Code hook settings">Copy</button>
|
|
1152
|
-
<pre><code>${escapeHtml(CLAUDE_CODE_HOOK_SETTINGS)}</code></pre>
|
|
1153
|
-
</div>
|
|
1154
|
-
<p class="setup-hint">Command hook target: <code>${HOOK_BASE_SCRIPT_PATH}</code></p>
|
|
1399
|
+
<p class="setup-hint">${autoHint}</p>
|
|
1400
|
+
</div>
|
|
1401
|
+
<div class="setup-method setup-security-mode" data-setup-modes="permissions" hidden>
|
|
1402
|
+
<details class="setup-manual-fallback">
|
|
1403
|
+
<summary>Manual fallback</summary>
|
|
1404
|
+
<div class="setup-manual-fallback-body">
|
|
1405
|
+
<h4>1. Save the shared hook bridge once</h4>
|
|
1406
|
+
<p>Save this file as <code>${HOOK_BASE_SCRIPT_PATH}</code>, then make it executable with <code>chmod +x ${HOOK_BASE_SCRIPT_PATH}</code>.</p>
|
|
1407
|
+
<div class="setup-code-block"><button class="setup-copy-btn" type="button" data-copy-text='${escapeAttr(HOOK_BASE_SCRIPT)}' aria-label="Copy shared hook bridge">Copy</button>
|
|
1408
|
+
<pre><code>${escapeHtml(HOOK_BASE_SCRIPT)}</code></pre>
|
|
1155
1409
|
</div>
|
|
1156
|
-
|
|
1157
|
-
|
|
1410
|
+
${featureSection}
|
|
1411
|
+
<h4>${stepNumber}. Add the ${partial.label} hook settings in ${partial.configPath}</h4>
|
|
1412
|
+
<div class="setup-code-block"><button class="setup-copy-btn" type="button" data-copy-text='${escapeAttr(partial.settingsBlock)}' aria-label="Copy ${partial.label} hook settings">Copy</button>
|
|
1413
|
+
<pre><code>${escapeHtml(partial.settingsBlock)}</code></pre>
|
|
1414
|
+
</div>
|
|
1415
|
+
<p class="setup-hint">Command hook target: <code>${partial.scriptPath}</code></p>
|
|
1416
|
+
</div>
|
|
1417
|
+
</details>
|
|
1418
|
+
</div>`;
|
|
1419
|
+
};
|
|
1420
|
+
|
|
1421
|
+
const renderPermissionSection = (p) => {
|
|
1422
|
+
const hookSupport = p.hookSupport || 'unsupported';
|
|
1423
|
+
const configPath = p.hookConfigPath || p.configPath || p.tomlPath || 'this client’s user configuration';
|
|
1424
|
+
|
|
1425
|
+
if (hookSupport === 'verified' && VERIFIED_PERMISSION_PLATFORMS[p.id]) {
|
|
1426
|
+
return renderVerifiedPermissionSection(p, VERIFIED_PERMISSION_PLATFORMS[p.id]);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
if (hookSupport === 'partial' && PARTIAL_PERMISSION_PLATFORMS[p.id]) {
|
|
1430
|
+
return renderPartialPermissionSection(p, PARTIAL_PERMISSION_PLATFORMS[p.id]);
|
|
1158
1431
|
}
|
|
1159
1432
|
|
|
1160
1433
|
if (hookSupport === 'manual') {
|
|
@@ -1194,7 +1467,7 @@ exec bash "$SCRIPT_DIR/pretooluse-dollhouse.sh"`;
|
|
|
1194
1467
|
|
|
1195
1468
|
intro.innerHTML = `<div class="setup-permissions-note">
|
|
1196
1469
|
<strong>Permissions & Security</strong>
|
|
1197
|
-
<p>Use this mode to turn on permission enforcement for supported clients. Claude Code is fully guided in this release. Where we have workable manual steps for other clients, they are shown here. Otherwise, the client will be marked as coming soon.</p>
|
|
1470
|
+
<p>Use this mode to turn on permission enforcement for supported clients. Claude Code is fully guided in this release, and Gemini CLI, Cursor, VS Code, Windsurf, plus Codex have native partial support. Where we have workable manual steps for other clients, they are shown here. Otherwise, the client will be marked as coming soon.</p>
|
|
1198
1471
|
</div>`;
|
|
1199
1472
|
};
|
|
1200
1473
|
|
|
@@ -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;AAsJ7E;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAkIrF"}
|