@dollhousemcp/mcp-server 2.0.29 → 2.0.31
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/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/handlers/mcp-aql/OperationSchema.js +2 -2
- package/dist/handlers/mcp-aql/evaluatePermission.d.ts.map +1 -1
- package/dist/handlers/mcp-aql/evaluatePermission.js +6 -3
- package/dist/services/BuildInfoService.d.ts +5 -0
- package/dist/services/BuildInfoService.d.ts.map +1 -1
- package/dist/services/BuildInfoService.js +44 -8
- package/dist/utils/permissionHookInstallers.d.ts +27 -0
- package/dist/utils/permissionHookInstallers.d.ts.map +1 -0
- package/dist/utils/permissionHookInstallers.js +465 -0
- package/dist/utils/permissionHookShared.d.ts +165 -0
- package/dist/utils/permissionHookShared.d.ts.map +1 -0
- package/dist/utils/permissionHookShared.js +425 -0
- package/dist/utils/permissionHookStatus.d.ts +10 -0
- package/dist/utils/permissionHookStatus.d.ts.map +1 -0
- package/dist/utils/permissionHookStatus.js +260 -0
- package/dist/utils/permissionHooks.d.ts +3 -91
- package/dist/utils/permissionHooks.d.ts.map +1 -1
- package/dist/utils/permissionHooks.js +4 -947
- package/dist/web/routes/healthRoutes.d.ts +3 -0
- package/dist/web/routes/healthRoutes.d.ts.map +1 -1
- package/dist/web/routes/healthRoutes.js +24 -2
- package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
- package/dist/web/routes/permissionRoutes.js +21 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +9 -2
- package/package.json +3 -1
- package/scripts/permission-hook-config.sh +67 -0
- package/scripts/pretooluse-dollhouse.sh +185 -38
- package/scripts/pretooluse-vscode.sh +23 -10
- package/scripts/pretooluse-windsurf.sh +6 -6
- package/server.json +2 -2
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
import { AUTO_REPAIRABLE_HOOK_HOSTS, auditHookAssets, collectHookMarkerPaths, collectHookMarkerPathsAsync, getPermissionHookDiagnosticsPath, getPrimaryHookScriptPath, installHookAssetsForHost, normalizeHookHost, readLastPermissionHookDiagnostic, readHostSpecificHookStatus, summarizeMarkerStatuses, supportsManagedHookAssets, } from './permissionHookShared.js';
|
|
4
|
+
let lastPermissionHookStartupRepairSummary = null;
|
|
5
|
+
export function getPermissionHookStatus(homeDir = homedir(), host) {
|
|
6
|
+
if (host) {
|
|
7
|
+
return readHostSpecificHookStatus(homeDir, host);
|
|
8
|
+
}
|
|
9
|
+
return summarizeMarkerStatuses(collectHookMarkerPaths(homeDir));
|
|
10
|
+
}
|
|
11
|
+
export async function getPermissionHookStatusAsync(homeDir = homedir(), host) {
|
|
12
|
+
if (host) {
|
|
13
|
+
return readHostSpecificHookStatus(homeDir, host);
|
|
14
|
+
}
|
|
15
|
+
return summarizeMarkerStatuses(await collectHookMarkerPathsAsync(homeDir));
|
|
16
|
+
}
|
|
17
|
+
function shouldAttemptHookAssetRepair(status, audit) {
|
|
18
|
+
return Boolean(status.installed
|
|
19
|
+
|| status.assetsPrepared
|
|
20
|
+
|| status.scriptPath
|
|
21
|
+
|| audit.assetsPrepared
|
|
22
|
+
|| audit.staleAssets.length > 0);
|
|
23
|
+
}
|
|
24
|
+
function buildFallbackPermissionHookStatus(baseStatus, normalizedHost, homeDir) {
|
|
25
|
+
return {
|
|
26
|
+
...baseStatus,
|
|
27
|
+
host: baseStatus.host ?? normalizedHost,
|
|
28
|
+
scriptPath: baseStatus.scriptPath ?? getPrimaryHookScriptPath(normalizedHost, homeDir),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async function auditAndMaybeRepairHookAssets(normalizedHost, homeDir, sourceScriptPath, autoRepair, fallbackStatus) {
|
|
32
|
+
let audit = await auditHookAssets(normalizedHost, homeDir, sourceScriptPath);
|
|
33
|
+
let autoRepaired = false;
|
|
34
|
+
if (!audit.assetsCurrent && autoRepair && shouldAttemptHookAssetRepair(fallbackStatus, audit)) {
|
|
35
|
+
await installHookAssetsForHost(normalizedHost, homeDir, sourceScriptPath);
|
|
36
|
+
audit = await auditHookAssets(normalizedHost, homeDir, sourceScriptPath);
|
|
37
|
+
autoRepaired = audit.assetsCurrent;
|
|
38
|
+
}
|
|
39
|
+
return { audit, autoRepaired };
|
|
40
|
+
}
|
|
41
|
+
function buildHookRepairFailureStatus(fallbackStatus, error) {
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
logger.warn(`[PermissionHooks] Failed to reconcile hook assets for ${fallbackStatus.host}: ${message}`);
|
|
44
|
+
return {
|
|
45
|
+
...fallbackStatus,
|
|
46
|
+
assetsCurrent: false,
|
|
47
|
+
autoRepaired: false,
|
|
48
|
+
needsRepair: true,
|
|
49
|
+
repairError: message,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function toStartupRepairOutcome(status) {
|
|
53
|
+
if (status.repairError)
|
|
54
|
+
return 'error';
|
|
55
|
+
if (status.autoRepaired)
|
|
56
|
+
return 'repaired';
|
|
57
|
+
if (status.needsRepair && (status.installed || status.assetsPrepared))
|
|
58
|
+
return 'needs_repair';
|
|
59
|
+
if (status.assetsCurrent)
|
|
60
|
+
return 'current';
|
|
61
|
+
return 'not_installed';
|
|
62
|
+
}
|
|
63
|
+
function toStartupRepairHostResult(host, status) {
|
|
64
|
+
return {
|
|
65
|
+
...status,
|
|
66
|
+
host,
|
|
67
|
+
outcome: toStartupRepairOutcome(status),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function cloneStartupRepairSummary(summary) {
|
|
71
|
+
if (!summary)
|
|
72
|
+
return null;
|
|
73
|
+
return {
|
|
74
|
+
...summary,
|
|
75
|
+
hostResults: summary.hostResults.map((result) => ({ ...result })),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function getLastPermissionHookStartupRepairSummary() {
|
|
79
|
+
return cloneStartupRepairSummary(lastPermissionHookStartupRepairSummary);
|
|
80
|
+
}
|
|
81
|
+
export function _resetPermissionHookStartupRepairSummaryForTests() {
|
|
82
|
+
lastPermissionHookStartupRepairSummary = null;
|
|
83
|
+
}
|
|
84
|
+
export async function reconcilePermissionHookStatus(host, options = {}) {
|
|
85
|
+
const normalizedHost = normalizeHookHost(host);
|
|
86
|
+
const homeDir = options.homeDir ?? homedir();
|
|
87
|
+
const sourceScriptPath = options.sourceScriptPath;
|
|
88
|
+
const autoRepair = options.autoRepair ?? false;
|
|
89
|
+
const baseStatus = readHostSpecificHookStatus(homeDir, normalizedHost);
|
|
90
|
+
if (!supportsManagedHookAssets(normalizedHost)) {
|
|
91
|
+
return baseStatus;
|
|
92
|
+
}
|
|
93
|
+
const fallbackStatus = buildFallbackPermissionHookStatus(baseStatus, normalizedHost, homeDir);
|
|
94
|
+
try {
|
|
95
|
+
const { audit, autoRepaired } = await auditAndMaybeRepairHookAssets(normalizedHost, homeDir, sourceScriptPath, autoRepair, fallbackStatus);
|
|
96
|
+
return {
|
|
97
|
+
...fallbackStatus,
|
|
98
|
+
assetsPrepared: audit.assetsPrepared,
|
|
99
|
+
assetsCurrent: audit.assetsCurrent,
|
|
100
|
+
autoRepaired,
|
|
101
|
+
needsRepair: !audit.assetsCurrent,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
return buildHookRepairFailureStatus(fallbackStatus, error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export async function getPermissionHookAuditSummary(homeDir = homedir()) {
|
|
109
|
+
const statuses = await Promise.all(AUTO_REPAIRABLE_HOOK_HOSTS.map(async (host) => ({
|
|
110
|
+
host,
|
|
111
|
+
status: await reconcilePermissionHookStatus(host, { homeDir }),
|
|
112
|
+
})));
|
|
113
|
+
const installedHosts = statuses
|
|
114
|
+
.filter(({ status }) => status.installed || status.assetsPrepared)
|
|
115
|
+
.map(({ host }) => host);
|
|
116
|
+
const currentHosts = statuses
|
|
117
|
+
.filter(({ status }) => status.assetsCurrent)
|
|
118
|
+
.map(({ host }) => host);
|
|
119
|
+
const repairedHosts = statuses
|
|
120
|
+
.filter(({ status }) => status.autoRepaired)
|
|
121
|
+
.map(({ host }) => host);
|
|
122
|
+
const needsRepairHosts = statuses
|
|
123
|
+
.filter(({ status }) => status.needsRepair)
|
|
124
|
+
.map(({ host }) => host);
|
|
125
|
+
const diagnosticsPath = getPermissionHookDiagnosticsPath(homeDir);
|
|
126
|
+
const lastDiagnostic = await readLastPermissionHookDiagnostic(homeDir);
|
|
127
|
+
return {
|
|
128
|
+
installedHosts,
|
|
129
|
+
currentHosts,
|
|
130
|
+
repairedHosts,
|
|
131
|
+
needsRepairHosts,
|
|
132
|
+
diagnosticsPath,
|
|
133
|
+
lastDiagnostic,
|
|
134
|
+
lastStartupRepair: getLastPermissionHookStartupRepairSummary(),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function formatHookHostLabel(count) {
|
|
138
|
+
return `${count} hook host${count === 1 ? '' : 's'}`;
|
|
139
|
+
}
|
|
140
|
+
function formatHookVerb(count, singular, plural) {
|
|
141
|
+
return count === 1 ? singular : plural;
|
|
142
|
+
}
|
|
143
|
+
function buildPermissionHookHealthMessage(summary, hadErrors, repairedCount, needsRepairCount) {
|
|
144
|
+
if (hadErrors) {
|
|
145
|
+
if (needsRepairCount > 0) {
|
|
146
|
+
const hostLabel = formatHookHostLabel(needsRepairCount);
|
|
147
|
+
const verb = formatHookVerb(needsRepairCount, 'needs', 'need');
|
|
148
|
+
return `${hostLabel} still ${verb} attention after startup repair`;
|
|
149
|
+
}
|
|
150
|
+
return 'A startup hook repair failed and needs attention';
|
|
151
|
+
}
|
|
152
|
+
if (needsRepairCount > 0) {
|
|
153
|
+
const hostLabel = formatHookHostLabel(needsRepairCount);
|
|
154
|
+
const verb = formatHookVerb(needsRepairCount, 'needs', 'need');
|
|
155
|
+
return `${hostLabel} still ${verb} repair`;
|
|
156
|
+
}
|
|
157
|
+
if (repairedCount > 0) {
|
|
158
|
+
const hostLabel = formatHookHostLabel(repairedCount);
|
|
159
|
+
return `${hostLabel} repaired on startup`;
|
|
160
|
+
}
|
|
161
|
+
if (summary.currentHosts.length > 0) {
|
|
162
|
+
return 'Managed hook assets are current';
|
|
163
|
+
}
|
|
164
|
+
return 'No managed hook assets currently installed';
|
|
165
|
+
}
|
|
166
|
+
export function summarizePermissionHookHealth(summary) {
|
|
167
|
+
const lastStartupRepair = summary.lastStartupRepair;
|
|
168
|
+
const hadErrors = Boolean(lastStartupRepair?.hostResults.some((result) => result.outcome === 'error'));
|
|
169
|
+
const needsRepairCount = lastStartupRepair?.needsRepairCount ?? summary.needsRepairHosts.length;
|
|
170
|
+
const repairedCount = lastStartupRepair?.repairedCount ?? summary.repairedHosts.length;
|
|
171
|
+
const message = buildPermissionHookHealthMessage(summary, hadErrors, repairedCount, needsRepairCount);
|
|
172
|
+
if (hadErrors) {
|
|
173
|
+
return {
|
|
174
|
+
status: 'error',
|
|
175
|
+
message,
|
|
176
|
+
repairedCount,
|
|
177
|
+
needsRepairCount,
|
|
178
|
+
lastCheckedAt: lastStartupRepair?.completedAt,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
if (needsRepairCount > 0) {
|
|
182
|
+
return {
|
|
183
|
+
status: 'warning',
|
|
184
|
+
message,
|
|
185
|
+
repairedCount,
|
|
186
|
+
needsRepairCount,
|
|
187
|
+
lastCheckedAt: lastStartupRepair?.completedAt,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
if (repairedCount > 0) {
|
|
191
|
+
return {
|
|
192
|
+
status: 'ok',
|
|
193
|
+
message,
|
|
194
|
+
repairedCount,
|
|
195
|
+
needsRepairCount,
|
|
196
|
+
lastCheckedAt: lastStartupRepair?.completedAt,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
status: 'ok',
|
|
201
|
+
message,
|
|
202
|
+
repairedCount,
|
|
203
|
+
needsRepairCount,
|
|
204
|
+
lastCheckedAt: lastStartupRepair?.completedAt,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
export async function repairPermissionHooksOnStartup(homeDir = homedir(), sourceScriptPath) {
|
|
208
|
+
const startedAt = Date.now();
|
|
209
|
+
const startedAtIso = new Date(startedAt).toISOString();
|
|
210
|
+
const hostResults = [];
|
|
211
|
+
// Process sequentially because several hosts share the same bridge/helper
|
|
212
|
+
// targets under ~/.dollhouse/hooks, and concurrent writes are flaky on Windows.
|
|
213
|
+
for (const host of AUTO_REPAIRABLE_HOOK_HOSTS) {
|
|
214
|
+
try {
|
|
215
|
+
const status = await reconcilePermissionHookStatus(host, {
|
|
216
|
+
homeDir,
|
|
217
|
+
autoRepair: true,
|
|
218
|
+
sourceScriptPath,
|
|
219
|
+
});
|
|
220
|
+
if (status.autoRepaired) {
|
|
221
|
+
logger.info(`[PermissionHooks] Refreshed installed hook assets for ${host}`);
|
|
222
|
+
}
|
|
223
|
+
else if (status.needsRepair && status.installed) {
|
|
224
|
+
logger.warn(`[PermissionHooks] Hook assets still need repair for ${host}` +
|
|
225
|
+
(status.repairError ? `: ${status.repairError}` : ''));
|
|
226
|
+
}
|
|
227
|
+
hostResults.push(toStartupRepairHostResult(host, status));
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
231
|
+
logger.warn(`[PermissionHooks] Startup hook repair failed for ${host}: ${message}`);
|
|
232
|
+
hostResults.push({
|
|
233
|
+
host,
|
|
234
|
+
installed: false,
|
|
235
|
+
assetsPrepared: false,
|
|
236
|
+
assetsCurrent: false,
|
|
237
|
+
autoRepaired: false,
|
|
238
|
+
needsRepair: true,
|
|
239
|
+
repairError: message,
|
|
240
|
+
outcome: 'error',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const repairedCount = hostResults.filter((result) => result.outcome === 'repaired').length;
|
|
245
|
+
const needsRepairCount = hostResults.filter((result) => result.outcome === 'needs_repair' || result.outcome === 'error').length;
|
|
246
|
+
const completedAt = Date.now();
|
|
247
|
+
const summary = {
|
|
248
|
+
startedAt: startedAtIso,
|
|
249
|
+
completedAt: new Date(completedAt).toISOString(),
|
|
250
|
+
durationMs: completedAt - startedAt,
|
|
251
|
+
repairedCount,
|
|
252
|
+
needsRepairCount,
|
|
253
|
+
hostResults,
|
|
254
|
+
};
|
|
255
|
+
lastPermissionHookStartupRepairSummary = cloneStartupRepairSummary(summary);
|
|
256
|
+
logger.info(`[PermissionHooks] Startup hook asset audit completed in ${summary.durationMs}ms ` +
|
|
257
|
+
`(repaired=${repairedCount}, needsRepair=${needsRepairCount})`);
|
|
258
|
+
return summary;
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbkhvb2tTdGF0dXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvcGVybWlzc2lvbkhvb2tTdGF0dXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sRUFRTCwwQkFBMEIsRUFDMUIsZUFBZSxFQUNmLHNCQUFzQixFQUN0QiwyQkFBMkIsRUFDM0IsZ0NBQWdDLEVBQ2hDLHdCQUF3QixFQUN4Qix3QkFBd0IsRUFDeEIsaUJBQWlCLEVBQ2pCLGdDQUFnQyxFQUNoQywwQkFBMEIsRUFDMUIsdUJBQXVCLEVBQ3ZCLHlCQUF5QixHQUMxQixNQUFNLDJCQUEyQixDQUFDO0FBRW5DLElBQUksc0NBQXNDLEdBQThDLElBQUksQ0FBQztBQUU3RixNQUFNLFVBQVUsdUJBQXVCLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxFQUFFLElBQWE7SUFDeEUsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNULE9BQU8sMEJBQTBCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxPQUFPLHVCQUF1QixDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsNEJBQTRCLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxFQUFFLElBQWE7SUFDbkYsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNULE9BQU8sMEJBQTBCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRCxPQUFPLHVCQUF1QixDQUFDLE1BQU0sMkJBQTJCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRUQsU0FBUyw0QkFBNEIsQ0FDbkMsTUFBNEIsRUFD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Z0JBQ2pCLFdBQVcsRUFBRSxPQUFPO2dCQUNwQixPQUFPLEVBQUUsT0FBTzthQUMrQixDQUFDLENBQUM7UUFDckQsQ0FBQztJQUNILENBQUM7SUFDRCxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxLQUFLLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMzRixNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUNyRCxNQUFNLENBQUMsT0FBTyxLQUFLLGNBQWMsSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMxRSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDL0IsTUFBTSxPQUFPLEdBQXVDO1FBQ2xELFNBQVMsRUFBRSxZQUFZO1FBQ3ZCLFdBQVcsRUFBRSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxXQUFXLEVBQUU7UUFDaEQsVUFBVSxFQUFFLFdBQVcsR0FBRyxTQUFTO1FBQ25DLGFBQWE7UUFDYixnQkFBZ0I7UUFDaEIsV0FBVztLQUNaLENBQUM7SUFDRixzQ0FBc0MsR0FBRyx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM1RSxNQUFNLENBQUMsSUFBSSxDQUNULDJEQUEyRCxPQUFPLENBQUMsVUFBVSxLQUFLO1FBQ2xGLGFBQWEsYUFBYSxpQkFBaUIsZ0JBQWdCLEdBQUcsQ0FDL0QsQ0FBQztJQUNGLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQge1xuICB0eXBlIFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5LFxuICB0eXBlIFBlcm1pc3Npb25Ib29rSGVhbHRoU3VtbWFyeSxcbiAgdHlwZSBIb29rQXNzZXRBdWRpdFJlc3VsdCxcbiAgdHlwZSBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0LFxuICB0eXBlIFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnksXG4gIHR5cGUgUGVybWlzc2lvbkhvb2tTdGF0dXMsXG4gIHR5cGUgUmVjb25jaWxlUGVybWlzc2lvbkhvb2tPcHRpb25zLFxuICBBVVRPX1JFUEFJUkFCTEVfSE9PS19IT1NUUyxcbiAgYXVkaXRIb29rQXNzZXRzLFxuICBjb2xsZWN0SG9va01hcmtlclBhdGhzLFxuICBjb2xsZWN0SG9va01hcmtlclBhdGhzQXN5bmMsXG4gIGdldFBlcm1pc3Npb25Ib29rRGlhZ25vc3RpY3NQYXRoLFxuICBnZXRQcmltYXJ5SG9va1NjcmlwdFBhdGgsXG4gIGluc3RhbGxIb29rQXNzZXRzRm9ySG9zdCxcbiAgbm9ybWFsaXplSG9va0hvc3QsXG4gIHJlYWRMYXN0UGVybWlzc2lvbkhvb2tEaWFnbm9zdGljLFxuICByZWFkSG9zdFNwZWNpZmljSG9va1N0YXR1cyxcbiAgc3VtbWFyaXplTWFya2VyU3RhdHVzZXMsXG4gIHN1cHBvcnRzTWFuYWdlZEhvb2tBc3NldHMsXG59IGZyb20gJy4vcGVybWlzc2lvbkhvb2tTaGFyZWQuanMnO1xuXG5sZXQgbGFzdFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnk6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBlcm1pc3Npb25Ib29rU3RhdHVzKGhvbWVEaXIgPSBob21lZGlyKCksIGhvc3Q/OiBzdHJpbmcpOiBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIGlmIChob3N0KSB7XG4gICAgcmV0dXJuIHJlYWRIb3N0U3BlY2lmaWNIb29rU3RhdHVzKGhvbWVEaXIsIGhvc3QpO1xuICB9XG5cbiAgcmV0dXJuIHN1bW1hcml6ZU1hcmtlclN0YXR1c2VzKGNvbGxlY3RIb29rTWFya2VyUGF0aHMoaG9tZURpcikpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0UGVybWlzc2lvbkhvb2tTdGF0dXNBc3luYyhob21lRGlyID0gaG9tZWRpcigpLCBob3N0Pzogc3RyaW5nKTogUHJvbWlzZTxQZXJtaXNzaW9uSG9va1N0YXR1cz4ge1xuICBpZiAoaG9zdCkge1xuICAgIHJldHVybiByZWFkSG9zdFNwZWNpZmljSG9va1N0YXR1cyhob21lRGlyLCBob3N0KTtcbiAgfVxuXG4gIHJldHVybiBzdW1tYXJpemVNYXJrZXJTdGF0dXNlcyhhd2FpdCBjb2xsZWN0SG9va01hcmtlclBhdGhzQXN5bmMoaG9tZURpcikpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRBdHRlbXB0SG9va0Fzc2V0UmVwYWlyKFxuICBzdGF0dXM6IFBlcm1pc3Npb25Ib29rU3RhdHVzLFxuICBhdWRpdDogSG9va0Fzc2V0QXVkaXRSZXN1bHQsXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgc3RhdHVzLmluc3RhbGxlZFxuICAgIHx8IHN0YXR1cy5hc3NldHNQcmVwYXJlZFxuICAgIHx8IHN0YXR1cy5zY3JpcHRQYXRoXG4gICAgfHwgYXVkaXQuYXNzZXRzUHJlcGFyZWRcbiAgICB8fCBhdWRpdC5zdGFsZUFzc2V0cy5sZW5ndGggPiAwLFxuICApO1xufVxuXG5mdW5jdGlvbiBidWlsZEZhbGxiYWNrUGVybWlzc2lvbkhvb2tTdGF0dXMoXG4gIGJhc2VTdGF0dXM6IFBlcm1pc3Npb25Ib29rU3RhdHVzLFxuICBub3JtYWxpemVkSG9zdDogc3RyaW5nLFxuICBob21lRGlyOiBzdHJpbmcsXG4pOiBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIHJldHVybiB7XG4gICAgLi4uYmFzZVN0YXR1cyxcbiAgICBob3N0OiBiYXNlU3RhdHVzLmhvc3QgPz8gbm9ybWFsaXplZEhvc3QsXG4gICAgc2NyaXB0UGF0aDogYmFzZVN0YXR1cy5zY3JpcHRQYXRoID8/IGdldFByaW1hcnlIb29rU2NyaXB0UGF0aChub3JtYWxpemVkSG9zdCwgaG9tZURpciksXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGF1ZGl0QW5kTWF5YmVSZXBhaXJIb29rQXNzZXRzKFxuICBub3JtYWxpemVkSG9zdDogc3RyaW5nLFxuICBob21lRGlyOiBzdHJpbmcsXG4gIHNvdXJjZVNjcmlwdFBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgYXV0b1JlcGFpcjogYm9vbGVhbixcbiAgZmFsbGJhY2tTdGF0dXM6IFBlcm1pc3Npb25Ib29rU3RhdHVzLFxuKTogUHJvbWlzZTx7IGF1ZGl0OiBIb29rQXNzZXRBdWRpdFJlc3VsdDsgYXV0b1JlcGFpcmVkOiBib29sZWFuIH0+IHtcbiAgbGV0IGF1ZGl0ID0gYXdhaXQgYXVkaXRIb29rQXNzZXRzKG5vcm1hbGl6ZWRIb3N0LCBob21lRGlyLCBzb3VyY2VTY3JpcHRQYXRoKTtcbiAgbGV0IGF1dG9SZXBhaXJlZCA9IGZhbHNlO1xuXG4gIGlmICghYXVkaXQuYXNzZXRzQ3VycmVudCAmJiBhdXRvUmVwYWlyICYmIHNob3VsZEF0dGVtcHRIb29rQXNzZXRSZXBhaXIoZmFsbGJhY2tTdGF0dXMsIGF1ZGl0KSkge1xuICAgIGF3YWl0IGluc3RhbGxIb29rQXNzZXRzRm9ySG9zdChub3JtYWxpemVkSG9zdCwgaG9tZURpciwgc291cmNlU2NyaXB0UGF0aCk7XG4gICAgYXVkaXQgPSBhd2FpdCBhdWRpdEhvb2tBc3NldHMobm9ybWFsaXplZEhvc3QsIGhvbWVEaXIsIHNvdXJjZVNjcmlwdFBhdGgpO1xuICAgIGF1dG9SZXBhaXJlZCA9IGF1ZGl0LmFzc2V0c0N1cnJlbnQ7XG4gIH1cblxuICByZXR1cm4geyBhdWRpdCwgYXV0b1JlcGFpcmVkIH07XG59XG5cbmZ1bmN0aW9uIGJ1aWxkSG9va1JlcGFpckZhaWx1cmVTdGF0dXMoXG4gIGZhbGxiYWNrU3RhdHVzOiBQZXJtaXNzaW9uSG9va1N0YXR1cyxcbiAgZXJyb3I6IHVua25vd24sXG4pOiBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gIGxvZ2dlci53YXJuKGBbUGVybWlzc2lvbkhvb2tzXSBGYWlsZWQgdG8gcmVjb25jaWxlIGhvb2sgYXNzZXRzIGZvciAke2ZhbGxiYWNrU3RhdHVzLmhvc3R9OiAke21lc3NhZ2V9YCk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5mYWxsYmFja1N0YXR1cyxcbiAgICBhc3NldHNDdXJyZW50OiBmYWxzZSxcbiAgICBhdXRvUmVwYWlyZWQ6IGZhbHNlLFxuICAgIG5lZWRzUmVwYWlyOiB0cnVlLFxuICAgIHJlcGFpckVycm9yOiBtZXNzYWdlLFxuICB9O1xufVxuXG5mdW5jdGlvbiB0b1N0YXJ0dXBSZXBhaXJPdXRjb21lKHN0YXR1czogUGVybWlzc2lvbkhvb2tTdGF0dXMpOiBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0WydvdXRjb21lJ10ge1xuICBpZiAoc3RhdHVzLnJlcGFpckVycm9yKSByZXR1cm4gJ2Vycm9yJztcbiAgaWYgKHN0YXR1cy5hdXRvUmVwYWlyZWQpIHJldHVybiAncmVwYWlyZWQnO1xuICBpZiAoc3RhdHVzLm5lZWRzUmVwYWlyICYmIChzdGF0dXMuaW5zdGFsbGVkIHx8IHN0YXR1cy5hc3NldHNQcmVwYXJlZCkpIHJldHVybiAnbmVlZHNfcmVwYWlyJztcbiAgaWYgKHN0YXR1cy5hc3NldHNDdXJyZW50KSByZXR1cm4gJ2N1cnJlbnQnO1xuICByZXR1cm4gJ25vdF9pbnN0YWxsZWQnO1xufVxuXG5mdW5jdGlvbiB0b1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0KFxuICBob3N0OiBzdHJpbmcsXG4gIHN0YXR1czogUGVybWlzc2lvbkhvb2tTdGF0dXMsXG4pOiBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0dXMsXG4gICAgaG9zdCxcbiAgICBvdXRjb21lOiB0b1N0YXJ0dXBSZXBhaXJPdXRjb21lKHN0YXR1cyksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsb25lU3RhcnR1cFJlcGFpclN1bW1hcnkoXG4gIHN1bW1hcnk6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgfCBudWxsLFxuKTogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSB8IG51bGwge1xuICBpZiAoIXN1bW1hcnkpIHJldHVybiBudWxsO1xuICByZXR1cm4ge1xuICAgIC4uLnN1bW1hcnksXG4gICAgaG9zdFJlc3VsdHM6IHN1bW1hcnkuaG9zdFJlc3VsdHMubWFwKChyZXN1bHQpID0+ICh7IC4uLnJlc3VsdCB9KSksXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMYXN0UGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSgpOiBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5IHwgbnVsbCB7XG4gIHJldHVybiBjbG9uZVN0YXJ0dXBSZXBhaXJTdW1tYXJ5KGxhc3RQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF9yZXNldFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnlGb3JUZXN0cygpOiB2b2lkIHtcbiAgbGFzdFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgPSBudWxsO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVjb25jaWxlUGVybWlzc2lvbkhvb2tTdGF0dXMoXG4gIGhvc3Q6IHN0cmluZyxcbiAgb3B0aW9uczogUmVjb25jaWxlUGVybWlzc2lvbkhvb2tPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFBlcm1pc3Npb25Ib29rU3RhdHVzPiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRIb3N0ID0gbm9ybWFsaXplSG9va0hvc3QoaG9zdCk7XG4gIGNvbnN0IGhvbWVEaXIgPSBvcHRpb25zLmhvbWVEaXIgPz8gaG9tZWRpcigpO1xuICBjb25zdCBzb3VyY2VTY3JpcHRQYXRoID0gb3B0aW9ucy5zb3VyY2VTY3JpcHRQYXRoO1xuICBjb25zdCBhdXRvUmVwYWlyID0gb3B0aW9ucy5hdXRvUmVwYWlyID8/IGZhbHNlO1xuICBjb25zdCBiYXNlU3RhdHVzID0gcmVhZEhvc3RTcGVjaWZpY0hvb2tTdGF0dXMoaG9tZURpciwgbm9ybWFsaXplZEhvc3QpO1xuXG4gIGlmICghc3VwcG9ydHNNYW5hZ2VkSG9va0Fzc2V0cyhub3JtYWxpemVkSG9zdCkpIHtcbiAgICByZXR1cm4gYmFzZVN0YXR1cztcbiAgfVxuXG4gIGNvbnN0IGZhbGxiYWNrU3RhdHVzID0gYnVpbGRGYWxsYmFja1Blcm1pc3Npb25Ib29rU3RhdHVzKGJhc2VTdGF0dXMsIG5vcm1hbGl6ZWRIb3N0LCBob21lRGlyKTtcblxuICB0cnkge1xuICAgIGNvbnN0IHsgYXVkaXQsIGF1dG9SZXBhaXJlZCB9ID0gYXdhaXQgYXVkaXRBbmRNYXliZVJlcGFpckhvb2tBc3NldHMoXG4gICAgICBub3JtYWxpemVkSG9zdCxcbiAgICAgIGhvbWVEaXIsXG4gICAgICBzb3VyY2VTY3JpcHRQYXRoLFxuICAgICAgYXV0b1JlcGFpcixcbiAgICAgIGZhbGxiYWNrU3RhdHVzLFxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uZmFsbGJhY2tTdGF0dXMsXG4gICAgICBhc3NldHNQcmVwYXJlZDogYXVkaXQuYXNzZXRzUHJlcGFyZWQsXG4gICAgICBhc3NldHNDdXJyZW50OiBhdWRpdC5hc3NldHNDdXJyZW50LFxuICAgICAgYXV0b1JlcGFpcmVkLFxuICAgICAgbmVlZHNSZXBhaXI6ICFhdWRpdC5hc3NldHNDdXJyZW50LFxuICAgIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGJ1aWxkSG9va1JlcGFpckZhaWx1cmVTdGF0dXMoZmFsbGJhY2tTdGF0dXMsIGVycm9yKTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0UGVybWlzc2lvbkhvb2tBdWRpdFN1bW1hcnkoaG9tZURpciA9IGhvbWVkaXIoKSk6IFByb21pc2U8UGVybWlzc2lvbkhvb2tBdWRpdFN1bW1hcnk+IHtcbiAgY29uc3Qgc3RhdHVzZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBBVVRPX1JFUEFJUkFCTEVfSE9PS19IT1NUUy5tYXAoYXN5bmMgKGhvc3QpID0+ICh7XG4gICAgICBob3N0LFxuICAgICAgc3RhdHVzOiBhd2FpdCByZWNvbmNpbGVQZXJtaXNzaW9uSG9va1N0YXR1cyhob3N0LCB7IGhvbWVEaXIgfSksXG4gICAgfSkpLFxuICApO1xuXG4gIGNvbnN0IGluc3RhbGxlZEhvc3RzID0gc3RhdHVzZXNcbiAgICAuZmlsdGVyKCh7IHN0YXR1cyB9KSA9PiBzdGF0dXMuaW5zdGFsbGVkIHx8IHN0YXR1cy5hc3NldHNQcmVwYXJlZClcbiAgICAubWFwKCh7IGhvc3QgfSkgPT4gaG9zdCk7XG4gIGNvbnN0IGN1cnJlbnRIb3N0cyA9IHN0YXR1c2VzXG4gICAgLmZpbHRlcigoeyBzdGF0dXMgfSkgPT4gc3RhdHVzLmFzc2V0c0N1cnJlbnQpXG4gICAgLm1hcCgoeyBob3N0IH0pID0+IGhvc3QpO1xuICBjb25zdCByZXBhaXJlZEhvc3RzID0gc3RhdHVzZXNcbiAgICAuZmlsdGVyKCh7IHN0YXR1cyB9KSA9PiBzdGF0dXMuYXV0b1JlcGFpcmVkKVxuICAgIC5tYXAoKHsgaG9zdCB9KSA9PiBob3N0KTtcbiAgY29uc3QgbmVlZHNSZXBhaXJIb3N0cyA9IHN0YXR1c2VzXG4gICAgLmZpbHRlcigoeyBzdGF0dXMgfSkgPT4gc3RhdHVzLm5lZWRzUmVwYWlyKVxuICAgIC5tYXAoKHsgaG9zdCB9KSA9PiBob3N0KTtcbiAgY29uc3QgZGlhZ25vc3RpY3NQYXRoID0gZ2V0UGVybWlzc2lvbkhvb2tEaWFnbm9zdGljc1BhdGgoaG9tZURpcik7XG4gIGNvbnN0IGxhc3REaWFnbm9zdGljID0gYXdhaXQgcmVhZExhc3RQZXJtaXNzaW9uSG9va0RpYWdub3N0aWMoaG9tZURpcik7XG5cbiAgcmV0dXJuIHtcbiAgICBpbnN0YWxsZWRIb3N0cyxcbiAgICBjdXJyZW50SG9zdHMsXG4gICAgcmVwYWlyZWRIb3N0cyxcbiAgICBuZWVkc1JlcGFpckhvc3RzLFxuICAgIGRpYWdub3N0aWNzUGF0aCxcbiAgICBsYXN0RGlhZ25vc3RpYyxcbiAgICBsYXN0U3RhcnR1cFJlcGFpcjogZ2V0TGFzdFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkoKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0SG9va0hvc3RMYWJlbChjb3VudDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke2NvdW50fSBob29rIGhvc3Qke2NvdW50ID09PSAxID8gJycgOiAncyd9YDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0SG9va1ZlcmIoY291bnQ6IG51bWJlciwgc2luZ3VsYXI6IHN0cmluZywgcGx1cmFsOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY291bnQgPT09IDEgPyBzaW5ndWxhciA6IHBsdXJhbDtcbn1cblxuZnVuY3Rpb24gYnVpbGRQZXJtaXNzaW9uSG9va0hlYWx0aE1lc3NhZ2UoXG4gIHN1bW1hcnk6IFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5LFxuICBoYWRFcnJvcnM6IGJvb2xlYW4sXG4gIHJlcGFpcmVkQ291bnQ6IG51bWJlcixcbiAgbmVlZHNSZXBhaXJDb3VudDogbnVtYmVyLFxuKTogc3RyaW5nIHtcbiAgaWYgKGhhZEVycm9ycykge1xuICAgIGlmIChuZWVkc1JlcGFpckNvdW50ID4gMCkge1xuICAgICAgY29uc3QgaG9zdExhYmVsID0gZm9ybWF0SG9va0hvc3RMYWJlbChuZWVkc1JlcGFpckNvdW50KTtcbiAgICAgIGNvbnN0IHZlcmIgPSBmb3JtYXRIb29rVmVyYihuZWVkc1JlcGFpckNvdW50LCAnbmVlZHMnLCAnbmVlZCcpO1xuICAgICAgcmV0dXJuIGAke2hvc3RMYWJlbH0gc3RpbGwgJHt2ZXJifSBhdHRlbnRpb24gYWZ0ZXIgc3RhcnR1cCByZXBhaXJgO1xuICAgIH1cblxuICAgIHJldHVybiAnQSBzdGFydHVwIGhvb2sgcmVwYWlyIGZhaWxlZCBhbmQgbmVlZHMgYXR0ZW50aW9uJztcbiAgfVxuXG4gIGlmIChuZWVkc1JlcGFpckNvdW50ID4gMCkge1xuICAgIGNvbnN0IGhvc3RMYWJlbCA9IGZvcm1hdEhvb2tIb3N0TGFiZWwobmVlZHNSZXBhaXJDb3VudCk7XG4gICAgY29uc3QgdmVyYiA9IGZvcm1hdEhvb2tWZXJiKG5lZWRzUmVwYWlyQ291bnQsICduZWVkcycsICduZWVkJyk7XG4gICAgcmV0dXJuIGAke2hvc3RMYWJlbH0gc3RpbGwgJHt2ZXJifSByZXBhaXJgO1xuICB9XG5cbiAgaWYgKHJlcGFpcmVkQ291bnQgPiAwKSB7XG4gICAgY29uc3QgaG9zdExhYmVsID0gZm9ybWF0SG9va0hvc3RMYWJlbChyZXBhaXJlZENvdW50KTtcbiAgICByZXR1cm4gYCR7aG9zdExhYmVsfSByZXBhaXJlZCBvbiBzdGFydHVwYDtcbiAgfVxuXG4gIGlmIChzdW1tYXJ5LmN1cnJlbnRIb3N0cy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuICdNYW5hZ2VkIGhvb2sgYXNzZXRzIGFyZSBjdXJyZW50JztcbiAgfVxuXG4gIHJldHVybiAnTm8gbWFuYWdlZCBob29rIGFzc2V0cyBjdXJyZW50bHkgaW5zdGFsbGVkJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1bW1hcml6ZVBlcm1pc3Npb25Ib29rSGVhbHRoKFxuICBzdW1tYXJ5OiBQZXJtaXNzaW9uSG9va0F1ZGl0U3VtbWFyeSxcbik6IFBlcm1pc3Npb25Ib29rSGVhbHRoU3VtbWFyeSB7XG4gIGNvbnN0IGxhc3RTdGFydHVwUmVwYWlyID0gc3VtbWFyeS5sYXN0U3RhcnR1cFJlcGFpcjtcbiAgY29uc3QgaGFkRXJyb3JzID0gQm9vbGVhbihcbiAgICBsYXN0U3RhcnR1cFJlcGFpcj8uaG9zdFJlc3VsdHMuc29tZSgocmVzdWx0KSA9PiByZXN1bHQub3V0Y29tZSA9PT0gJ2Vycm9yJyksXG4gICk7XG4gIGNvbnN0IG5lZWRzUmVwYWlyQ291bnQgPSBsYXN0U3RhcnR1cFJlcGFpcj8ubmVlZHNSZXBhaXJDb3VudCA/PyBzdW1tYXJ5Lm5lZWRzUmVwYWlySG9zdHMubGVuZ3RoO1xuICBjb25zdCByZXBhaXJlZENvdW50ID0gbGFzdFN0YXJ0dXBSZXBhaXI/LnJlcGFpcmVkQ291bnQgPz8gc3VtbWFyeS5yZXBhaXJlZEhvc3RzLmxlbmd0aDtcbiAgY29uc3QgbWVzc2FnZSA9IGJ1aWxkUGVybWlzc2lvbkhvb2tIZWFsdGhNZXNzYWdlKFxuICAgIHN1bW1hcnksXG4gICAgaGFkRXJyb3JzLFxuICAgIHJlcGFpcmVkQ291bnQsXG4gICAgbmVlZHNSZXBhaXJDb3VudCxcbiAgKTtcblxuICBpZiAoaGFkRXJyb3JzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIG1lc3NhZ2UsXG4gICAgICByZXBhaXJlZENvdW50LFxuICAgICAgbmVlZHNSZXBhaXJDb3VudCxcbiAgICAgIGxhc3RDaGVja2VkQXQ6IGxhc3RTdGFydHVwUmVwYWlyPy5jb21wbGV0ZWRBdCxcbiAgICB9O1xuICB9XG5cbiAgaWYgKG5lZWRzUmVwYWlyQ291bnQgPiAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ3dhcm5pbmcnLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHJlcGFpcmVkQ291bnQsXG4gICAgICBuZWVkc1JlcGFpckNvdW50LFxuICAgICAgbGFzdENoZWNrZWRBdDogbGFzdFN0YXJ0dXBSZXBhaXI/LmNvbXBsZXRlZEF0LFxuICAgIH07XG4gIH1cblxuICBpZiAocmVwYWlyZWRDb3VudCA+IDApIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnb2snLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHJlcGFpcmVkQ291bnQsXG4gICAgICBuZWVkc1JlcGFpckNvdW50LFxuICAgICAgbGFzdENoZWNrZWRBdDogbGFzdFN0YXJ0dXBSZXBhaXI/LmNvbXBsZXRlZEF0LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHN0YXR1czogJ29rJyxcbiAgICBtZXNzYWdlLFxuICAgIHJlcGFpcmVkQ291bnQsXG4gICAgbmVlZHNSZXBhaXJDb3VudCxcbiAgICBsYXN0Q2hlY2tlZEF0OiBsYXN0U3RhcnR1cFJlcGFpcj8uY29tcGxldGVkQXQsXG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXBhaXJQZXJtaXNzaW9uSG9va3NPblN0YXJ0dXAoXG4gIGhvbWVEaXIgPSBob21lZGlyKCksXG4gIHNvdXJjZVNjcmlwdFBhdGg/OiBzdHJpbmcsXG4pOiBQcm9taXNlPFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnk+IHtcbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3Qgc3RhcnRlZEF0SXNvID0gbmV3IERhdGUoc3RhcnRlZEF0KS50b0lTT1N0cmluZygpO1xuICBjb25zdCBob3N0UmVzdWx0czogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdFtdID0gW107XG5cbiAgLy8gUHJvY2VzcyBzZXF1ZW50aWFsbHkgYmVjYXVzZSBzZXZlcmFsIGhvc3RzIHNoYXJlIHRoZSBzYW1lIGJyaWRnZS9oZWxwZXJcbiAgLy8gdGFyZ2V0cyB1bmRlciB+Ly5kb2xsaG91c2UvaG9va3MsIGFuZCBjb25jdXJyZW50IHdyaXRlcyBhcmUgZmxha3kgb24gV2luZG93cy5cbiAgZm9yIChjb25zdCBob3N0IG9mIEFVVE9fUkVQQUlSQUJMRV9IT09LX0hPU1RTKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IHJlY29uY2lsZVBlcm1pc3Npb25Ib29rU3RhdHVzKGhvc3QsIHtcbiAgICAgICAgaG9tZURpcixcbiAgICAgICAgYXV0b1JlcGFpcjogdHJ1ZSxcbiAgICAgICAgc291cmNlU2NyaXB0UGF0aCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoc3RhdHVzLmF1dG9SZXBhaXJlZCkge1xuICAgICAgICBsb2dnZXIuaW5mbyhgW1Blcm1pc3Npb25Ib29rc10gUmVmcmVzaGVkIGluc3RhbGxlZCBob29rIGFzc2V0cyBmb3IgJHtob3N0fWApO1xuICAgICAgfSBlbHNlIGlmIChzdGF0dXMubmVlZHNSZXBhaXIgJiYgc3RhdHVzLmluc3RhbGxlZCkge1xuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBgW1Blcm1pc3Npb25Ib29rc10gSG9vayBhc3NldHMgc3RpbGwgbmVlZCByZXBhaXIgZm9yICR7aG9zdH1gICtcbiAgICAgICAgICAoc3RhdHVzLnJlcGFpckVycm9yID8gYDogJHtzdGF0dXMucmVwYWlyRXJyb3J9YCA6ICcnKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaG9zdFJlc3VsdHMucHVzaCh0b1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0KGhvc3QsIHN0YXR1cykpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgICAgbG9nZ2VyLndhcm4oYFtQZXJtaXNzaW9uSG9va3NdIFN0YXJ0dXAgaG9vayByZXBhaXIgZmFpbGVkIGZvciAke2hvc3R9OiAke21lc3NhZ2V9YCk7XG4gICAgICBob3N0UmVzdWx0cy5wdXNoKHtcbiAgICAgICAgaG9zdCxcbiAgICAgICAgaW5zdGFsbGVkOiBmYWxzZSxcbiAgICAgICAgYXNzZXRzUHJlcGFyZWQ6IGZhbHNlLFxuICAgICAgICBhc3NldHNDdXJyZW50OiBmYWxzZSxcbiAgICAgICAgYXV0b1JlcGFpcmVkOiBmYWxzZSxcbiAgICAgICAgbmVlZHNSZXBhaXI6IHRydWUsXG4gICAgICAgIHJlcGFpckVycm9yOiBtZXNzYWdlLFxuICAgICAgICBvdXRjb21lOiAnZXJyb3InLFxuICAgICAgfSBzYXRpc2ZpZXMgUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdCk7XG4gICAgfVxuICB9XG4gIGNvbnN0IHJlcGFpcmVkQ291bnQgPSBob3N0UmVzdWx0cy5maWx0ZXIoKHJlc3VsdCkgPT4gcmVzdWx0Lm91dGNvbWUgPT09ICdyZXBhaXJlZCcpLmxlbmd0aDtcbiAgY29uc3QgbmVlZHNSZXBhaXJDb3VudCA9IGhvc3RSZXN1bHRzLmZpbHRlcigocmVzdWx0KSA9PlxuICAgIHJlc3VsdC5vdXRjb21lID09PSAnbmVlZHNfcmVwYWlyJyB8fCByZXN1bHQub3V0Y29tZSA9PT0gJ2Vycm9yJykubGVuZ3RoO1xuICBjb25zdCBjb21wbGV0ZWRBdCA9IERhdGUubm93KCk7XG4gIGNvbnN0IHN1bW1hcnk6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgPSB7XG4gICAgc3RhcnRlZEF0OiBzdGFydGVkQXRJc28sXG4gICAgY29tcGxldGVkQXQ6IG5ldyBEYXRlKGNvbXBsZXRlZEF0KS50b0lTT1N0cmluZygpLFxuICAgIGR1cmF0aW9uTXM6IGNvbXBsZXRlZEF0IC0gc3RhcnRlZEF0LFxuICAgIHJlcGFpcmVkQ291bnQsXG4gICAgbmVlZHNSZXBhaXJDb3VudCxcbiAgICBob3N0UmVzdWx0cyxcbiAgfTtcbiAgbGFzdFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgPSBjbG9uZVN0YXJ0dXBSZXBhaXJTdW1tYXJ5KHN1bW1hcnkpO1xuICBsb2dnZXIuaW5mbyhcbiAgICBgW1Blcm1pc3Npb25Ib29rc10gU3RhcnR1cCBob29rIGFzc2V0IGF1ZGl0IGNvbXBsZXRlZCBpbiAke3N1bW1hcnkuZHVyYXRpb25Nc31tcyBgICtcbiAgICBgKHJlcGFpcmVkPSR7cmVwYWlyZWRDb3VudH0sIG5lZWRzUmVwYWlyPSR7bmVlZHNSZXBhaXJDb3VudH0pYCxcbiAgKTtcbiAgcmV0dXJuIHN1bW1hcnk7XG59XG4iXX0=
|
|
@@ -1,92 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
settingsPath?: string;
|
|
5
|
-
additionalPaths?: string[];
|
|
6
|
-
configured?: boolean;
|
|
7
|
-
assetsPrepared?: boolean;
|
|
8
|
-
installedAt: string;
|
|
9
|
-
}
|
|
10
|
-
export interface PermissionHookStatus {
|
|
11
|
-
installed: boolean;
|
|
12
|
-
configured?: boolean;
|
|
13
|
-
assetsPrepared?: boolean;
|
|
14
|
-
assetsCurrent?: boolean;
|
|
15
|
-
autoRepaired?: boolean;
|
|
16
|
-
needsRepair?: boolean;
|
|
17
|
-
repairError?: string;
|
|
18
|
-
host?: string;
|
|
19
|
-
scriptPath?: string;
|
|
20
|
-
settingsPath?: string;
|
|
21
|
-
additionalPaths?: string[];
|
|
22
|
-
}
|
|
23
|
-
export interface InstallPermissionHookResult {
|
|
24
|
-
supported: boolean;
|
|
25
|
-
installed: boolean;
|
|
26
|
-
configured: boolean;
|
|
27
|
-
assetsPrepared?: boolean;
|
|
28
|
-
host: string;
|
|
29
|
-
scriptPath?: string;
|
|
30
|
-
settingsPath?: string;
|
|
31
|
-
additionalPaths?: string[];
|
|
32
|
-
markerPath?: string;
|
|
33
|
-
backupPath?: string;
|
|
34
|
-
message: string;
|
|
35
|
-
}
|
|
36
|
-
export interface InstallPermissionHookOptions {
|
|
37
|
-
homeDir?: string;
|
|
38
|
-
sourceScriptPath?: string;
|
|
39
|
-
now?: Date;
|
|
40
|
-
}
|
|
41
|
-
export interface ReconcilePermissionHookOptions {
|
|
42
|
-
homeDir?: string;
|
|
43
|
-
sourceScriptPath?: string;
|
|
44
|
-
autoRepair?: boolean;
|
|
45
|
-
}
|
|
46
|
-
export interface PermissionHookAuditSummary {
|
|
47
|
-
installedHosts: string[];
|
|
48
|
-
currentHosts: string[];
|
|
49
|
-
repairedHosts: string[];
|
|
50
|
-
needsRepairHosts: string[];
|
|
51
|
-
}
|
|
52
|
-
export declare function getPermissionHookScriptPath(homeDir?: string): string;
|
|
53
|
-
export declare function getPermissionHookMarkerPath(homeDir?: string, host?: string): string;
|
|
54
|
-
export declare function getClaudeHookSettingsPath(homeDir?: string): string;
|
|
55
|
-
export declare function getVsCodeHookSettingsPath(homeDir?: string): string;
|
|
56
|
-
export declare function getVsCodeUserSettingsPath(homeDir?: string): string;
|
|
57
|
-
export declare function getGeminiHookSettingsPath(homeDir?: string): string;
|
|
58
|
-
export declare function getCursorHookSettingsPath(homeDir?: string): string;
|
|
59
|
-
export declare function getWindsurfHookSettingsPath(homeDir?: string): string;
|
|
60
|
-
export declare function getCodexHookSettingsPath(homeDir?: string): string;
|
|
61
|
-
export declare function getCodexConfigPath(homeDir?: string): string;
|
|
62
|
-
export declare function getPermissionHookStatus(homeDir?: string, host?: string): PermissionHookStatus;
|
|
63
|
-
export declare function getPermissionHookStatusAsync(homeDir?: string, host?: string): Promise<PermissionHookStatus>;
|
|
64
|
-
export declare function reconcilePermissionHookStatus(host: string, options?: ReconcilePermissionHookOptions): Promise<PermissionHookStatus>;
|
|
65
|
-
export declare function getPermissionHookAuditSummary(homeDir?: string): Promise<PermissionHookAuditSummary>;
|
|
66
|
-
export declare function repairPermissionHooksOnStartup(homeDir?: string): Promise<void>;
|
|
67
|
-
export declare function ensureClaudePreToolUseHook(parsed: Record<string, unknown>, command: string): {
|
|
68
|
-
changed: boolean;
|
|
69
|
-
parsed: Record<string, unknown>;
|
|
70
|
-
};
|
|
71
|
-
export declare function ensureVsCodePreToolUseHook(parsed: Record<string, unknown>, command: string): {
|
|
72
|
-
changed: boolean;
|
|
73
|
-
parsed: Record<string, unknown>;
|
|
74
|
-
};
|
|
75
|
-
export declare function ensureGeminiBeforeToolHook(parsed: Record<string, unknown>, command: string): {
|
|
76
|
-
changed: boolean;
|
|
77
|
-
parsed: Record<string, unknown>;
|
|
78
|
-
};
|
|
79
|
-
export declare function ensureCodexPreToolUseHook(parsed: Record<string, unknown>, command: string): {
|
|
80
|
-
changed: boolean;
|
|
81
|
-
parsed: Record<string, unknown>;
|
|
82
|
-
};
|
|
83
|
-
export declare function ensureCursorPreToolUseHook(parsed: Record<string, unknown>, command: string): {
|
|
84
|
-
changed: boolean;
|
|
85
|
-
parsed: Record<string, unknown>;
|
|
86
|
-
};
|
|
87
|
-
export declare function ensureWindsurfHooks(parsed: Record<string, unknown>, command: string): {
|
|
88
|
-
changed: boolean;
|
|
89
|
-
parsed: Record<string, unknown>;
|
|
90
|
-
};
|
|
91
|
-
export declare function installPermissionHook(client: string, options?: InstallPermissionHookOptions): Promise<InstallPermissionHookResult>;
|
|
1
|
+
export { AUTO_REPAIRABLE_HOOK_HOSTS, MANAGED_HOOK_WRAPPER_BASENAMES, WRAPPER_HOOK_HOSTS, type HookAssetAuditResult, type HookAssetDescriptor, type InstallPermissionHookOptions, type InstallPermissionHookResult, type PermissionHookAuditSummary, type PermissionHookDiagnosticRecord, type PermissionHookHealthSummary, type PermissionHookMarker, type PermissionHookStartupRepairHostResult, type PermissionHookStartupRepairSummary, type PermissionHookStatus, type ReconcilePermissionHookOptions, detectIndent, getClaudeHookSettingsPath, getCodexConfigPath, getPermissionHookDiagnosticsPath, getCodexHookSettingsPath, getCursorHookSettingsPath, getGeminiHookSettingsPath, getHookSourcePath, getHookWrapperBasename, getHookWrapperPath, getManagedHookAssets, getPermissionHookMarkerPath, getPermissionHookScriptPath, getPrimaryHookScriptPath, getVsCodeHookSettingsPath, getVsCodeUserSettingsPath, getWindsurfHookSettingsPath, installHookAssetsForHost, isMissingFileError, normalizeHookHost, readLastPermissionHookDiagnostic, readOptionalUtf8, supportsManagedHookAssets, writeBackupIfPresent, } from './permissionHookShared.js';
|
|
2
|
+
export { ensureClaudePreToolUseHook, ensureCodexPreToolUseHook, ensureCursorPreToolUseHook, ensureGeminiBeforeToolHook, ensureVsCodePreToolUseHook, ensureWindsurfHooks, installPermissionHook, } from './permissionHookInstallers.js';
|
|
3
|
+
export { _resetPermissionHookStartupRepairSummaryForTests, getLastPermissionHookStartupRepairSummary, getPermissionHookAuditSummary, getPermissionHookStatus, getPermissionHookStatusAsync, reconcilePermissionHookStatus, repairPermissionHooksOnStartup, summarizePermissionHookHealth, } from './permissionHookStatus.js';
|
|
92
4
|
//# sourceMappingURL=permissionHooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionHooks.d.ts","sourceRoot":"","sources":["../../src/utils/permissionHooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"permissionHooks.d.ts","sourceRoot":"","sources":["../../src/utils/permissionHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,EAC9B,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,EACzB,KAAK,qCAAqC,EAC1C,KAAK,kCAAkC,EACvC,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,YAAY,EACZ,yBAAyB,EACzB,kBAAkB,EAClB,gCAAgC,EAChC,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,gCAAgC,EAChC,gBAAgB,EAChB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,gDAAgD,EAChD,yCAAyC,EACzC,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,2BAA2B,CAAC"}
|