@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,126 @@
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
+ 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
+ lastStartupRepair: PermissionHookStartupRepairSummary | null;
52
+ }
53
+ export interface PermissionHookHealthSummary {
54
+ status: 'ok' | 'warning' | 'error';
55
+ message: string;
56
+ repairedCount: number;
57
+ needsRepairCount: number;
58
+ lastCheckedAt?: string;
59
+ }
60
+ export interface PermissionHookStartupRepairHostResult extends PermissionHookStatus {
61
+ host: string;
62
+ outcome: 'current' | 'repaired' | 'needs_repair' | 'not_installed' | 'error';
63
+ }
64
+ export interface PermissionHookStartupRepairSummary {
65
+ startedAt: string;
66
+ completedAt: string;
67
+ durationMs: number;
68
+ repairedCount: number;
69
+ needsRepairCount: number;
70
+ hostResults: PermissionHookStartupRepairHostResult[];
71
+ }
72
+ export interface HookAssetDescriptor {
73
+ kind: 'bridge' | 'port-helper' | 'config-helper' | 'wrapper';
74
+ sourcePath: string;
75
+ targetPath: string;
76
+ }
77
+ export interface HookAssetAuditResult {
78
+ assetsPrepared: boolean;
79
+ assetsCurrent: boolean;
80
+ staleAssets: HookAssetDescriptor[];
81
+ }
82
+ export declare const MANAGED_HOOK_WRAPPER_BASENAMES: {
83
+ readonly vscode: "pretooluse-vscode.sh";
84
+ readonly cursor: "pretooluse-cursor.sh";
85
+ readonly windsurf: "pretooluse-windsurf.sh";
86
+ readonly 'gemini-cli': "pretooluse-gemini.sh";
87
+ readonly codex: "pretooluse-codex.sh";
88
+ };
89
+ export declare const WRAPPER_HOOK_HOSTS: Array<keyof typeof MANAGED_HOOK_WRAPPER_BASENAMES>;
90
+ export declare const AUTO_REPAIRABLE_HOOK_HOSTS: readonly ["claude-code", ...("cursor" | "vscode" | "windsurf" | "gemini-cli" | "codex")[]];
91
+ export declare function isMissingFileError(error: unknown): boolean;
92
+ export declare function detectIndent(raw: string): number | string;
93
+ export declare function getPermissionHookScriptPath(homeDir?: string): string;
94
+ export declare function normalizeHookHost(host: string): string;
95
+ export declare function readHostSpecificHookStatus(homeDir: string, host: string): PermissionHookStatus;
96
+ export declare function collectHookMarkerPaths(homeDir: string): Set<string>;
97
+ export declare function collectHookMarkerPathsAsync(homeDir: string): Promise<Set<string>>;
98
+ export declare function summarizeMarkerStatuses(markerPaths: Iterable<string>): PermissionHookStatus;
99
+ export declare function getHookWrapperBasename(host: string): string | null;
100
+ export declare function getHookWrapperPath(host: string, homeDir?: string): string | null;
101
+ export declare function getHookSourcePath(host: string): string;
102
+ export declare function supportsManagedHookAssets(host: string): boolean;
103
+ export declare function getPrimaryHookScriptPath(host: string, homeDir?: string): string;
104
+ export declare function getManagedHookAssets(host: string, homeDir?: string, sourceScriptPath?: string): HookAssetDescriptor[];
105
+ export declare function auditHookAssets(host: string, homeDir?: string, sourceScriptPath?: string): Promise<HookAssetAuditResult>;
106
+ export declare function getPermissionHookMarkerPath(homeDir?: string, host?: string): string;
107
+ export declare function getClaudeHookSettingsPath(homeDir?: string): string;
108
+ export declare function getVsCodeHookSettingsPath(homeDir?: string): string;
109
+ export declare function getVsCodeUserSettingsPath(homeDir?: string): string;
110
+ export declare function getGeminiHookSettingsPath(homeDir?: string): string;
111
+ export declare function getCursorHookSettingsPath(homeDir?: string): string;
112
+ export declare function getWindsurfHookSettingsPath(homeDir?: string): string;
113
+ export declare function getCodexHookSettingsPath(homeDir?: string): string;
114
+ export declare function getCodexConfigPath(homeDir?: string): string;
115
+ export declare function normalizeHooksRoot(parsed: Record<string, unknown>): Record<string, unknown[]>;
116
+ export declare function ensureCommandHook(parsed: Record<string, unknown>, eventName: string, command: string, matcher: string, extraHookFields?: Record<string, unknown>): {
117
+ changed: boolean;
118
+ parsed: Record<string, unknown>;
119
+ };
120
+ export declare function readOptionalUtf8(filePath: string, fallback: string): Promise<string>;
121
+ export declare function writeBackupIfPresent(filePath: string, raw: string): Promise<string | undefined>;
122
+ export declare function writeHookMarker(homeDir: string, marker: PermissionHookMarker): Promise<string>;
123
+ export declare function installHookAssetsForHost(client: string, homeDir: string, sourceScriptPath?: string): Promise<{
124
+ scriptPath: string;
125
+ }>;
126
+ //# sourceMappingURL=permissionHookShared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionHookShared.d.ts","sourceRoot":"","sources":["../../src/utils/permissionHookShared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,388 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { access, chmod, copyFile, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { homedir, platform } from 'node:os';
6
+ import { UnicodeValidator } from '../security/validators/unicodeValidator.js';
7
+ import { logger } from './logger.js';
8
+ export const MANAGED_HOOK_WRAPPER_BASENAMES = {
9
+ 'vscode': 'pretooluse-vscode.sh',
10
+ 'cursor': 'pretooluse-cursor.sh',
11
+ 'windsurf': 'pretooluse-windsurf.sh',
12
+ 'gemini-cli': 'pretooluse-gemini.sh',
13
+ 'codex': 'pretooluse-codex.sh',
14
+ };
15
+ export const WRAPPER_HOOK_HOSTS = Object.keys(MANAGED_HOOK_WRAPPER_BASENAMES);
16
+ export const AUTO_REPAIRABLE_HOOK_HOSTS = ['claude-code', ...WRAPPER_HOOK_HOSTS];
17
+ function repoRootFromModule() {
18
+ const currentFile = fileURLToPath(import.meta.url);
19
+ return dirname(dirname(dirname(currentFile)));
20
+ }
21
+ export function isMissingFileError(error) {
22
+ return Boolean(error
23
+ && typeof error === 'object'
24
+ && 'code' in error
25
+ && error.code === 'ENOENT');
26
+ }
27
+ export function detectIndent(raw) {
28
+ for (const line of raw.split('\n')) {
29
+ if (line.length === 0 || line.startsWith('{') || line.startsWith('}'))
30
+ continue;
31
+ if (line.startsWith('\t'))
32
+ return '\t';
33
+ if (line.startsWith(' ')) {
34
+ const spaces = line.length - line.trimStart().length;
35
+ if (spaces >= 2)
36
+ return spaces;
37
+ }
38
+ }
39
+ return 2;
40
+ }
41
+ export function getPermissionHookScriptPath(homeDir = homedir()) {
42
+ return join(homeDir, '.dollhouse', 'hooks', 'pretooluse-dollhouse.sh');
43
+ }
44
+ function getPermissionHookRunDir(homeDir = homedir()) {
45
+ return join(homeDir, '.dollhouse', 'run');
46
+ }
47
+ export function normalizeHookHost(host) {
48
+ return UnicodeValidator.normalize(host).normalizedContent.trim().toLowerCase();
49
+ }
50
+ function isHookMarkerFilename(entry) {
51
+ return entry.startsWith('hook-installed-') && entry.endsWith('.json');
52
+ }
53
+ export function readHostSpecificHookStatus(homeDir, host) {
54
+ const normalized = normalizeHookHost(host);
55
+ const status = readMarkerStatus(getPermissionHookMarkerPath(homeDir, normalized));
56
+ if (status.installed || status.assetsPrepared) {
57
+ return status;
58
+ }
59
+ if (normalized === 'claude-code') {
60
+ return readMarkerStatus(getPermissionHookMarkerPath(homeDir));
61
+ }
62
+ return { installed: false };
63
+ }
64
+ export function collectHookMarkerPaths(homeDir) {
65
+ const markerPaths = new Set([getPermissionHookMarkerPath(homeDir)]);
66
+ const runDir = getPermissionHookRunDir(homeDir);
67
+ try {
68
+ for (const entry of readdirSync(runDir)) {
69
+ if (isHookMarkerFilename(entry)) {
70
+ markerPaths.add(join(runDir, entry));
71
+ }
72
+ }
73
+ }
74
+ catch {
75
+ // No run dir yet — fall through to default false.
76
+ }
77
+ return markerPaths;
78
+ }
79
+ export async function collectHookMarkerPathsAsync(homeDir) {
80
+ const markerPaths = new Set([getPermissionHookMarkerPath(homeDir)]);
81
+ const runDir = getPermissionHookRunDir(homeDir);
82
+ try {
83
+ for (const entry of await readdir(runDir)) {
84
+ if (isHookMarkerFilename(entry)) {
85
+ markerPaths.add(join(runDir, entry));
86
+ }
87
+ }
88
+ }
89
+ catch {
90
+ // No run dir yet — fall through to default false.
91
+ }
92
+ return markerPaths;
93
+ }
94
+ export function summarizeMarkerStatuses(markerPaths) {
95
+ let fallback = { installed: false };
96
+ for (const markerPath of markerPaths) {
97
+ const status = readMarkerStatus(markerPath);
98
+ if (status.installed)
99
+ return status;
100
+ if (!fallback.assetsPrepared && status.assetsPrepared)
101
+ fallback = status;
102
+ }
103
+ return fallback;
104
+ }
105
+ export function getHookWrapperBasename(host) {
106
+ const normalizedHost = normalizeHookHost(host);
107
+ return MANAGED_HOOK_WRAPPER_BASENAMES[normalizedHost] ?? null;
108
+ }
109
+ export function getHookWrapperPath(host, homeDir = homedir()) {
110
+ const basename = getHookWrapperBasename(host);
111
+ return basename ? join(homeDir, '.dollhouse', 'hooks', basename) : null;
112
+ }
113
+ export function getHookSourcePath(host) {
114
+ const root = repoRootFromModule();
115
+ const basename = getHookWrapperBasename(host);
116
+ return basename ? join(root, 'scripts', basename) : join(root, 'scripts', 'pretooluse-dollhouse.sh');
117
+ }
118
+ export function supportsManagedHookAssets(host) {
119
+ const normalized = normalizeHookHost(host);
120
+ return normalized === 'claude-code' || getHookWrapperBasename(normalized) !== null;
121
+ }
122
+ export function getPrimaryHookScriptPath(host, homeDir = homedir()) {
123
+ return getHookWrapperPath(host, homeDir) ?? getPermissionHookScriptPath(homeDir);
124
+ }
125
+ export function getManagedHookAssets(host, homeDir = homedir(), sourceScriptPath) {
126
+ const normalized = normalizeHookHost(host);
127
+ const hooksDir = dirname(getPermissionHookScriptPath(homeDir));
128
+ const assets = [
129
+ {
130
+ kind: 'bridge',
131
+ sourcePath: sourceScriptPath ?? join(repoRootFromModule(), 'scripts', 'pretooluse-dollhouse.sh'),
132
+ targetPath: getPermissionHookScriptPath(homeDir),
133
+ },
134
+ {
135
+ kind: 'port-helper',
136
+ sourcePath: join(repoRootFromModule(), 'scripts', 'permission-port-discovery.sh'),
137
+ targetPath: join(hooksDir, 'permission-port-discovery.sh'),
138
+ },
139
+ {
140
+ kind: 'config-helper',
141
+ sourcePath: join(repoRootFromModule(), 'scripts', 'permission-hook-config.sh'),
142
+ targetPath: join(hooksDir, 'permission-hook-config.sh'),
143
+ },
144
+ ];
145
+ const wrapperTargetPath = getHookWrapperPath(normalized, homeDir);
146
+ if (wrapperTargetPath) {
147
+ assets.push({
148
+ kind: 'wrapper',
149
+ sourcePath: getHookSourcePath(normalized),
150
+ targetPath: wrapperTargetPath,
151
+ });
152
+ }
153
+ return assets;
154
+ }
155
+ async function readOptionalUtf8File(filePath) {
156
+ try {
157
+ return await readFile(filePath, 'utf-8');
158
+ }
159
+ catch (error) {
160
+ if (isMissingFileError(error)) {
161
+ return undefined;
162
+ }
163
+ throw error;
164
+ }
165
+ }
166
+ export async function auditHookAssets(host, homeDir = homedir(), sourceScriptPath) {
167
+ const assets = getManagedHookAssets(host, homeDir, sourceScriptPath);
168
+ const staleAssets = [];
169
+ let assetsPrepared = true;
170
+ for (const asset of assets) {
171
+ const sourceRaw = await readFile(asset.sourcePath, 'utf-8');
172
+ const targetRaw = await readOptionalUtf8File(asset.targetPath);
173
+ if (targetRaw === undefined) {
174
+ assetsPrepared = false;
175
+ staleAssets.push(asset);
176
+ continue;
177
+ }
178
+ if (targetRaw !== sourceRaw) {
179
+ staleAssets.push(asset);
180
+ }
181
+ }
182
+ return {
183
+ assetsPrepared,
184
+ assetsCurrent: staleAssets.length === 0,
185
+ staleAssets,
186
+ };
187
+ }
188
+ export function getPermissionHookMarkerPath(homeDir = homedir(), host) {
189
+ if (!host) {
190
+ return join(getPermissionHookRunDir(homeDir), 'hook-installed.json');
191
+ }
192
+ return join(getPermissionHookRunDir(homeDir), `hook-installed-${normalizeHookHost(host)}.json`);
193
+ }
194
+ export function getClaudeHookSettingsPath(homeDir = homedir()) {
195
+ return join(homeDir, '.claude', 'settings.json');
196
+ }
197
+ export function getVsCodeHookSettingsPath(homeDir = homedir()) {
198
+ return join(homeDir, '.copilot', 'hooks', 'dollhouse-permissions.json');
199
+ }
200
+ export function getVsCodeUserSettingsPath(homeDir = homedir()) {
201
+ const currentPlatform = platform();
202
+ if (currentPlatform === 'darwin') {
203
+ return join(homeDir, 'Library', 'Application Support', 'Code', 'User', 'settings.json');
204
+ }
205
+ if (currentPlatform === 'win32') {
206
+ const appData = process.env.APPDATA || join(homeDir, 'AppData', 'Roaming');
207
+ return join(appData, 'Code', 'User', 'settings.json');
208
+ }
209
+ return join(homeDir, '.config', 'Code', 'User', 'settings.json');
210
+ }
211
+ export function getGeminiHookSettingsPath(homeDir = homedir()) {
212
+ return join(homeDir, '.gemini', 'settings.json');
213
+ }
214
+ export function getCursorHookSettingsPath(homeDir = homedir()) {
215
+ return join(homeDir, '.cursor', 'hooks.json');
216
+ }
217
+ export function getWindsurfHookSettingsPath(homeDir = homedir()) {
218
+ return join(homeDir, '.codeium', 'windsurf', 'hooks.json');
219
+ }
220
+ export function getCodexHookSettingsPath(homeDir = homedir()) {
221
+ return join(homeDir, '.codex', 'hooks.json');
222
+ }
223
+ export function getCodexConfigPath(homeDir = homedir()) {
224
+ return join(homeDir, '.codex', 'config.toml');
225
+ }
226
+ function toPermissionHookStatus(raw) {
227
+ if (typeof raw.host !== 'string' ||
228
+ typeof raw.scriptPath !== 'string') {
229
+ return { installed: false };
230
+ }
231
+ const scriptReady = existsSync(raw.scriptPath);
232
+ const settingsReady = !raw.settingsPath || existsSync(raw.settingsPath);
233
+ const additionalPathsReady = !raw.additionalPaths || raw.additionalPaths.every((path) => existsSync(path));
234
+ const assetsPrepared = (raw.assetsPrepared ?? raw.configured ?? true) && scriptReady;
235
+ const configured = (raw.configured ?? true) && scriptReady && settingsReady && additionalPathsReady;
236
+ return {
237
+ installed: configured,
238
+ configured,
239
+ assetsPrepared,
240
+ host: raw.host,
241
+ scriptPath: raw.scriptPath,
242
+ settingsPath: raw.settingsPath,
243
+ additionalPaths: raw.additionalPaths,
244
+ };
245
+ }
246
+ function readMarkerStatus(markerPath) {
247
+ try {
248
+ const raw = readFileSync(markerPath, 'utf-8');
249
+ return toPermissionHookStatus(JSON.parse(raw));
250
+ }
251
+ catch (error) {
252
+ if (!isMissingFileError(error)) {
253
+ logger.warn(`[Permissions] Failed to read hook marker at ${markerPath}: ${String(error)}`);
254
+ }
255
+ return { installed: false };
256
+ }
257
+ }
258
+ export function normalizeHooksRoot(parsed) {
259
+ const hooksValue = parsed.hooks;
260
+ if (!hooksValue || typeof hooksValue !== 'object' || Array.isArray(hooksValue)) {
261
+ parsed.hooks = {};
262
+ }
263
+ return parsed.hooks;
264
+ }
265
+ export function ensureCommandHook(parsed, eventName, command, matcher, extraHookFields = {}) {
266
+ const hooksRoot = normalizeHooksRoot(parsed);
267
+ const existingEntries = Array.isArray(hooksRoot[eventName])
268
+ ? hooksRoot[eventName].filter((entry) => typeof entry === 'object' && entry !== null)
269
+ : [];
270
+ hooksRoot[eventName] = existingEntries;
271
+ const commandExists = existingEntries.some((entry) => {
272
+ const hooks = Array.isArray(entry?.hooks) ? entry.hooks : [];
273
+ return hooks.some((hook) => hook?.type === 'command' && hook?.command === command);
274
+ });
275
+ if (commandExists) {
276
+ return { changed: false, parsed };
277
+ }
278
+ const wildcardEntry = existingEntries.find((entry) => (entry?.matcher === matcher || entry?.matcher === undefined) && Array.isArray(entry?.hooks));
279
+ if (wildcardEntry) {
280
+ const hooks = wildcardEntry.hooks;
281
+ hooks.push({
282
+ type: 'command',
283
+ command,
284
+ ...extraHookFields,
285
+ });
286
+ }
287
+ else {
288
+ existingEntries.push({
289
+ matcher,
290
+ hooks: [
291
+ {
292
+ type: 'command',
293
+ command,
294
+ ...extraHookFields,
295
+ },
296
+ ],
297
+ });
298
+ }
299
+ return { changed: true, parsed };
300
+ }
301
+ async function copyHookAsset(sourcePath, targetPath) {
302
+ await mkdir(dirname(targetPath), { recursive: true });
303
+ const sourceRaw = await readFile(sourcePath, 'utf-8');
304
+ let targetRaw;
305
+ try {
306
+ targetRaw = await readFile(targetPath, 'utf-8');
307
+ }
308
+ catch (error) {
309
+ if (!isMissingFileError(error)) {
310
+ throw error;
311
+ }
312
+ }
313
+ const changed = targetRaw === undefined || sourceRaw !== targetRaw;
314
+ if (changed) {
315
+ await copyFile(sourcePath, targetPath);
316
+ }
317
+ else {
318
+ await access(targetPath);
319
+ }
320
+ await chmod(targetPath, 0o755);
321
+ return changed;
322
+ }
323
+ export async function readOptionalUtf8(filePath, fallback) {
324
+ try {
325
+ return await readFile(filePath, 'utf-8');
326
+ }
327
+ catch (error) {
328
+ if (isMissingFileError(error)) {
329
+ return fallback;
330
+ }
331
+ throw error;
332
+ }
333
+ }
334
+ export async function writeBackupIfPresent(filePath, raw) {
335
+ if (!existsSync(filePath)) {
336
+ return undefined;
337
+ }
338
+ const backupPath = `${filePath}.dollhouse.bak`;
339
+ await writeFile(backupPath, raw, 'utf-8');
340
+ return backupPath;
341
+ }
342
+ export async function writeHookMarker(homeDir, marker) {
343
+ const markerPath = getPermissionHookMarkerPath(homeDir, marker.host);
344
+ await mkdir(dirname(markerPath), { recursive: true });
345
+ await writeFile(markerPath, JSON.stringify(marker, null, 2) + '\n', 'utf-8');
346
+ return markerPath;
347
+ }
348
+ export async function installHookAssetsForHost(client, homeDir, sourceScriptPath) {
349
+ const normalizedClient = normalizeHookHost(client);
350
+ const hooksDir = dirname(getPermissionHookScriptPath(homeDir));
351
+ const sharedTargetPath = getPermissionHookScriptPath(homeDir);
352
+ const sharedSourcePath = sourceScriptPath ?? join(repoRootFromModule(), 'scripts', 'pretooluse-dollhouse.sh');
353
+ const portHelperSourcePath = join(repoRootFromModule(), 'scripts', 'permission-port-discovery.sh');
354
+ const portHelperTargetPath = join(hooksDir, 'permission-port-discovery.sh');
355
+ const configHelperSourcePath = join(repoRootFromModule(), 'scripts', 'permission-hook-config.sh');
356
+ const configHelperTargetPath = join(hooksDir, 'permission-hook-config.sh');
357
+ const sharedStat = statSync(sharedSourcePath);
358
+ if (!sharedStat.isFile()) {
359
+ logger.warn(`[PermissionHooks] Shared hook bridge missing for ${normalizedClient}: ${sharedSourcePath}`);
360
+ throw new Error(`Permission hook source script not found: ${sharedSourcePath}`);
361
+ }
362
+ await copyHookAsset(sharedSourcePath, sharedTargetPath);
363
+ const portHelperStat = statSync(portHelperSourcePath);
364
+ if (!portHelperStat.isFile()) {
365
+ logger.warn(`[PermissionHooks] Port discovery helper missing for ${normalizedClient}: ${portHelperSourcePath}`);
366
+ throw new Error(`Permission hook helper script not found: ${portHelperSourcePath}`);
367
+ }
368
+ await copyHookAsset(portHelperSourcePath, portHelperTargetPath);
369
+ const configHelperStat = statSync(configHelperSourcePath);
370
+ if (!configHelperStat.isFile()) {
371
+ logger.warn(`[PermissionHooks] Config helper missing for ${normalizedClient}: ${configHelperSourcePath}`);
372
+ throw new Error(`Permission hook config helper not found: ${configHelperSourcePath}`);
373
+ }
374
+ await copyHookAsset(configHelperSourcePath, configHelperTargetPath);
375
+ const wrapperTargetPath = getHookWrapperPath(normalizedClient, homeDir);
376
+ if (!wrapperTargetPath) {
377
+ return { scriptPath: sharedTargetPath };
378
+ }
379
+ const wrapperSourcePath = getHookSourcePath(normalizedClient);
380
+ const wrapperStat = statSync(wrapperSourcePath);
381
+ if (!wrapperStat.isFile()) {
382
+ logger.warn(`[PermissionHooks] Wrapper hook script missing for ${normalizedClient}: ${wrapperSourcePath}`);
383
+ throw new Error(`Permission hook wrapper script not found: ${wrapperSourcePath}`);
384
+ }
385
+ await copyHookAsset(wrapperSourcePath, wrapperTargetPath);
386
+ return { scriptPath: wrapperTargetPath };
387
+ }
388
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbkhvb2tTaGFyZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvcGVybWlzc2lvbkhvb2tTaGFyZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEcsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDMUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM1QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBOEZyQyxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRztJQUM1QyxRQUFRLEVBQUUsc0JBQXNCO0lBQ2hDLFFBQVEsRUFBRSxzQkFBc0I7SUFDaEMsVUFBVSxFQUFFLHdCQUF3QjtJQUNwQyxZQUFZLEVBQUUsc0JBQXNCO0lBQ3BDLE9BQU8sRUFBRSxxQkFBcUI7Q0FDdEIsQ0FBQztBQUVYLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQXVELENBQUM7QUFFcEksTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxhQUFhLEVBQUUsR0FBRyxrQkFBa0IsQ0FBVSxDQUFDO0FBRTFGLFNBQVMsa0JBQWtCO0lBQ3pCLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMs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QixFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDMUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDO0FBQzNDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMsIHJlYWRkaXJTeW5jLCBzdGF0U3luYyB9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHsgYWNjZXNzLCBjaG1vZCwgY29weUZpbGUsIG1rZGlyLCByZWFkRmlsZSwgcmVhZGRpciwgd3JpdGVGaWxlIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICdub2RlOnVybCc7XG5pbXBvcnQgeyBob21lZGlyLCBwbGF0Zm9ybSB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgVW5pY29kZVZhbGlkYXRvciB9IGZyb20gJy4uL3NlY3VyaXR5L3ZhbGlkYXRvcnMvdW5pY29kZVZhbGlkYXRvci5qcyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkhvb2tNYXJrZXIge1xuICBob3N0OiBzdHJpbmc7XG4gIHNjcmlwdFBhdGg6IHN0cmluZztcbiAgc2V0dGluZ3NQYXRoPzogc3RyaW5nO1xuICBhZGRpdGlvbmFsUGF0aHM/OiBzdHJpbmdbXTtcbiAgY29uZmlndXJlZD86IGJvb2xlYW47XG4gIGFzc2V0c1ByZXBhcmVkPzogYm9vbGVhbjtcbiAgaW5zdGFsbGVkQXQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIGluc3RhbGxlZDogYm9vbGVhbjtcbiAgY29uZmlndXJlZD86IGJvb2xlYW47XG4gIGFzc2V0c1ByZXBhcmVkPzogYm9vbGVhbjtcbiAgYXNzZXRzQ3VycmVudD86IGJvb2xlYW47XG4gIGF1dG9SZXBhaXJlZD86IGJvb2xlYW47XG4gIG5lZWRzUmVwYWlyPzogYm9vbGVhbjtcbiAgcmVwYWlyRXJyb3I/OiBzdHJpbmc7XG4gIGhvc3Q/OiBzdHJpbmc7XG4gIHNjcmlwdFBhdGg/OiBzdHJpbmc7XG4gIHNldHRpbmdzUGF0aD86IHN0cmluZztcbiAgYWRkaXRpb25hbFBhdGhzPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5zdGFsbFBlcm1pc3Npb25Ib29rUmVzdWx0IHtcbiAgc3VwcG9ydGVkOiBib29sZWFuO1xuICBpbnN0YWxsZWQ6IGJvb2xlYW47XG4gIGNvbmZpZ3VyZWQ6IGJvb2xlYW47XG4gIGFzc2V0c1ByZXBhcmVkPzogYm9vbGVhbjtcbiAgaG9zdDogc3RyaW5nO1xuICBzY3JpcHRQYXRoPzogc3RyaW5nO1xuICBzZXR0aW5nc1BhdGg/OiBzdHJpbmc7XG4gIGFkZGl0aW9uYWxQYXRocz86IHN0cmluZ1tdO1xuICBtYXJrZXJQYXRoPzogc3RyaW5nO1xuICBiYWNrdXBQYXRoPzogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5zdGFsbFBlcm1pc3Npb25Ib29rT3B0aW9ucyB7XG4gIGhvbWVEaXI/OiBzdHJpbmc7XG4gIHNvdXJjZVNjcmlwdFBhdGg/OiBzdHJpbmc7XG4gIG5vdz86IERhdGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb25jaWxlUGVybWlzc2lvbkhvb2tPcHRpb25zIHtcbiAgaG9tZURpcj86IHN0cmluZztcbiAgc291cmNlU2NyaXB0UGF0aD86IHN0cmluZztcbiAgYXV0b1JlcGFpcj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkhvb2tBdWRpdFN1bW1hcnkge1xuICBpbnN0YWxsZWRIb3N0czogc3RyaW5nW107XG4gIGN1cnJlbnRIb3N0czogc3RyaW5nW107XG4gIHJlcGFpcmVkSG9zdHM6IHN0cmluZ1tdO1xuICBuZWVkc1JlcGFpckhvc3RzOiBzdHJpbmdbXTtcbiAgbGFzdFN0YXJ0dXBSZXBhaXI6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkgfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25Ib29rSGVhbHRoU3VtbWFyeSB7XG4gIHN0YXR1czogJ29rJyB8ICd3YXJuaW5nJyB8ICdlcnJvcic7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgcmVwYWlyZWRDb3VudDogbnVtYmVyO1xuICBuZWVkc1JlcGFpckNvdW50OiBudW1iZXI7XG4gIGxhc3RDaGVja2VkQXQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVybWlzc2lvbkhvb2tTdGFydHVwUmVwYWlySG9zdFJlc3VsdCBleHRlbmRzIFBlcm1pc3Npb25Ib29rU3RhdHVzIHtcbiAgaG9zdDogc3RyaW5nO1xuICBvdXRjb21lOiAnY3VycmVudCcgfCAncmVwYWlyZWQnIHwgJ25lZWRzX3JlcGFpcicgfCAnbm90X2luc3RhbGxlZCcgfCAnZXJyb3InO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpclN1bW1hcnkge1xuICBzdGFydGVkQXQ6IHN0cmluZztcbiAgY29tcGxldGVkQXQ6IHN0cmluZztcbiAgZHVyYXRpb25NczogbnVtYmVyO1xuICByZXBhaXJlZENvdW50OiBudW1iZXI7XG4gIG5lZWRzUmVwYWlyQ291bnQ6IG51bWJlcjtcbiAgaG9zdFJlc3VsdHM6IFBlcm1pc3Npb25Ib29rU3RhcnR1cFJlcGFpckhvc3RSZXN1bHRbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIb29rQXNzZXREZXNjcmlwdG9yIHtcbiAga2luZDogJ2JyaWRnZScgfCAncG9ydC1oZWxwZXInIHwgJ2NvbmZpZy1oZWxwZXInIHwgJ3dyYXBwZXInO1xuICBzb3VyY2VQYXRoOiBzdHJpbmc7XG4gIHRhcmdldFBhdGg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIb29rQXNzZXRBdWRpdFJlc3VsdCB7XG4gIGFzc2V0c1ByZXBhcmVkOiBib29sZWFuO1xuICBhc3NldHNDdXJyZW50OiBib29sZWFuO1xuICBzdGFsZUFzc2V0czogSG9va0Fzc2V0RGVzY3JpcHRvcltdO1xufVxuXG5leHBvcnQgY29uc3QgTUFOQUdFRF9IT09LX1dSQVBQRVJfQkFTRU5BTUVTID0ge1xuICAndnNjb2RlJzogJ3ByZXRvb2x1c2UtdnNjb2RlLnNoJyxcbiAgJ2N1cnNvcic6ICdwcmV0b29sdXNlLWN1cnNvci5zaCcsXG4gICd3aW5kc3VyZic6ICdwcmV0b29sdXNlLXdpbmRzdXJmLnNoJyxcbiAgJ2dlbWluaS1jbGknOiAncHJldG9vbHVzZS1nZW1pbmkuc2gnLFxuICAnY29kZXgnOiAncHJldG9vbHVzZS1jb2RleC5zaCcsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgV1JBUFBFUl9IT09LX0hPU1RTID0gT2JqZWN0LmtleXMoTUFOQUdFRF9IT09LX1dSQVBQRVJfQkFTRU5BTUVTKSBhcyBBcnJheTxrZXlvZiB0eXBlb2YgTUFOQUdFRF9IT09LX1dSQVBQRVJfQkFTRU5BTUVTPjtcblxuZXhwb3J0IGNvbnN0IEFVVE9fUkVQQUlSQUJMRV9IT09LX0hPU1RTID0gWydjbGF1ZGUtY29kZScsIC4uLldSQVBQRVJfSE9PS19IT1NUU10gYXMgY29uc3Q7XG5cbmZ1bmN0aW9uIHJlcG9Sb290RnJvbU1vZHVsZSgpOiBzdHJpbmcge1xuICBjb25zdCBjdXJyZW50RmlsZSA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKTtcbiAgcmV0dXJuIGRpcm5hbWUoZGlybmFtZShkaXJuYW1lKGN1cnJlbnRGaWxlKSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNaXNzaW5nRmlsZUVycm9yKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIGVycm9yXG4gICAgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0J1xuICAgICYmICdjb2RlJyBpbiBlcnJvclxuICAgICYmIChlcnJvciBhcyB7IGNvZGU/OiBzdHJpbmcgfSkuY29kZSA9PT0gJ0VOT0VOVCcsXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RJbmRlbnQocmF3OiBzdHJpbmcpOiBudW1iZXIgfCBzdHJpbmcge1xuICBmb3IgKGNvbnN0IGxpbmUgb2YgcmF3LnNwbGl0KCdcXG4nKSkge1xuICAgIGlmIChsaW5lLmxlbmd0aCA9PT0gMCB8fCBsaW5lLnN0YXJ0c1dpdGgoJ3snKSB8fCBsaW5lLnN0YXJ0c1dpdGgoJ30nKSkgY29udGludWU7XG4gICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnXFx0JykpIHJldHVybiAnXFx0JztcbiAgICBpZiAobGluZS5zdGFydHNXaXRoKCcgJykpIHtcbiAgICAgIGNvbnN0IHNwYWNlcyA9IGxpbmUubGVuZ3RoIC0gbGluZS50cmltU3RhcnQoKS5sZW5ndGg7XG4gICAgICBpZiAoc3BhY2VzID49IDIpIHJldHVybiBzcGFjZXM7XG4gICAgfVxuICB9XG4gIHJldHVybiAyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGVybWlzc2lvbkhvb2tTY3JpcHRQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmRvbGxob3VzZScsICdob29rcycsICdwcmV0b29sdXNlLWRvbGxob3VzZS5zaCcpO1xufVxuXG5mdW5jdGlvbiBnZXRQZXJtaXNzaW9uSG9va1J1bkRpcihob21lRGlyID0gaG9tZWRpcigpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oaG9tZURpciwgJy5kb2xsaG91c2UnLCAncnVuJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVIb29rSG9zdChob3N0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUoaG9zdCkubm9ybWFsaXplZENvbnRlbnQudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIGlzSG9va01hcmtlckZpbGVuYW1lKGVudHJ5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGVudHJ5LnN0YXJ0c1dpdGgoJ2hvb2staW5zdGFsbGVkLScpICYmIGVudHJ5LmVuZHNXaXRoKCcuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVhZEhvc3RTcGVjaWZpY0hvb2tTdGF0dXMoaG9tZURpcjogc3RyaW5nLCBob3N0OiBzdHJpbmcpOiBQZXJtaXNzaW9uSG9va1N0YXR1cyB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVIb29rSG9zdChob3N0KTtcbiAgY29uc3Qgc3RhdHVzID0gcmVhZE1hcmtlclN0YXR1cyhnZXRQZXJtaXNzaW9uSG9va01hcmtlclBhdGgoaG9tZURpciwgbm9ybWFsaXplZCkpO1xuICBpZiAoc3RhdHVzLmluc3RhbGxlZCB8fCBzdGF0dXMuYXNzZXRzUHJlcGFyZWQpIHtcbiAgICByZXR1cm4gc3RhdHVzO1xuICB9XG4gIGlmIChub3JtYWxpemVkID09PSAnY2xhdWRlLWNvZGUnKSB7XG4gICAgcmV0dXJuIHJlYWRNYXJrZXJTdGF0dXMoZ2V0UGVybWlzc2lvbkhvb2tNYXJrZXJQYXRoKGhvbWVEaXIpKTtcbiAgfVxuICByZXR1cm4geyBpbnN0YWxsZWQ6IGZhbHNlIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2xsZWN0SG9va01hcmtlclBhdGhzKGhvbWVEaXI6IHN0cmluZyk6IFNldDxzdHJpbmc+IHtcbiAgY29uc3QgbWFya2VyUGF0aHMgPSBuZXcgU2V0PHN0cmluZz4oW2dldFBlcm1pc3Npb25Ib29rTWFya2VyUGF0aChob21lRGlyKV0pO1xuICBjb25zdCBydW5EaXIgPSBnZXRQZXJtaXNzaW9uSG9va1J1bkRpcihob21lRGlyKTtcbiAgdHJ5IHtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKHJ1bkRpcikpIHtcbiAgICAgIGlmIChpc0hvb2tNYXJrZXJGaWxlbmFtZShlbnRyeSkpIHtcbiAgICAgICAgbWFya2VyUGF0aHMuYWRkKGpvaW4ocnVuRGlyLCBlbnRyeSkpO1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCB7XG4gICAgLy8gTm8gcnVuIGRpciB5ZXQg4oCUIGZhbGwgdGhyb3VnaCB0byBkZWZhdWx0IGZhbHNlLlxuICB9XG4gIHJldHVybiBtYXJrZXJQYXRocztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbGxlY3RIb29rTWFya2VyUGF0aHNBc3luYyhob21lRGlyOiBzdHJpbmcpOiBQcm9taXNlPFNldDxzdHJpbmc+PiB7XG4gIGNvbnN0IG1hcmtlclBhdGhzID0gbmV3IFNldDxzdHJpbmc+KFtnZXRQZXJtaXNzaW9uSG9va01hcmtlclBhdGgoaG9tZURpcildKTtcbiAgY29uc3QgcnVuRGlyID0gZ2V0UGVybWlzc2lvbkhvb2tSdW5EaXIoaG9tZURpcik7XG4gIHRyeSB7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBhd2FpdCByZWFkZGlyKHJ1bkRpcikpIHtcbiAgICAgIGlmIChpc0hvb2tNYXJrZXJGaWxlbmFtZShlbnRyeSkpIHtcbiAgICAgICAgbWFya2VyUGF0aHMuYWRkKGpvaW4ocnVuRGlyLCBlbnRyeSkpO1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCB7XG4gICAgLy8gTm8gcnVuIGRpciB5ZXQg4oCUIGZhbGwgdGhyb3VnaCB0byBkZWZhdWx0IGZhbHNlLlxuICB9XG4gIHJldHVybiBtYXJrZXJQYXRocztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1bW1hcml6ZU1hcmtlclN0YXR1c2VzKG1hcmtlclBhdGhzOiBJdGVyYWJsZTxzdHJpbmc+KTogUGVybWlzc2lvbkhvb2tTdGF0dXMge1xuICBsZXQgZmFsbGJhY2s6IFBlcm1pc3Npb25Ib29rU3RhdHVzID0geyBpbnN0YWxsZWQ6IGZhbHNlIH07XG4gIGZvciAoY29uc3QgbWFya2VyUGF0aCBvZiBtYXJrZXJQYXRocykge1xuICAgIGNvbnN0IHN0YXR1cyA9IHJlYWRNYXJrZXJTdGF0dXMobWFya2VyUGF0aCk7XG4gICAgaWYgKHN0YXR1cy5pbnN0YWxsZWQpIHJldHVybiBzdGF0dXM7XG4gICAgaWYgKCFmYWxsYmFjay5hc3NldHNQcmVwYXJlZCAmJiBzdGF0dXMuYXNzZXRzUHJlcGFyZWQpIGZhbGxiYWNrID0gc3RhdHVzO1xuICB9XG4gIHJldHVybiBmYWxsYmFjaztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tXcmFwcGVyQmFzZW5hbWUoaG9zdDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRIb3N0ID0gbm9ybWFsaXplSG9va0hvc3QoaG9zdCk7XG4gIHJldHVybiBNQU5BR0VEX0hPT0tfV1JBUFBFUl9CQVNFTkFNRVNbbm9ybWFsaXplZEhvc3QgYXMga2V5b2YgdHlwZW9mIE1BTkFHRURfSE9PS19XUkFQUEVSX0JBU0VOQU1FU10gPz8gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tXcmFwcGVyUGF0aChob3N0OiBzdHJpbmcsIGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgYmFzZW5hbWUgPSBnZXRIb29rV3JhcHBlckJhc2VuYW1lKGhvc3QpO1xuICByZXR1cm4gYmFzZW5hbWUgPyBqb2luKGhvbWVEaXIsICcuZG9sbGhvdXNlJywgJ2hvb2tzJywgYmFzZW5hbWUpIDogbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tTb3VyY2VQYXRoKGhvc3Q6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJvb3QgPSByZXBvUm9vdEZyb21Nb2R1bGUoKTtcbiAgY29uc3QgYmFzZW5hbWUgPSBnZXRIb29rV3JhcHBlckJhc2VuYW1lKGhvc3QpO1xuICByZXR1cm4gYmFzZW5hbWUgPyBqb2luKHJvb3QsICdzY3JpcHRzJywgYmFzZW5hbWUpIDogam9pbihyb290LCAnc2NyaXB0cycsICdwcmV0b29sdXNlLWRvbGxob3VzZS5zaCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3VwcG9ydHNNYW5hZ2VkSG9va0Fzc2V0cyhob3N0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZUhvb2tIb3N0KGhvc3QpO1xuICByZXR1cm4gbm9ybWFsaXplZCA9PT0gJ2NsYXVkZS1jb2RlJyB8fCBnZXRIb29rV3JhcHBlckJhc2VuYW1lKG5vcm1hbGl6ZWQpICE9PSBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJpbWFyeUhvb2tTY3JpcHRQYXRoKGhvc3Q6IHN0cmluZywgaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIHJldHVybiBnZXRIb29rV3JhcHBlclBhdGgoaG9zdCwgaG9tZURpcikgPz8gZ2V0UGVybWlzc2lvbkhvb2tTY3JpcHRQYXRoKGhvbWVEaXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFuYWdlZEhvb2tBc3NldHMoXG4gIGhvc3Q6IHN0cmluZyxcbiAgaG9tZURpciA9IGhvbWVkaXIoKSxcbiAgc291cmNlU2NyaXB0UGF0aD86IHN0cmluZyxcbik6IEhvb2tBc3NldERlc2NyaXB0b3JbXSB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVIb29rSG9zdChob3N0KTtcbiAgY29uc3QgaG9va3NEaXIgPSBkaXJuYW1lKGdldFBlcm1pc3Npb25Ib29rU2NyaXB0UGF0aChob21lRGlyKSk7XG4gIGNvbnN0IGFzc2V0czogSG9va0Fzc2V0RGVzY3JpcHRvcltdID0gW1xuICAgIHtcbiAgICAgIGtpbmQ6ICdicmlkZ2UnLFxuICAgICAgc291cmNlUGF0aDogc291cmNlU2NyaXB0UGF0aCA/PyBqb2luKHJlcG9Sb290RnJvbU1vZHVsZSgpLCAnc2NyaXB0cycsICdwcmV0b29sdXNlLWRvbGxob3VzZS5zaCcpLFxuICAgICAgdGFyZ2V0UGF0aDogZ2V0UGVybWlzc2lvbkhvb2tTY3JpcHRQYXRoKGhvbWVEaXIpLFxuICAgIH0sXG4gICAge1xuICAgICAga2luZDogJ3BvcnQtaGVscGVyJyxcbiAgICAgIHNvdXJjZVBhdGg6IGpvaW4ocmVwb1Jvb3RGcm9tTW9kdWxlKCksICdzY3JpcHRzJywgJ3Blcm1pc3Npb24tcG9ydC1kaXNjb3Zlcnkuc2gnKSxcbiAgICAgIHRhcmdldFBhdGg6IGpvaW4oaG9va3NEaXIsICdwZXJtaXNzaW9uLXBvcnQtZGlzY292ZXJ5LnNoJyksXG4gICAgfSxcbiAgICB7XG4gICAgICBraW5kOiAnY29uZmlnLWhlbHBlcicsXG4gICAgICBzb3VyY2VQYXRoOiBqb2luKHJlcG9Sb290RnJvbU1vZHVsZSgpLCAnc2NyaXB0cycsICdwZXJtaXNzaW9uLWhvb2stY29uZmlnLnNoJyksXG4gICAgICB0YXJnZXRQYXRoOiBqb2luKGhvb2tzRGlyLCAncGVybWlzc2lvbi1ob29rLWNvbmZpZy5zaCcpLFxuICAgIH0sXG4gIF07XG5cbiAgY29uc3Qgd3JhcHBlclRhcmdldFBhdGggPSBnZXRIb29rV3JhcHBlclBhdGgobm9ybWFsaXplZCwgaG9tZURpcik7XG4gIGlmICh3cmFwcGVyVGFyZ2V0UGF0aCkge1xuICAgIGFzc2V0cy5wdXNoKHtcbiAgICAgIGtpbmQ6ICd3cmFwcGVyJyxcbiAgICAgIHNvdXJjZVBhdGg6IGdldEhvb2tTb3VyY2VQYXRoKG5vcm1hbGl6ZWQpLFxuICAgICAgdGFyZ2V0UGF0aDogd3JhcHBlclRhcmdldFBhdGgsXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYXNzZXRzO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZWFkT3B0aW9uYWxVdGY4RmlsZShmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgsICd1dGYtOCcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChpc01pc3NpbmdGaWxlRXJyb3IoZXJyb3IpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXVkaXRIb29rQXNzZXRzKFxuICBob3N0OiBzdHJpbmcsXG4gIGhvbWVEaXIgPSBob21lZGlyKCksXG4gIHNvdXJjZVNjcmlwdFBhdGg/OiBzdHJpbmcsXG4pOiBQcm9taXNlPEhvb2tBc3NldEF1ZGl0UmVzdWx0PiB7XG4gIGNvbnN0IGFzc2V0cyA9IGdldE1hbmFnZWRIb29rQXNzZXRzKGhvc3QsIGhvbWVEaXIsIHNvdXJjZVNjcmlwdFBhdGgpO1xuICBjb25zdCBzdGFsZUFzc2V0czogSG9va0Fzc2V0RGVzY3JpcHRvcltdID0gW107XG4gIGxldCBhc3NldHNQcmVwYXJlZCA9IHRydWU7XG5cbiAgZm9yIChjb25zdCBhc3NldCBvZiBhc3NldHMpIHtcbiAgICBjb25zdCBzb3VyY2VSYXcgPSBhd2FpdCByZWFkRmlsZShhc3NldC5zb3VyY2VQYXRoLCAndXRmLTgnKTtcbiAgICBjb25zdCB0YXJnZXRSYXcgPSBhd2FpdCByZWFkT3B0aW9uYWxVdGY4RmlsZShhc3NldC50YXJnZXRQYXRoKTtcbiAgICBpZiAodGFyZ2V0UmF3ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGFzc2V0c1ByZXBhcmVkID0gZmFsc2U7XG4gICAgICBzdGFsZUFzc2V0cy5wdXNoKGFzc2V0KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0UmF3ICE9PSBzb3VyY2VSYXcpIHtcbiAgICAgIHN0YWxlQXNzZXRzLnB1c2goYXNzZXQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYXNzZXRzUHJlcGFyZWQsXG4gICAgYXNzZXRzQ3VycmVudDogc3RhbGVBc3NldHMubGVuZ3RoID09PSAwLFxuICAgIHN0YWxlQXNzZXRzLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGVybWlzc2lvbkhvb2tNYXJrZXJQYXRoKGhvbWVEaXIgPSBob21lZGlyKCksIGhvc3Q/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoIWhvc3QpIHtcbiAgICByZXR1cm4gam9pbihnZXRQZXJtaXNzaW9uSG9va1J1bkRpcihob21lRGlyKSwgJ2hvb2staW5zdGFsbGVkLmpzb24nKTtcbiAgfVxuICByZXR1cm4gam9pbihnZXRQZXJtaXNzaW9uSG9va1J1bkRpcihob21lRGlyKSwgYGhvb2staW5zdGFsbGVkLSR7bm9ybWFsaXplSG9va0hvc3QoaG9zdCl9Lmpzb25gKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENsYXVkZUhvb2tTZXR0aW5nc1BhdGgoaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGhvbWVEaXIsICcuY2xhdWRlJywgJ3NldHRpbmdzLmpzb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZzQ29kZUhvb2tTZXR0aW5nc1BhdGgoaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGhvbWVEaXIsICcuY29waWxvdCcsICdob29rcycsICdkb2xsaG91c2UtcGVybWlzc2lvbnMuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VnNDb2RlVXNlclNldHRpbmdzUGF0aChob21lRGlyID0gaG9tZWRpcigpKTogc3RyaW5nIHtcbiAgY29uc3QgY3VycmVudFBsYXRmb3JtID0gcGxhdGZvcm0oKTtcbiAgaWYgKGN1cnJlbnRQbGF0Zm9ybSA9PT0gJ2RhcndpbicpIHtcbiAgICByZXR1cm4gam9pbihob21lRGlyLCAnTGlicmFyeScsICdBcHBsaWNhdGlvbiBTdXBwb3J0JywgJ0NvZGUnLCAnVXNlcicsICdzZXR0aW5ncy5qc29uJyk7XG4gIH1cbiAgaWYgKGN1cnJlbnRQbGF0Zm9ybSA9PT0gJ3dpbjMyJykge1xuICAgIGNvbnN0IGFwcERhdGEgPSBwcm9jZXNzLmVudi5BUFBEQVRBIHx8IGpvaW4oaG9tZURpciwgJ0FwcERhdGEnLCAnUm9hbWluZycpO1xuICAgIHJldHVybiBqb2luKGFwcERhdGEsICdDb2RlJywgJ1VzZXInLCAnc2V0dGluZ3MuanNvbicpO1xuICB9XG4gIHJldHVybiBqb2luKGhvbWVEaXIsICcuY29uZmlnJywgJ0NvZGUnLCAnVXNlcicsICdzZXR0aW5ncy5qc29uJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHZW1pbmlIb29rU2V0dGluZ3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmdlbWluaScsICdzZXR0aW5ncy5qc29uJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDdXJzb3JIb29rU2V0dGluZ3NQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmN1cnNvcicsICdob29rcy5qc29uJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXaW5kc3VyZkhvb2tTZXR0aW5nc1BhdGgoaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGhvbWVEaXIsICcuY29kZWl1bScsICd3aW5kc3VyZicsICdob29rcy5qc29uJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb2RleEhvb2tTZXR0aW5nc1BhdGgoaG9tZURpciA9IGhvbWVkaXIoKSk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGhvbWVEaXIsICcuY29kZXgnLCAnaG9va3MuanNvbicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29kZXhDb25maWdQYXRoKGhvbWVEaXIgPSBob21lZGlyKCkpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihob21lRGlyLCAnLmNvZGV4JywgJ2NvbmZpZy50b21sJyk7XG59XG5cbmZ1bmN0aW9uIHRvUGVybWlzc2lvbkhvb2tTdGF0dXMocmF3OiBQZXJtaXNzaW9uSG9va01hcmtlcik6IFBlcm1pc3Npb25Ib29rU3RhdHVzIHtcbiAgaWYgKFxuICAgIHR5cGVvZiByYXcuaG9zdCAhPT0gJ3N0cmluZycgfHxcbiAgICB0eXBlb2YgcmF3LnNjcmlwdFBhdGggIT09ICdzdHJpbmcnXG4gICkge1xuICAgIHJldHVybiB7IGluc3RhbGxlZDogZmFsc2UgfTtcbiAgfVxuXG4gIGNvbnN0IHNjcmlwdFJlYWR5ID0gZXhpc3RzU3luYyhyYXcuc2NyaXB0UGF0aCk7XG4gIGNvbnN0IHNldHRpbmdzUmVhZHkgPSAhcmF3LnNldHRpbmdzUGF0aCB8fCBleGlzdHNTeW5jKHJhdy5zZXR0aW5nc1BhdGgpO1xuICBjb25zdCBhZGRpdGlvbmFsUGF0aHNSZWFkeSA9ICFyYXcuYWRkaXRpb25hbFBhdGhzIHx8IHJhdy5hZGRpdGlvbmFsUGF0aHMuZXZlcnkoKHBhdGgpID0+IGV4aXN0c1N5bmMocGF0aCkpO1xuICBjb25zdCBhc3NldHNQcmVwYXJlZCA9IChyYXcuYXNzZXRzUHJlcGFyZWQgPz8gcmF3LmNvbmZpZ3VyZWQgPz8gdHJ1ZSkgJiYgc2NyaXB0UmVhZHk7XG4gIGNvbnN0IGNvbmZpZ3VyZWQgPSAocmF3LmNvbmZpZ3VyZWQgPz8gdHJ1ZSkgJiYgc2NyaXB0UmVhZHkgJiYgc2V0dGluZ3NSZWFkeSAmJiBhZGRpdGlvbmFsUGF0aHNSZWFkeTtcblxuICByZXR1cm4ge1xuICAgIGluc3RhbGxlZDogY29uZmlndXJlZCxcbiAgICBjb25maWd1cmVkLFxuICAgIGFzc2V0c1ByZXBhcmVkLFxuICAgIGhvc3Q6IHJhdy5ob3N0LFxuICAgIHNjcmlwdFBhdGg6IHJhdy5zY3JpcHRQYXRoLFxuICAgIHNldHRpbmdzUGF0aDogcmF3LnNldHRpbmdzUGF0aCxcbiAgICBhZGRpdGlvbmFsUGF0aHM6IHJhdy5hZGRpdGlvbmFsUGF0aHMsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlYWRNYXJrZXJTdGF0dXMobWFya2VyUGF0aDogc3RyaW5nKTogUGVybWlzc2lvbkhvb2tTdGF0dXMge1xuICB0cnkge1xuICAgIGNvbnN0IHJhdyA9IHJlYWRGaWxlU3luYyhtYXJrZXJQYXRoLCAndXRmLTgnKTtcbiAgICByZXR1cm4gdG9QZXJtaXNzaW9uSG9va1N0YXR1cyhKU09OLnBhcnNlKHJhdykgYXMgUGVybWlzc2lvbkhvb2tNYXJrZXIpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmICghaXNNaXNzaW5nRmlsZUVycm9yKGVycm9yKSkge1xuICAgICAgbG9nZ2VyLndhcm4oYFtQZXJtaXNzaW9uc10gRmFpbGVkIHRvIHJlYWQgaG9vayBtYXJrZXIgYXQgJHttYXJrZXJQYXRofTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgIH1cbiAgICByZXR1cm4geyBpbnN0YWxsZWQ6IGZhbHNlIH07XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUhvb2tzUm9vdChwYXJzZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUmVjb3JkPHN0cmluZywgdW5rbm93bltdPiB7XG4gIGNvbnN0IGhvb2tzVmFsdWUgPSBwYXJzZWQuaG9va3M7XG4gIGlmICghaG9va3NWYWx1ZSB8fCB0eXBlb2YgaG9va3NWYWx1ZSAhPT0gJ29iamVjdCcgfHwgQXJyYXkuaXNBcnJheShob29rc1ZhbHVlKSkge1xuICAgIHBhcnNlZC5ob29rcyA9IHt9O1xuICB9XG4gIHJldHVybiBwYXJzZWQuaG9va3MgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bltdPjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZUNvbW1hbmRIb29rKFxuICBwYXJzZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBldmVudE5hbWU6IHN0cmluZyxcbiAgY29tbWFuZDogc3RyaW5nLFxuICBtYXRjaGVyOiBzdHJpbmcsXG4gIGV4dHJhSG9va0ZpZWxkczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbik6IHsgY2hhbmdlZDogYm9vbGVhbjsgcGFyc2VkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9IHtcbiAgY29uc3QgaG9va3NSb290ID0gbm9ybWFsaXplSG9va3NSb290KHBhcnNlZCk7XG4gIGNvbnN0IGV4aXN0aW5nRW50cmllczogQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0gQXJyYXkuaXNBcnJheShob29rc1Jvb3RbZXZlbnROYW1lXSlcbiAgICA/IGhvb2tzUm9vdFtldmVudE5hbWVdLmZpbHRlcigoZW50cnkpOiBlbnRyeSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PiB0eXBlb2YgZW50cnkgPT09ICdvYmplY3QnICYmIGVudHJ5ICE9PSBudWxsKVxuICAgIDogW107XG4gIGhvb2tzUm9vdFtldmVudE5hbWVdID0gZXhpc3RpbmdFbnRyaWVzO1xuXG4gIGNvbnN0IGNvbW1hbmRFeGlzdHMgPSBleGlzdGluZ0VudHJpZXMuc29tZSgoZW50cnkpID0+IHtcbiAgICBjb25zdCBob29rcyA9IEFycmF5LmlzQXJyYXkoZW50cnk/Lmhvb2tzKSA/IGVudHJ5Lmhvb2tzIGFzIEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PiA6IFtdO1xuICAgIHJldHVybiBob29rcy5zb21lKChob29rKSA9PiBob29rPy50eXBlID09PSAnY29tbWFuZCcgJiYgaG9vaz8uY29tbWFuZCA9PT0gY29tbWFuZCk7XG4gIH0pO1xuICBpZiAoY29tbWFuZEV4aXN0cykge1xuICAgIHJldHVybiB7IGNoYW5nZWQ6IGZhbHNlLCBwYXJzZWQgfTtcbiAgfVxuXG4gIGNvbnN0IHdpbGRjYXJkRW50cnkgPSBleGlzdGluZ0VudHJpZXMuZmluZCgoZW50cnkpOiBlbnRyeSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PlxuICAgIChlbnRyeT8ubWF0Y2hlciA9PT0gbWF0Y2hlciB8fCBlbnRyeT8ubWF0Y2hlciA9PT0gdW5kZWZpbmVkKSAmJiBBcnJheS5pc0FycmF5KGVudHJ5Py5ob29rcyksXG4gICk7XG5cbiAgaWYgKHdpbGRjYXJkRW50cnkpIHtcbiAgICBjb25zdCBob29rcyA9IHdpbGRjYXJkRW50cnkuaG9va3MgYXMgQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICAgIGhvb2tzLnB1c2goe1xuICAgICAgdHlwZTogJ2NvbW1hbmQnLFxuICAgICAgY29tbWFuZCxcbiAgICAgIC4uLmV4dHJhSG9va0ZpZWxkcyxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBleGlzdGluZ0VudHJpZXMucHVzaCh7XG4gICAgICBtYXRjaGVyLFxuICAgICAgaG9va3M6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdjb21tYW5kJyxcbiAgICAgICAgICBjb21tYW5kLFxuICAgICAgICAgIC4uLmV4dHJhSG9va0ZpZWxkcyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4geyBjaGFuZ2VkOiB0cnVlLCBwYXJzZWQgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY29weUhvb2tBc3NldChzb3VyY2VQYXRoOiBzdHJpbmcsIHRhcmdldFBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBhd2FpdCBta2RpcihkaXJuYW1lKHRhcmdldFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICBjb25zdCBzb3VyY2VSYXcgPSBhd2FpdCByZWFkRmlsZShzb3VyY2VQYXRoLCAndXRmLTgnKTtcblxuICBsZXQgdGFyZ2V0UmF3OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHRyeSB7XG4gICAgdGFyZ2V0UmF3ID0gYXdhaXQgcmVhZEZpbGUodGFyZ2V0UGF0aCwgJ3V0Zi04Jyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKCFpc01pc3NpbmdGaWxlRXJyb3IoZXJyb3IpKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgY29uc3QgY2hhbmdlZCA9IHRhcmdldFJhdyA9PT0gdW5kZWZpbmVkIHx8IHNvdXJjZVJhdyAhPT0gdGFyZ2V0UmF3O1xuXG4gIGlmIChjaGFuZ2VkKSB7XG4gICAgYXdhaXQgY29weUZpbGUoc291cmNlUGF0aCwgdGFyZ2V0UGF0aCk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgYWNjZXNzKHRhcmdldFBhdGgpO1xuICB9XG5cbiAgYXdhaXQgY2htb2QodGFyZ2V0UGF0aCwgMG83NTUpO1xuICByZXR1cm4gY2hhbmdlZDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRPcHRpb25hbFV0ZjgoZmlsZVBhdGg6IHN0cmluZywgZmFsbGJhY2s6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoLCAndXRmLTgnKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoaXNNaXNzaW5nRmlsZUVycm9yKGVycm9yKSkge1xuICAgICAgcmV0dXJuIGZhbGxiYWNrO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVCYWNrdXBJZlByZXNlbnQoZmlsZVBhdGg6IHN0cmluZywgcmF3OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBpZiAoIWV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGJhY2t1cFBhdGggPSBgJHtmaWxlUGF0aH0uZG9sbGhvdXNlLmJha2A7XG4gIGF3YWl0IHdyaXRlRmlsZShiYWNrdXBQYXRoLCByYXcsICd1dGYtOCcpO1xuICByZXR1cm4gYmFja3VwUGF0aDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlSG9va01hcmtlcihcbiAgaG9tZURpcjogc3RyaW5nLFxuICBtYXJrZXI6IFBlcm1pc3Npb25Ib29rTWFya2VyLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgbWFya2VyUGF0aCA9IGdldFBlcm1pc3Npb25Ib29rTWFya2VyUGF0aChob21lRGlyLCBtYXJrZXIuaG9zdCk7XG4gIGF3YWl0IG1rZGlyKGRpcm5hbWUobWFya2VyUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBhd2FpdCB3cml0ZUZpbGUobWFya2VyUGF0aCwgSlNPTi5zdHJpbmdpZnkobWFya2VyLCBudWxsLCAyKSArICdcXG4nLCAndXRmLTgnKTtcbiAgcmV0dXJuIG1hcmtlclBhdGg7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpbnN0YWxsSG9va0Fzc2V0c0Zvckhvc3QoXG4gIGNsaWVudDogc3RyaW5nLFxuICBob21lRGlyOiBzdHJpbmcsXG4gIHNvdXJjZVNjcmlwdFBhdGg/OiBzdHJpbmcsXG4pOiBQcm9taXNlPHsgc2NyaXB0UGF0aDogc3RyaW5nIH0+IHtcbiAgY29uc3Qgbm9ybWFsaXplZENsaWVudCA9IG5vcm1hbGl6ZUhvb2tIb3N0KGNsaWVudCk7XG4gIGNvbnN0IGhvb2tzRGlyID0gZGlybmFtZShnZXRQZXJtaXNzaW9uSG9va1NjcmlwdFBhdGgoaG9tZURpcikpO1xuICBjb25zdCBzaGFyZWRUYXJnZXRQYXRoID0gZ2V0UGVybWlzc2lvbkhvb2tTY3JpcHRQYXRoKGhvbWVEaXIpO1xuICBjb25zdCBzaGFyZWRTb3VyY2VQYXRoID0gc291cmNlU2NyaXB0UGF0aCA/PyBqb2luKHJlcG9Sb290RnJvbU1vZHVsZSgpLCAnc2NyaXB0cycsICdwcmV0b29sdXNlLWRvbGxob3VzZS5zaCcpO1xuICBjb25zdCBwb3J0SGVscGVyU291cmNlUGF0aCA9IGpvaW4ocmVwb1Jvb3RGcm9tTW9kdWxlKCksICdzY3JpcHRzJywgJ3Blcm1pc3Npb24tcG9ydC1kaXNjb3Zlcnkuc2gnKTtcbiAgY29uc3QgcG9ydEhlbHBlclRhcmdldFBhdGggPSBqb2luKGhvb2tzRGlyLCAncGVybWlzc2lvbi1wb3J0LWRpc2NvdmVyeS5zaCcpO1xuICBjb25zdCBjb25maWdIZWxwZXJTb3VyY2VQYXRoID0gam9pbihyZXBvUm9vdEZyb21Nb2R1bGUoKSwgJ3NjcmlwdHMnLCAncGVybWlzc2lvbi1ob29rLWNvbmZpZy5zaCcpO1xuICBjb25zdCBjb25maWdIZWxwZXJUYXJnZXRQYXRoID0gam9pbihob29rc0RpciwgJ3Blcm1pc3Npb24taG9vay1jb25maWcuc2gnKTtcblxuICBjb25zdCBzaGFyZWRTdGF0ID0gc3RhdFN5bmMoc2hhcmVkU291cmNlUGF0aCk7XG4gIGlmICghc2hhcmVkU3RhdC5pc0ZpbGUoKSkge1xuICAgIGxvZ2dlci53YXJuKGBbUGVybWlzc2lvbkhvb2tzXSBTaGFyZWQgaG9vayBicmlkZ2UgbWlzc2luZyBmb3IgJHtub3JtYWxpemVkQ2xpZW50fTogJHtzaGFyZWRTb3VyY2VQYXRofWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgUGVybWlzc2lvbiBob29rIHNvdXJjZSBzY3JpcHQgbm90IGZvdW5kOiAke3NoYXJlZFNvdXJjZVBhdGh9YCk7XG4gIH1cbiAgYXdhaXQgY29weUhvb2tBc3NldChzaGFyZWRTb3VyY2VQYXRoLCBzaGFyZWRUYXJnZXRQYXRoKTtcblxuICBjb25zdCBwb3J0SGVscGVyU3RhdCA9IHN0YXRTeW5jKHBvcnRIZWxwZXJTb3VyY2VQYXRoKTtcbiAgaWYgKCFwb3J0SGVscGVyU3RhdC5pc0ZpbGUoKSkge1xuICAgIGxvZ2dlci53YXJuKGBbUGVybWlzc2lvbkhvb2tzXSBQb3J0IGRpc2NvdmVyeSBoZWxwZXIgbWlzc2luZyBmb3IgJHtub3JtYWxpemVkQ2xpZW50fTogJHtwb3J0SGVscGVyU291cmNlUGF0aH1gKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFBlcm1pc3Npb24gaG9vayBoZWxwZXIgc2NyaXB0IG5vdCBmb3VuZDogJHtwb3J0SGVscGVyU291cmNlUGF0aH1gKTtcbiAgfVxuICBhd2FpdCBjb3B5SG9va0Fzc2V0KHBvcnRIZWxwZXJTb3VyY2VQYXRoLCBwb3J0SGVscGVyVGFyZ2V0UGF0aCk7XG5cbiAgY29uc3QgY29uZmlnSGVscGVyU3RhdCA9IHN0YXRTeW5jKGNvbmZpZ0hlbHBlclNvdXJjZVBhdGgpO1xuICBpZiAoIWNvbmZpZ0hlbHBlclN0YXQuaXNGaWxlKCkpIHtcbiAgICBsb2dnZXIud2FybihgW1Blcm1pc3Npb25Ib29rc10gQ29uZmlnIGhlbHBlciBtaXNzaW5nIGZvciAke25vcm1hbGl6ZWRDbGllbnR9OiAke2NvbmZpZ0hlbHBlclNvdXJjZVBhdGh9YCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBQZXJtaXNzaW9uIGhvb2sgY29uZmlnIGhlbHBlciBub3QgZm91bmQ6ICR7Y29uZmlnSGVscGVyU291cmNlUGF0aH1gKTtcbiAgfVxuICBhd2FpdCBjb3B5SG9va0Fzc2V0KGNvbmZpZ0hlbHBlclNvdXJjZVBhdGgsIGNvbmZpZ0hlbHBlclRhcmdldFBhdGgpO1xuXG4gIGNvbnN0IHdyYXBwZXJUYXJnZXRQYXRoID0gZ2V0SG9va1dyYXBwZXJQYXRoKG5vcm1hbGl6ZWRDbGllbnQsIGhvbWVEaXIpO1xuICBpZiAoIXdyYXBwZXJUYXJnZXRQYXRoKSB7XG4gICAgcmV0dXJuIHsgc2NyaXB0UGF0aDogc2hhcmVkVGFyZ2V0UGF0aCB9O1xuICB9XG5cbiAgY29uc3Qgd3JhcHBlclNvdXJjZVBhdGggPSBnZXRIb29rU291cmNlUGF0aChub3JtYWxpemVkQ2xpZW50KTtcbiAgY29uc3Qgd3JhcHBlclN0YXQgPSBzdGF0U3luYyh3cmFwcGVyU291cmNlUGF0aCk7XG4gIGlmICghd3JhcHBlclN0YXQuaXNGaWxlKCkpIHtcbiAgICBsb2dnZXIud2FybihgW1Blcm1pc3Npb25Ib29rc10gV3JhcHBlciBob29rIHNjcmlwdCBtaXNzaW5nIGZvciAke25vcm1hbGl6ZWRDbGllbnR9OiAke3dyYXBwZXJTb3VyY2VQYXRofWApO1xuICAgIHRocm93IG5ldyBFcnJvcihgUGVybWlzc2lvbiBob29rIHdyYXBwZXIgc2NyaXB0IG5vdCBmb3VuZDogJHt3cmFwcGVyU291cmNlUGF0aH1gKTtcbiAgfVxuICBhd2FpdCBjb3B5SG9va0Fzc2V0KHdyYXBwZXJTb3VyY2VQYXRoLCB3cmFwcGVyVGFyZ2V0UGF0aCk7XG4gIHJldHVybiB7IHNjcmlwdFBhdGg6IHdyYXBwZXJUYXJnZXRQYXRoIH07XG59XG4iXX0=
@@ -0,0 +1,10 @@
1
+ import { type PermissionHookAuditSummary, type PermissionHookHealthSummary, type PermissionHookStartupRepairSummary, type PermissionHookStatus, type ReconcilePermissionHookOptions } from './permissionHookShared.js';
2
+ export declare function getPermissionHookStatus(homeDir?: string, host?: string): PermissionHookStatus;
3
+ export declare function getPermissionHookStatusAsync(homeDir?: string, host?: string): Promise<PermissionHookStatus>;
4
+ export declare function getLastPermissionHookStartupRepairSummary(): PermissionHookStartupRepairSummary | null;
5
+ export declare function _resetPermissionHookStartupRepairSummaryForTests(): void;
6
+ export declare function reconcilePermissionHookStatus(host: string, options?: ReconcilePermissionHookOptions): Promise<PermissionHookStatus>;
7
+ export declare function getPermissionHookAuditSummary(homeDir?: string): Promise<PermissionHookAuditSummary>;
8
+ export declare function summarizePermissionHookHealth(summary: PermissionHookAuditSummary): PermissionHookHealthSummary;
9
+ export declare function repairPermissionHooksOnStartup(homeDir?: string, sourceScriptPath?: string): Promise<PermissionHookStartupRepairSummary>;
10
+ //# sourceMappingURL=permissionHookStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionHookStatus.d.ts","sourceRoot":"","sources":["../../src/utils/permissionHookStatus.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAGhC,KAAK,kCAAkC,EACvC,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EAWpC,MAAM,2BAA2B,CAAC;AAInC,wBAAgB,uBAAuB,CAAC,OAAO,SAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAMhG;AAED,wBAAsB,4BAA4B,CAAC,OAAO,SAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAMpH;AA2FD,wBAAgB,yCAAyC,IAAI,kCAAkC,GAAG,IAAI,CAErG;AAED,wBAAgB,gDAAgD,IAAI,IAAI,CAEvE;AAED,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED,wBAAsB,6BAA6B,CAAC,OAAO,SAAY,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA4B5G;AA4CD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,0BAA0B,GAClC,2BAA2B,CAmD7B;AAED,wBAAsB,8BAA8B,CAClD,OAAO,SAAY,EACnB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,kCAAkC,CAAC,CA0D7C"}