@dollhousemcp/mcp-server 2.0.28 → 2.0.30

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/generated/version.d.ts +2 -2
  3. package/dist/generated/version.js +3 -3
  4. package/dist/services/BuildInfoService.d.ts +9 -1
  5. package/dist/services/BuildInfoService.d.ts.map +1 -1
  6. package/dist/services/BuildInfoService.js +37 -3
  7. package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -1
  8. package/dist/tools/portfolio/submitToPortfolioTool.js +4 -3
  9. package/dist/utils/permissionHookInstallers.d.ts +27 -0
  10. package/dist/utils/permissionHookInstallers.d.ts.map +1 -0
  11. package/dist/utils/permissionHookInstallers.js +465 -0
  12. package/dist/utils/permissionHookShared.d.ts +126 -0
  13. package/dist/utils/permissionHookShared.d.ts.map +1 -0
  14. package/dist/utils/permissionHookShared.js +388 -0
  15. package/dist/utils/permissionHookStatus.d.ts +10 -0
  16. package/dist/utils/permissionHookStatus.d.ts.map +1 -0
  17. package/dist/utils/permissionHookStatus.js +256 -0
  18. package/dist/utils/permissionHooks.d.ts +3 -73
  19. package/dist/utils/permissionHooks.d.ts.map +1 -1
  20. package/dist/utils/permissionHooks.js +4 -780
  21. package/dist/web/public/permissions.js +10 -0
  22. package/dist/web/public/setup.js +36 -0
  23. package/dist/web/routes/healthRoutes.d.ts +3 -0
  24. package/dist/web/routes/healthRoutes.d.ts.map +1 -1
  25. package/dist/web/routes/healthRoutes.js +22 -2
  26. package/dist/web/routes/permissionRoutes.d.ts +1 -0
  27. package/dist/web/routes/permissionRoutes.d.ts.map +1 -1
  28. package/dist/web/routes/permissionRoutes.js +28 -7
  29. package/dist/web/routes/setupRoutes.d.ts +5 -1
  30. package/dist/web/routes/setupRoutes.d.ts.map +1 -1
  31. package/dist/web/routes/setupRoutes.js +28 -14
  32. package/dist/web/server.d.ts.map +1 -1
  33. package/dist/web/server.js +12 -1
  34. package/package.json +3 -1
  35. package/scripts/permission-hook-config.sh +67 -0
  36. package/scripts/pretooluse-dollhouse.sh +42 -13
  37. package/scripts/pretooluse-vscode.sh +23 -10
  38. package/scripts/pretooluse-windsurf.sh +6 -6
  39. package/server.json +2 -2
@@ -0,0 +1,256 @@
1
+ import { homedir } from 'node:os';
2
+ import { logger } from './logger.js';
3
+ import { AUTO_REPAIRABLE_HOOK_HOSTS, auditHookAssets, collectHookMarkerPaths, collectHookMarkerPathsAsync, getPrimaryHookScriptPath, installHookAssetsForHost, normalizeHookHost, 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
+ return {
126
+ installedHosts,
127
+ currentHosts,
128
+ repairedHosts,
129
+ needsRepairHosts,
130
+ lastStartupRepair: getLastPermissionHookStartupRepairSummary(),
131
+ };
132
+ }
133
+ function formatHookHostLabel(count) {
134
+ return `${count} hook host${count === 1 ? '' : 's'}`;
135
+ }
136
+ function formatHookVerb(count, singular, plural) {
137
+ return count === 1 ? singular : plural;
138
+ }
139
+ function buildPermissionHookHealthMessage(summary, hadErrors, repairedCount, needsRepairCount) {
140
+ if (hadErrors) {
141
+ if (needsRepairCount > 0) {
142
+ const hostLabel = formatHookHostLabel(needsRepairCount);
143
+ const verb = formatHookVerb(needsRepairCount, 'needs', 'need');
144
+ return `${hostLabel} still ${verb} attention after startup repair`;
145
+ }
146
+ return 'A startup hook repair failed and needs attention';
147
+ }
148
+ if (needsRepairCount > 0) {
149
+ const hostLabel = formatHookHostLabel(needsRepairCount);
150
+ const verb = formatHookVerb(needsRepairCount, 'needs', 'need');
151
+ return `${hostLabel} still ${verb} repair`;
152
+ }
153
+ if (repairedCount > 0) {
154
+ const hostLabel = formatHookHostLabel(repairedCount);
155
+ return `${hostLabel} repaired on startup`;
156
+ }
157
+ if (summary.currentHosts.length > 0) {
158
+ return 'Managed hook assets are current';
159
+ }
160
+ return 'No managed hook assets currently installed';
161
+ }
162
+ export function summarizePermissionHookHealth(summary) {
163
+ const lastStartupRepair = summary.lastStartupRepair;
164
+ const hadErrors = Boolean(lastStartupRepair?.hostResults.some((result) => result.outcome === 'error'));
165
+ const needsRepairCount = lastStartupRepair?.needsRepairCount ?? summary.needsRepairHosts.length;
166
+ const repairedCount = lastStartupRepair?.repairedCount ?? summary.repairedHosts.length;
167
+ const message = buildPermissionHookHealthMessage(summary, hadErrors, repairedCount, needsRepairCount);
168
+ if (hadErrors) {
169
+ return {
170
+ status: 'error',
171
+ message,
172
+ repairedCount,
173
+ needsRepairCount,
174
+ lastCheckedAt: lastStartupRepair?.completedAt,
175
+ };
176
+ }
177
+ if (needsRepairCount > 0) {
178
+ return {
179
+ status: 'warning',
180
+ message,
181
+ repairedCount,
182
+ needsRepairCount,
183
+ lastCheckedAt: lastStartupRepair?.completedAt,
184
+ };
185
+ }
186
+ if (repairedCount > 0) {
187
+ return {
188
+ status: 'ok',
189
+ message,
190
+ repairedCount,
191
+ needsRepairCount,
192
+ lastCheckedAt: lastStartupRepair?.completedAt,
193
+ };
194
+ }
195
+ return {
196
+ status: 'ok',
197
+ message,
198
+ repairedCount,
199
+ needsRepairCount,
200
+ lastCheckedAt: lastStartupRepair?.completedAt,
201
+ };
202
+ }
203
+ export async function repairPermissionHooksOnStartup(homeDir = homedir(), sourceScriptPath) {
204
+ const startedAt = Date.now();
205
+ const startedAtIso = new Date(startedAt).toISOString();
206
+ const hostResults = [];
207
+ // Process sequentially because several hosts share the same bridge/helper
208
+ // targets under ~/.dollhouse/hooks, and concurrent writes are flaky on Windows.
209
+ for (const host of AUTO_REPAIRABLE_HOOK_HOSTS) {
210
+ try {
211
+ const status = await reconcilePermissionHookStatus(host, {
212
+ homeDir,
213
+ autoRepair: true,
214
+ sourceScriptPath,
215
+ });
216
+ if (status.autoRepaired) {
217
+ logger.info(`[PermissionHooks] Refreshed installed hook assets for ${host}`);
218
+ }
219
+ else if (status.needsRepair && status.installed) {
220
+ logger.warn(`[PermissionHooks] Hook assets still need repair for ${host}` +
221
+ (status.repairError ? `: ${status.repairError}` : ''));
222
+ }
223
+ hostResults.push(toStartupRepairHostResult(host, status));
224
+ }
225
+ catch (error) {
226
+ const message = error instanceof Error ? error.message : String(error);
227
+ logger.warn(`[PermissionHooks] Startup hook repair failed for ${host}: ${message}`);
228
+ hostResults.push({
229
+ host,
230
+ installed: false,
231
+ assetsPrepared: false,
232
+ assetsCurrent: false,
233
+ autoRepaired: false,
234
+ needsRepair: true,
235
+ repairError: message,
236
+ outcome: 'error',
237
+ });
238
+ }
239
+ }
240
+ const repairedCount = hostResults.filter((result) => result.outcome === 'repaired').length;
241
+ const needsRepairCount = hostResults.filter((result) => result.outcome === 'needs_repair' || result.outcome === 'error').length;
242
+ const completedAt = Date.now();
243
+ const summary = {
244
+ startedAt: startedAtIso,
245
+ completedAt: new Date(completedAt).toISOString(),
246
+ durationMs: completedAt - startedAt,
247
+ repairedCount,
248
+ needsRepairCount,
249
+ hostResults,
250
+ };
251
+ lastPermissionHookStartupRepairSummary = cloneStartupRepairSummary(summary);
252
+ logger.info(`[PermissionHooks] Startup hook asset audit completed in ${summary.durationMs}ms ` +
253
+ `(repaired=${repairedCount}, needsRepair=${needsRepairCount})`);
254
+ return summary;
255
+ }
256
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbkhvb2tTdGF0dXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvcGVybWlzc2lvbkhvb2tTdGF0dXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNsQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sRUFRTCwwQkFBMEIsRUFDMUIsZUFBZSxFQUNmLHNCQUFzQixFQUN0QiwyQkFBMkIsRUFDM0Isd0JBQXdCLEVBQ3hCLHdCQUF3QixFQUN4QixpQkFBaUIsRUFDakIsMEJBQTBCLEVBQzFCLHVCQUF1QixFQUN2Qix5QkFBeUIsR0FDMUIsTUFBTSwyQkFBMkIsQ0FBQztBQUVuQyxJQUFJLHNDQUFzQyxHQUE4QyxJQUFJLENBQUM7QUFFN0YsTUFBTSxVQUFVLHVCQUF1QixDQUFDLE9BQU8sR0FBRyxPQUFPLEVBQUUsRUFBRSxJQUFhO0lBQ3hFLElBQUksSUFBSSxFQUFFLENBQUM7UUFDVCxPQUFPLDBCQUEwQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsT0FBTyx1QkFBdUIsQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLDRCQUE0QixDQUFDLE9BQU8sR0FBRyxPQUFPLEVBQUUsRUFBRSxJQUFhO0lBQ25GLElBQUksSUFBSSxFQUFFLENBQUM7UUFDVCxPQUFPLDBCQUEwQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsT0FBTyx1QkFBdUIsQ0FBQyxNQUFNLDJCQUEyQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDN0UsQ0FBQztBQUVELFNBQVMsNEJBQTRCLENBQ25DLE1BQTRCLEVBQzVCLEtBQTJCO0lBRTNCLE9BQU8sT0FBTyxD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QUFNLENBQUMsT0FBTyxLQUFLLFVBQVUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMzRixNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUNyRCxNQUFNLENBQUMsT0FBTyxLQUFLLGNBQWMsSUFBSSxNQUFNLENBQUMsT0FBTyxLQUFLLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMxRSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDL0IsTUFBTSxPQUFPLEdBQXVDO1FBQ2xELFNBQVMsRUFBRSxZQUFZO1FBQ3ZCLFdBQVcsRUFBRSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxXQUFXLEVBQUU7UUFDaEQsVUFBVSxFQUFFLFdBQVcsR0FBRyxTQUFTO1FBQ25DLGFBQWE7UUFDYixnQkFBZ0I7UUFDaEIsV0FBVztLQUNaLENBQUM7SUFDRixzQ0FBc0MsR0FBRyx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM1RSxNQUFNLENBQUMsSUFBSSxDQUNULDJEQUEyRCxPQUFPLENBQUMsVUFBVSxLQUFLO1FBQ2xGLGFBQWEsYUFBYSxpQkFBaUIsZ0JBQWdCLEdBQUcsQ0FDL0QsQ0FBQztJQUNGLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBob21lZGlyIH0gZnJvbSAnbm9kZTpvcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5pbXBvcnQge1xuICB0eXBlIFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5LFxuICB0eXBlIFBlcm1pc3Npb25Ib29rSGVhbHRoU3VtbWFyeSxcbiAgdHlwZSBIb29rQXNzZXRBdWRpdFJlc3VsdCxcbiAgdHlwZSBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0LFxuICB0eXBlIFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnksXG4gIHR5cGUgUGVybWlzc2lvbkhvb2tTdGF0dXMsXG4gIHR5cGUgUmVjb25jaWxlUGVybWlzc2lvbkhvb2tPcHRpb25zLFxuICBBVVRPX1JFUEFJUkFCTEVfSE9PS19IT1NUUyxcbiAgYXVkaXRIb29rQXNzZXRzLFxuICBjb2xsZWN0SG9va01hcmtlclBhdGhzLFxuICBjb2xsZWN0SG9va01hcmtlclBhdGhzQXN5bmMsXG4gIGdldFByaW1hcnlIb29rU2NyaXB0UGF0aCxcbiAgaW5zdGFsbEhvb2tBc3NldHNGb3JIb3N0LFxuICBub3JtYWxpemVIb29rSG9zdCxcbiAgcmVhZEhvc3RTcGVjaWZpY0hvb2tTdGF0dXMsXG4gIHN1bW1hcml6ZU1hcmtlclN0YXR1c2VzLFxuICBzdXBwb3J0c01hbmFnZWRIb29rQXNzZXRzLFxufSBmcm9tICcuL3Blcm1pc3Npb25Ib29rU2hhcmVkLmpzJztcblxubGV0IGxhc3RQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5OiBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5IHwgbnVsbCA9IG51bGw7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQZXJtaXNzaW9uSG9va1N0YXR1cyhob21lRGlyID0gaG9tZWRpcigpLCBob3N0Pzogc3RyaW5nKTogUGVybWlzc2lvbkhvb2tTdGF0dXMge1xuICBpZiAoaG9zdCkge1xuICAgIHJldHVybiByZWFkSG9zdFNwZWNpZmljSG9va1N0YXR1cyhob21lRGlyLCBob3N0KTtcbiAgfVxuXG4gIHJldHVybiBzdW1tYXJpemVNYXJrZXJTdGF0dXNlcyhjb2xsZWN0SG9va01hcmtlclBhdGhzKGhvbWVEaXIpKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldFBlcm1pc3Npb25Ib29rU3RhdHVzQXN5bmMoaG9tZURpciA9IGhvbWVkaXIoKSwgaG9zdD86IHN0cmluZyk6IFByb21pc2U8UGVybWlzc2lvbkhvb2tTdGF0dXM+IHtcbiAgaWYgKGhvc3QpIHtcbiAgICByZXR1cm4gcmVhZEhvc3RTcGVjaWZpY0hvb2tTdGF0dXMoaG9tZURpciwgaG9zdCk7XG4gIH1cblxuICByZXR1cm4gc3VtbWFyaXplTWFya2VyU3RhdHVzZXMoYXdhaXQgY29sbGVjdEhvb2tNYXJrZXJQYXRoc0FzeW5jKGhvbWVEaXIpKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkQXR0ZW1wdEhvb2tBc3NldFJlcGFpcihcbiAgc3RhdHVzOiBQZXJtaXNzaW9uSG9va1N0YXR1cyxcbiAgYXVkaXQ6IEhvb2tBc3NldEF1ZGl0UmVzdWx0LFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIHN0YXR1cy5pbnN0YWxsZWRcbiAgICB8fCBzdGF0dXMuYXNzZXRzUHJlcGFyZWRcbiAgICB8fCBzdGF0dXMuc2NyaXB0UGF0aFxuICAgIHx8IGF1ZGl0LmFzc2V0c1ByZXBhcmVkXG4gICAgfHwgYXVkaXQuc3RhbGVBc3NldHMubGVuZ3RoID4gMCxcbiAgKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRGYWxsYmFja1Blcm1pc3Npb25Ib29rU3RhdHVzKFxuICBiYXNlU3RhdHVzOiBQZXJtaXNzaW9uSG9va1N0YXR1cyxcbiAgbm9ybWFsaXplZEhvc3Q6IHN0cmluZyxcbiAgaG9tZURpcjogc3RyaW5nLFxuKTogUGVybWlzc2lvbkhvb2tTdGF0dXMge1xuICByZXR1cm4ge1xuICAgIC4uLmJhc2VTdGF0dXMsXG4gICAgaG9zdDogYmFzZVN0YXR1cy5ob3N0ID8/IG5vcm1hbGl6ZWRIb3N0LFxuICAgIHNjcmlwdFBhdGg6IGJhc2VTdGF0dXMuc2NyaXB0UGF0aCA/PyBnZXRQcmltYXJ5SG9va1NjcmlwdFBhdGgobm9ybWFsaXplZEhvc3QsIGhvbWVEaXIpLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBhdWRpdEFuZE1heWJlUmVwYWlySG9va0Fzc2V0cyhcbiAgbm9ybWFsaXplZEhvc3Q6IHN0cmluZyxcbiAgaG9tZURpcjogc3RyaW5nLFxuICBzb3VyY2VTY3JpcHRQYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIGF1dG9SZXBhaXI6IGJvb2xlYW4sXG4gIGZhbGxiYWNrU3RhdHVzOiBQZXJtaXNzaW9uSG9va1N0YXR1cyxcbik6IFByb21pc2U8eyBhdWRpdDogSG9va0Fzc2V0QXVkaXRSZXN1bHQ7IGF1dG9SZXBhaXJlZDogYm9vbGVhbiB9PiB7XG4gIGxldCBhdWRpdCA9IGF3YWl0IGF1ZGl0SG9va0Fzc2V0cyhub3JtYWxpemVkSG9zdCwgaG9tZURpciwgc291cmNlU2NyaXB0UGF0aCk7XG4gIGxldCBhdXRvUmVwYWlyZWQgPSBmYWxzZTtcblxuICBpZiAoIWF1ZGl0LmFzc2V0c0N1cnJlbnQgJiYgYXV0b1JlcGFpciAmJiBzaG91bGRBdHRlbXB0SG9va0Fzc2V0UmVwYWlyKGZhbGxiYWNrU3RhdHVzLCBhdWRpdCkpIHtcbiAgICBhd2FpdCBpbnN0YWxsSG9va0Fzc2V0c0Zvckhvc3Qobm9ybWFsaXplZEhvc3QsIGhvbWVEaXIsIHNvdXJjZVNjcmlwdFBhdGgpO1xuICAgIGF1ZGl0ID0gYXdhaXQgYXVkaXRIb29rQXNzZXRzKG5vcm1hbGl6ZWRIb3N0LCBob21lRGlyLCBzb3VyY2VTY3JpcHRQYXRoKTtcbiAgICBhdXRvUmVwYWlyZWQgPSBhdWRpdC5hc3NldHNDdXJyZW50O1xuICB9XG5cbiAgcmV0dXJuIHsgYXVkaXQsIGF1dG9SZXBhaXJlZCB9O1xufVxuXG5mdW5jdGlvbiBidWlsZEhvb2tSZXBhaXJGYWlsdXJlU3RhdHVzKFxuICBmYWxsYmFja1N0YXR1czogUGVybWlzc2lvbkhvb2tTdGF0dXMsXG4gIGVycm9yOiB1bmtub3duLFxuKTogUGVybWlzc2lvbkhvb2tTdGF0dXMge1xuICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICBsb2dnZXIud2FybihgW1Blcm1pc3Npb25Ib29rc10gRmFpbGVkIHRvIHJlY29uY2lsZSBob29rIGFzc2V0cyBmb3IgJHtmYWxsYmFja1N0YXR1cy5ob3N0fTogJHttZXNzYWdlfWApO1xuXG4gIHJldHVybiB7XG4gICAgLi4uZmFsbGJhY2tTdGF0dXMsXG4gICAgYXNzZXRzQ3VycmVudDogZmFsc2UsXG4gICAgYXV0b1JlcGFpcmVkOiBmYWxzZSxcbiAgICBuZWVkc1JlcGFpcjogdHJ1ZSxcbiAgICByZXBhaXJFcnJvcjogbWVzc2FnZSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gdG9TdGFydHVwUmVwYWlyT3V0Y29tZShzdGF0dXM6IFBlcm1pc3Npb25Ib29rU3RhdHVzKTogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdFsnb3V0Y29tZSddIHtcbiAgaWYgKHN0YXR1cy5yZXBhaXJFcnJvcikgcmV0dXJuICdlcnJvcic7XG4gIGlmIChzdGF0dXMuYXV0b1JlcGFpcmVkKSByZXR1cm4gJ3JlcGFpcmVkJztcbiAgaWYgKHN0YXR1cy5uZWVkc1JlcGFpciAmJiAoc3RhdHVzLmluc3RhbGxlZCB8fCBzdGF0dXMuYXNzZXRzUHJlcGFyZWQpKSByZXR1cm4gJ25lZWRzX3JlcGFpcic7XG4gIGlmIChzdGF0dXMuYXNzZXRzQ3VycmVudCkgcmV0dXJuICdjdXJyZW50JztcbiAgcmV0dXJuICdub3RfaW5zdGFsbGVkJztcbn1cblxuZnVuY3Rpb24gdG9TdGFydHVwUmVwYWlySG9zdFJlc3VsdChcbiAgaG9zdDogc3RyaW5nLFxuICBzdGF0dXM6IFBlcm1pc3Npb25Ib29rU3RhdHVzLFxuKTogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdCB7XG4gIHJldHVybiB7XG4gICAgLi4uc3RhdHVzLFxuICAgIGhvc3QsXG4gICAgb3V0Y29tZTogdG9TdGFydHVwUmVwYWlyT3V0Y29tZShzdGF0dXMpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBjbG9uZVN0YXJ0dXBSZXBhaXJTdW1tYXJ5KFxuICBzdW1tYXJ5OiBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5IHwgbnVsbCxcbik6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgfCBudWxsIHtcbiAgaWYgKCFzdW1tYXJ5KSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHtcbiAgICAuLi5zdW1tYXJ5LFxuICAgIGhvc3RSZXN1bHRzOiBzdW1tYXJ5Lmhvc3RSZXN1bHRzLm1hcCgocmVzdWx0KSA9PiAoeyAuLi5yZXN1bHQgfSkpLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGFzdFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkoKTogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSB8IG51bGwge1xuICByZXR1cm4gY2xvbmVTdGFydHVwUmVwYWlyU3VtbWFyeShsYXN0UGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBfcmVzZXRQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5Rm9yVGVzdHMoKTogdm9pZCB7XG4gIGxhc3RQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJTdW1tYXJ5ID0gbnVsbDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlY29uY2lsZVBlcm1pc3Npb25Ib29rU3RhdHVzKFxuICBob3N0OiBzdHJpbmcsXG4gIG9wdGlvbnM6IFJlY29uY2lsZVBlcm1pc3Npb25Ib29rT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxQZXJtaXNzaW9uSG9va1N0YXR1cz4ge1xuICBjb25zdCBub3JtYWxpemVkSG9zdCA9IG5vcm1hbGl6ZUhvb2tIb3N0KGhvc3QpO1xuICBjb25zdCBob21lRGlyID0gb3B0aW9ucy5ob21lRGlyID8/IGhvbWVkaXIoKTtcbiAgY29uc3Qgc291cmNlU2NyaXB0UGF0aCA9IG9wdGlvbnMuc291cmNlU2NyaXB0UGF0aDtcbiAgY29uc3QgYXV0b1JlcGFpciA9IG9wdGlvbnMuYXV0b1JlcGFpciA/PyBmYWxzZTtcbiAgY29uc3QgYmFzZVN0YXR1cyA9IHJlYWRIb3N0U3BlY2lmaWNIb29rU3RhdHVzKGhvbWVEaXIsIG5vcm1hbGl6ZWRIb3N0KTtcblxuICBpZiAoIXN1cHBvcnRzTWFuYWdlZEhvb2tBc3NldHMobm9ybWFsaXplZEhvc3QpKSB7XG4gICAgcmV0dXJuIGJhc2VTdGF0dXM7XG4gIH1cblxuICBjb25zdCBmYWxsYmFja1N0YXR1cyA9IGJ1aWxkRmFsbGJhY2tQZXJtaXNzaW9uSG9va1N0YXR1cyhiYXNlU3RhdHVzLCBub3JtYWxpemVkSG9zdCwgaG9tZURpcik7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IGF1ZGl0LCBhdXRvUmVwYWlyZWQgfSA9IGF3YWl0IGF1ZGl0QW5kTWF5YmVSZXBhaXJIb29rQXNzZXRzKFxuICAgICAgbm9ybWFsaXplZEhvc3QsXG4gICAgICBob21lRGlyLFxuICAgICAgc291cmNlU2NyaXB0UGF0aCxcbiAgICAgIGF1dG9SZXBhaXIsXG4gICAgICBmYWxsYmFja1N0YXR1cyxcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZhbGxiYWNrU3RhdHVzLFxuICAgICAgYXNzZXRzUHJlcGFyZWQ6IGF1ZGl0LmFzc2V0c1ByZXBhcmVkLFxuICAgICAgYXNzZXRzQ3VycmVudDogYXVkaXQuYXNzZXRzQ3VycmVudCxcbiAgICAgIGF1dG9SZXBhaXJlZCxcbiAgICAgIG5lZWRzUmVwYWlyOiAhYXVkaXQuYXNzZXRzQ3VycmVudCxcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBidWlsZEhvb2tSZXBhaXJGYWlsdXJlU3RhdHVzKGZhbGxiYWNrU3RhdHVzLCBlcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5KGhvbWVEaXIgPSBob21lZGlyKCkpOiBQcm9taXNlPFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5PiB7XG4gIGNvbnN0IHN0YXR1c2VzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgQVVUT19SRVBBSVJBQkxFX0hPT0tfSE9TVFMubWFwKGFzeW5jIChob3N0KSA9PiAoe1xuICAgICAgaG9zdCxcbiAgICAgIHN0YXR1czogYXdhaXQgcmVjb25jaWxlUGVybWlzc2lvbkhvb2tTdGF0dXMoaG9zdCwgeyBob21lRGlyIH0pLFxuICAgIH0pKSxcbiAgKTtcblxuICBjb25zdCBpbnN0YWxsZWRIb3N0cyA9IHN0YXR1c2VzXG4gICAgLmZpbHRlcigoeyBzdGF0dXMgfSkgPT4gc3RhdHVzLmluc3RhbGxlZCB8fCBzdGF0dXMuYXNzZXRzUHJlcGFyZWQpXG4gICAgLm1hcCgoeyBob3N0IH0pID0+IGhvc3QpO1xuICBjb25zdCBjdXJyZW50SG9zdHMgPSBzdGF0dXNlc1xuICAgIC5maWx0ZXIoKHsgc3RhdHVzIH0pID0+IHN0YXR1cy5hc3NldHNDdXJyZW50KVxuICAgIC5tYXAoKHsgaG9zdCB9KSA9PiBob3N0KTtcbiAgY29uc3QgcmVwYWlyZWRIb3N0cyA9IHN0YXR1c2VzXG4gICAgLmZpbHRlcigoeyBzdGF0dXMgfSkgPT4gc3RhdHVzLmF1dG9SZXBhaXJlZClcbiAgICAubWFwKCh7IGhvc3QgfSkgPT4gaG9zdCk7XG4gIGNvbnN0IG5lZWRzUmVwYWlySG9zdHMgPSBzdGF0dXNlc1xuICAgIC5maWx0ZXIoKHsgc3RhdHVzIH0pID0+IHN0YXR1cy5uZWVkc1JlcGFpcilcbiAgICAubWFwKCh7IGhvc3QgfSkgPT4gaG9zdCk7XG5cbiAgcmV0dXJuIHtcbiAgICBpbnN0YWxsZWRIb3N0cyxcbiAgICBjdXJyZW50SG9zdHMsXG4gICAgcmVwYWlyZWRIb3N0cyxcbiAgICBuZWVkc1JlcGFpckhvc3RzLFxuICAgIGxhc3RTdGFydHVwUmVwYWlyOiBnZXRMYXN0UGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSgpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRIb29rSG9zdExhYmVsKGNvdW50OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7Y291bnR9IGhvb2sgaG9zdCR7Y291bnQgPT09IDEgPyAnJyA6ICdzJ31gO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRIb29rVmVyYihjb3VudDogbnVtYmVyLCBzaW5ndWxhcjogc3RyaW5nLCBwbHVyYWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBjb3VudCA9PT0gMSA/IHNpbmd1bGFyIDogcGx1cmFsO1xufVxuXG5mdW5jdGlvbiBidWlsZFBlcm1pc3Npb25Ib29rSGVhbHRoTWVzc2FnZShcbiAgc3VtbWFyeTogUGVybWlzc2lvbkhvb2tBdWRpdFN1bW1hcnksXG4gIGhhZEVycm9yczogYm9vbGVhbixcbiAgcmVwYWlyZWRDb3VudDogbnVtYmVyLFxuICBuZWVkc1JlcGFpckNvdW50OiBudW1iZXIsXG4pOiBzdHJpbmcge1xuICBpZiAoaGFkRXJyb3JzKSB7XG4gICAgaWYgKG5lZWRzUmVwYWlyQ291bnQgPiAwKSB7XG4gICAgICBjb25zdCBob3N0TGFiZWwgPSBmb3JtYXRIb29rSG9zdExhYmVsKG5lZWRzUmVwYWlyQ291bnQpO1xuICAgICAgY29uc3QgdmVyYiA9IGZvcm1hdEhvb2tWZXJiKG5lZWRzUmVwYWlyQ291bnQsICduZWVkcycsICduZWVkJyk7XG4gICAgICByZXR1cm4gYCR7aG9zdExhYmVsfSBzdGlsbCAke3ZlcmJ9IGF0dGVudGlvbiBhZnRlciBzdGFydHVwIHJlcGFpcmA7XG4gICAgfVxuXG4gICAgcmV0dXJuICdBIHN0YXJ0dXAgaG9vayByZXBhaXIgZmFpbGVkIGFuZCBuZWVkcyBhdHRlbnRpb24nO1xuICB9XG5cbiAgaWYgKG5lZWRzUmVwYWlyQ291bnQgPiAwKSB7XG4gICAgY29uc3QgaG9zdExhYmVsID0gZm9ybWF0SG9va0hvc3RMYWJlbChuZWVkc1JlcGFpckNvdW50KTtcbiAgICBjb25zdCB2ZXJiID0gZm9ybWF0SG9va1ZlcmIobmVlZHNSZXBhaXJDb3VudCwgJ25lZWRzJywgJ25lZWQnKTtcbiAgICByZXR1cm4gYCR7aG9zdExhYmVsfSBzdGlsbCAke3ZlcmJ9IHJlcGFpcmA7XG4gIH1cblxuICBpZiAocmVwYWlyZWRDb3VudCA+IDApIHtcbiAgICBjb25zdCBob3N0TGFiZWwgPSBmb3JtYXRIb29rSG9zdExhYmVsKHJlcGFpcmVkQ291bnQpO1xuICAgIHJldHVybiBgJHtob3N0TGFiZWx9IHJlcGFpcmVkIG9uIHN0YXJ0dXBgO1xuICB9XG5cbiAgaWYgKHN1bW1hcnkuY3VycmVudEhvc3RzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gJ01hbmFnZWQgaG9vayBhc3NldHMgYXJlIGN1cnJlbnQnO1xuICB9XG5cbiAgcmV0dXJuICdObyBtYW5hZ2VkIGhvb2sgYXNzZXRzIGN1cnJlbnRseSBpbnN0YWxsZWQnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3VtbWFyaXplUGVybWlzc2lvbkhvb2tIZWFsdGgoXG4gIHN1bW1hcnk6IFBlcm1pc3Npb25Ib29rQXVkaXRTdW1tYXJ5LFxuKTogUGVybWlzc2lvbkhvb2tIZWFsdGhTdW1tYXJ5IHtcbiAgY29uc3QgbGFzdFN0YXJ0dXBSZXBhaXIgPSBzdW1tYXJ5Lmxhc3RTdGFydHVwUmVwYWlyO1xuICBjb25zdCBoYWRFcnJvcnMgPSBCb29sZWFuKFxuICAgIGxhc3RTdGFydHVwUmVwYWlyPy5ob3N0UmVzdWx0cy5zb21lKChyZXN1bHQpID0+IHJlc3VsdC5vdXRjb21lID09PSAnZXJyb3InKSxcbiAgKTtcbiAgY29uc3QgbmVlZHNSZXBhaXJDb3VudCA9IGxhc3RTdGFydHVwUmVwYWlyPy5uZWVkc1JlcGFpckNvdW50ID8/IHN1bW1hcnkubmVlZHNSZXBhaXJIb3N0cy5sZW5ndGg7XG4gIGNvbnN0IHJlcGFpcmVkQ291bnQgPSBsYXN0U3RhcnR1cFJlcGFpcj8ucmVwYWlyZWRDb3VudCA/PyBzdW1tYXJ5LnJlcGFpcmVkSG9zdHMubGVuZ3RoO1xuICBjb25zdCBtZXNzYWdlID0gYnVpbGRQZXJtaXNzaW9uSG9va0hlYWx0aE1lc3NhZ2UoXG4gICAgc3VtbWFyeSxcbiAgICBoYWRFcnJvcnMsXG4gICAgcmVwYWlyZWRDb3VudCxcbiAgICBuZWVkc1JlcGFpckNvdW50LFxuICApO1xuXG4gIGlmIChoYWRFcnJvcnMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHJlcGFpcmVkQ291bnQsXG4gICAgICBuZWVkc1JlcGFpckNvdW50LFxuICAgICAgbGFzdENoZWNrZWRBdDogbGFzdFN0YXJ0dXBSZXBhaXI/LmNvbXBsZXRlZEF0LFxuICAgIH07XG4gIH1cblxuICBpZiAobmVlZHNSZXBhaXJDb3VudCA+IDApIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnd2FybmluZycsXG4gICAgICBtZXNzYWdlLFxuICAgICAgcmVwYWlyZWRDb3VudCxcbiAgICAgIG5lZWRzUmVwYWlyQ291bnQsXG4gICAgICBsYXN0Q2hlY2tlZEF0OiBsYXN0U3RhcnR1cFJlcGFpcj8uY29tcGxldGVkQXQsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXBhaXJlZENvdW50ID4gMCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdvaycsXG4gICAgICBtZXNzYWdlLFxuICAgICAgcmVwYWlyZWRDb3VudCxcbiAgICAgIG5lZWRzUmVwYWlyQ291bnQsXG4gICAgICBsYXN0Q2hlY2tlZEF0OiBsYXN0U3RhcnR1cFJlcGFpcj8uY29tcGxldGVkQXQsXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc3RhdHVzOiAnb2snLFxuICAgIG1lc3NhZ2UsXG4gICAgcmVwYWlyZWRDb3VudCxcbiAgICBuZWVkc1JlcGFpckNvdW50LFxuICAgIGxhc3RDaGVja2VkQXQ6IGxhc3RTdGFydHVwUmVwYWlyPy5jb21wbGV0ZWRBdCxcbiAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGFpclBlcm1pc3Npb25Ib29rc09uU3RhcnR1cChcbiAgaG9tZURpciA9IGhvbWVkaXIoKSxcbiAgc291cmNlU2NyaXB0UGF0aD86IHN0cmluZyxcbik6IFByb21pc2U8UGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeT4ge1xuICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICBjb25zdCBzdGFydGVkQXRJc28gPSBuZXcgRGF0ZShzdGFydGVkQXQpLnRvSVNPU3RyaW5nKCk7XG4gIGNvbnN0IGhvc3RSZXN1bHRzOiBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0W10gPSBbXTtcblxuICAvLyBQcm9jZXNzIHNlcXVlbnRpYWxseSBiZWNhdXNlIHNldmVyYWwgaG9zdHMgc2hhcmUgdGhlIHNhbWUgYnJpZGdlL2hlbHBlclxuICAvLyB0YXJnZXRzIHVuZGVyIH4vLmRvbGxob3VzZS9ob29rcywgYW5kIGNvbmN1cnJlbnQgd3JpdGVzIGFyZSBmbGFreSBvbiBXaW5kb3dzLlxuICBmb3IgKGNvbnN0IGhvc3Qgb2YgQVVUT19SRVBBSVJBQkxFX0hPT0tfSE9TVFMpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgcmVjb25jaWxlUGVybWlzc2lvbkhvb2tTdGF0dXMoaG9zdCwge1xuICAgICAgICBob21lRGlyLFxuICAgICAgICBhdXRvUmVwYWlyOiB0cnVlLFxuICAgICAgICBzb3VyY2VTY3JpcHRQYXRoLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChzdGF0dXMuYXV0b1JlcGFpcmVkKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbUGVybWlzc2lvbkhvb2tzXSBSZWZyZXNoZWQgaW5zdGFsbGVkIGhvb2sgYXNzZXRzIGZvciAke2hvc3R9YCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXR1cy5uZWVkc1JlcGFpciAmJiBzdGF0dXMuaW5zdGFsbGVkKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGBbUGVybWlzc2lvbkhvb2tzXSBIb29rIGFzc2V0cyBzdGlsbCBuZWVkIHJlcGFpciBmb3IgJHtob3N0fWAgK1xuICAgICAgICAgIChzdGF0dXMucmVwYWlyRXJyb3IgPyBgOiAke3N0YXR1cy5yZXBhaXJFcnJvcn1gIDogJycpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBob3N0UmVzdWx0cy5wdXNoKHRvU3RhcnR1cFJlcGFpckhvc3RSZXN1bHQoaG9zdCwgc3RhdHVzKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICBsb2dnZXIud2FybihgW1Blcm1pc3Npb25Ib29rc10gU3RhcnR1cCBob29rIHJlcGFpciBmYWlsZWQgZm9yICR7aG9zdH06ICR7bWVzc2FnZX1gKTtcbiAgICAgIGhvc3RSZXN1bHRzLnB1c2goe1xuICAgICAgICBob3N0LFxuICAgICAgICBpbnN0YWxsZWQ6IGZhbHNlLFxuICAgICAgICBhc3NldHNQcmVwYXJlZDogZmFsc2UsXG4gICAgICAgIGFzc2V0c0N1cnJlbnQ6IGZhbHNlLFxuICAgICAgICBhdXRvUmVwYWlyZWQ6IGZhbHNlLFxuICAgICAgICBuZWVkc1JlcGFpcjogdHJ1ZSxcbiAgICAgICAgcmVwYWlyRXJyb3I6IG1lc3NhZ2UsXG4gICAgICAgIG91dGNvbWU6ICdlcnJvcicsXG4gICAgICB9IHNhdGlzZmllcyBQZXJtaXNzaW9uSG9va1N0YXJ0dXBSZXBhaXJIb3N0UmVzdWx0KTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcmVwYWlyZWRDb3VudCA9IGhvc3RSZXN1bHRzLmZpbHRlcigocmVzdWx0KSA9PiByZXN1bHQub3V0Y29tZSA9PT0gJ3JlcGFpcmVkJykubGVuZ3RoO1xuICBjb25zdCBuZWVkc1JlcGFpckNvdW50ID0gaG9zdFJlc3VsdHMuZmlsdGVyKChyZXN1bHQpID0+XG4gICAgcmVzdWx0Lm91dGNvbWUgPT09ICduZWVkc19yZXBhaXInIHx8IHJlc3VsdC5vdXRjb21lID09PSAnZXJyb3InKS5sZW5ndGg7XG4gIGNvbnN0IGNvbXBsZXRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3Qgc3VtbWFyeTogUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSA9IHtcbiAgICBzdGFydGVkQXQ6IHN0YXJ0ZWRBdElzbyxcbiAgICBjb21wbGV0ZWRBdDogbmV3IERhdGUoY29tcGxldGVkQXQpLnRvSVNPU3RyaW5nKCksXG4gICAgZHVyYXRpb25NczogY29tcGxldGVkQXQgLSBzdGFydGVkQXQsXG4gICAgcmVwYWlyZWRDb3VudCxcbiAgICBuZWVkc1JlcGFpckNvdW50LFxuICAgIGhvc3RSZXN1bHRzLFxuICB9O1xuICBsYXN0UGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlyU3VtbWFyeSA9IGNsb25lU3RhcnR1cFJlcGFpclN1bW1hcnkoc3VtbWFyeSk7XG4gIGxvZ2dlci5pbmZvKFxuICAgIGBbUGVybWlzc2lvbkhvb2tzXSBTdGFydHVwIGhvb2sgYXNzZXQgYXVkaXQgY29tcGxldGVkIGluICR7c3VtbWFyeS5kdXJhdGlvbk1zfW1zIGAgK1xuICAgIGAocmVwYWlyZWQ9JHtyZXBhaXJlZENvdW50fSwgbmVlZHNSZXBhaXI9JHtuZWVkc1JlcGFpckNvdW50fSlgLFxuICApO1xuICByZXR1cm4gc3VtbWFyeTtcbn1cbiJdfQ==
@@ -1,74 +1,4 @@
1
- export interface PermissionHookMarker {
2
- host: string;
3
- scriptPath: string;
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
- host?: string;
15
- scriptPath?: string;
16
- settingsPath?: string;
17
- additionalPaths?: string[];
18
- }
19
- export interface InstallPermissionHookResult {
20
- supported: boolean;
21
- installed: boolean;
22
- configured: boolean;
23
- assetsPrepared?: boolean;
24
- host: string;
25
- scriptPath?: string;
26
- settingsPath?: string;
27
- additionalPaths?: string[];
28
- markerPath?: string;
29
- backupPath?: string;
30
- message: string;
31
- }
32
- export interface InstallPermissionHookOptions {
33
- homeDir?: string;
34
- sourceScriptPath?: string;
35
- now?: Date;
36
- }
37
- export declare function getPermissionHookScriptPath(homeDir?: string): string;
38
- export declare function getPermissionHookMarkerPath(homeDir?: string, host?: string): string;
39
- export declare function getClaudeHookSettingsPath(homeDir?: string): string;
40
- export declare function getVsCodeHookSettingsPath(homeDir?: string): string;
41
- export declare function getVsCodeUserSettingsPath(homeDir?: string): string;
42
- export declare function getGeminiHookSettingsPath(homeDir?: string): string;
43
- export declare function getCursorHookSettingsPath(homeDir?: string): string;
44
- export declare function getWindsurfHookSettingsPath(homeDir?: string): string;
45
- export declare function getCodexHookSettingsPath(homeDir?: string): string;
46
- export declare function getCodexConfigPath(homeDir?: string): string;
47
- export declare function getPermissionHookStatus(homeDir?: string, host?: string): PermissionHookStatus;
48
- export declare function getPermissionHookStatusAsync(homeDir?: string, host?: string): Promise<PermissionHookStatus>;
49
- export declare function ensureClaudePreToolUseHook(parsed: Record<string, unknown>, command: string): {
50
- changed: boolean;
51
- parsed: Record<string, unknown>;
52
- };
53
- export declare function ensureVsCodePreToolUseHook(parsed: Record<string, unknown>, command: string): {
54
- changed: boolean;
55
- parsed: Record<string, unknown>;
56
- };
57
- export declare function ensureGeminiBeforeToolHook(parsed: Record<string, unknown>, command: string): {
58
- changed: boolean;
59
- parsed: Record<string, unknown>;
60
- };
61
- export declare function ensureCodexPreToolUseHook(parsed: Record<string, unknown>, command: string): {
62
- changed: boolean;
63
- parsed: Record<string, unknown>;
64
- };
65
- export declare function ensureCursorPreToolUseHook(parsed: Record<string, unknown>, command: string): {
66
- changed: boolean;
67
- parsed: Record<string, unknown>;
68
- };
69
- export declare function ensureWindsurfHooks(parsed: Record<string, unknown>, command: string): {
70
- changed: boolean;
71
- parsed: Record<string, unknown>;
72
- };
73
- 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 PermissionHookHealthSummary, type PermissionHookMarker, type PermissionHookStartupRepairHostResult, type PermissionHookStartupRepairSummary, type PermissionHookStatus, type ReconcilePermissionHookOptions, detectIndent, getClaudeHookSettingsPath, getCodexConfigPath, getCodexHookSettingsPath, getCursorHookSettingsPath, getGeminiHookSettingsPath, getHookSourcePath, getHookWrapperBasename, getHookWrapperPath, getManagedHookAssets, getPermissionHookMarkerPath, getPermissionHookScriptPath, getPrimaryHookScriptPath, getVsCodeHookSettingsPath, getVsCodeUserSettingsPath, getWindsurfHookSettingsPath, installHookAssetsForHost, isMissingFileError, normalizeHookHost, 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';
74
4
  //# sourceMappingURL=permissionHooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permissionHooks.d.ts","sourceRoot":"","sources":["../../src/utils/permissionHooks.ts"],"names":[],"mappings":"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"}
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,2BAA2B,EAChC,KAAK,oBAAoB,EACzB,KAAK,qCAAqC,EAC1C,KAAK,kCAAkC,EACvC,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,YAAY,EACZ,yBAAyB,EACzB,kBAAkB,EAClB,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,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"}