@dollhousemcp/mcp-server 2.0.37 → 2.0.39
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 +9 -0
- package/dist/cli/convert.js +20 -6
- package/dist/elements/agents/AgentManager.d.ts +5 -5
- package/dist/elements/agents/AgentManager.d.ts.map +1 -1
- package/dist/elements/agents/AgentManager.js +22 -2
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/utils/pathSecurity.d.ts +44 -1
- package/dist/utils/pathSecurity.d.ts.map +1 -1
- package/dist/utils/pathSecurity.js +144 -10
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Auto-generated file - DO NOT EDIT
|
|
3
3
|
* Generated at build time by scripts/generate-version.js
|
|
4
4
|
*/
|
|
5
|
-
export declare const PACKAGE_VERSION = "2.0.
|
|
6
|
-
export declare const BUILD_TIMESTAMP = "2026-07-
|
|
5
|
+
export declare const PACKAGE_VERSION = "2.0.39";
|
|
6
|
+
export declare const BUILD_TIMESTAMP = "2026-07-31T16:08:01.942Z";
|
|
7
7
|
export declare const BUILD_TYPE: 'npm' | 'git';
|
|
8
8
|
export declare const PACKAGE_NAME = "@dollhousemcp/mcp-server";
|
|
9
9
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Auto-generated file - DO NOT EDIT
|
|
3
3
|
* Generated at build time by scripts/generate-version.js
|
|
4
4
|
*/
|
|
5
|
-
export const PACKAGE_VERSION = '2.0.
|
|
6
|
-
export const BUILD_TIMESTAMP = '2026-07-
|
|
5
|
+
export const PACKAGE_VERSION = '2.0.39';
|
|
6
|
+
export const BUILD_TIMESTAMP = '2026-07-31T16:08:01.942Z';
|
|
7
7
|
export const BUILD_TYPE = 'npm';
|
|
8
8
|
export const PACKAGE_NAME = '@dollhousemcp/mcp-server';
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZWQvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBQ3hDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUMxRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEtBQUssQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGZpbGUgLSBETyBOT1QgRURJVFxuICogR2VuZXJhdGVkIGF0IGJ1aWxkIHRpbWUgYnkgc2NyaXB0cy9nZW5lcmF0ZS12ZXJzaW9uLmpzXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9ICcyLjAuMzknO1xuZXhwb3J0IGNvbnN0IEJVSUxEX1RJTUVTVEFNUCA9ICcyMDI2LTA3LTMxVDE2OjA4OjAxLjk0MlonO1xuZXhwb3J0IGNvbnN0IEJVSUxEX1RZUEU6ICducG0nIHwgJ2dpdCcgPSAnbnBtJztcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSAnQGRvbGxob3VzZW1jcC9tY3Atc2VydmVyJztcbiJdfQ==
|
|
@@ -3,7 +3,50 @@
|
|
|
3
3
|
* directory. This is separator-aware, so sibling paths such as `/tmp/base2`
|
|
4
4
|
* are not treated as children of `/tmp/base`. Existing symlinked base paths
|
|
5
5
|
* and symlinked descendants under the base are rejected because writes would
|
|
6
|
-
* follow them outside the lexical containment boundary.
|
|
6
|
+
* follow them outside the lexical containment boundary. A base that does not
|
|
7
|
+
* exist yet is vetted through its nearest existing ancestor: if that ancestor
|
|
8
|
+
* is a symlink, the recursive mkdir/write that follows would be redirected
|
|
9
|
+
* outside the intended tree, so it is rejected too (#2342).
|
|
10
|
+
*
|
|
11
|
+
* CONTRACT (#2344): the base's own ancestry can only be best-effort vetted
|
|
12
|
+
* here — a symlink whose target pre-contains matching subdirectories is not
|
|
13
|
+
* detectable without a caller-known boundary (see nearestExistingAncestorStats
|
|
14
|
+
* for why walking every ancestor false-positives on system symlinks). Do NOT
|
|
15
|
+
* pass user-controlled base paths directly to this function: vet them first
|
|
16
|
+
* with vetOutputBase(), which contains them canonically against an anchor and
|
|
17
|
+
* returns the canonical base to use here. Every current caller does this.
|
|
7
18
|
*/
|
|
8
19
|
export declare function resolvePathWithinBase(baseDir: string, ...segments: string[]): string;
|
|
20
|
+
/**
|
|
21
|
+
* Canonical (realpath) form of a path that may not fully exist yet: the
|
|
22
|
+
* deepest existing ancestor is resolved through every symlink, and the
|
|
23
|
+
* not-yet-created suffix is appended unchanged. This answers "where would a
|
|
24
|
+
* recursive mkdir/write on this path REALLY land?" — which per-component
|
|
25
|
+
* lstat checks cannot, because lstat resolves intermediate symlinks and only
|
|
26
|
+
* reports on the final component (#2344).
|
|
27
|
+
*/
|
|
28
|
+
export declare function canonicalizePath(inputPath: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Vets a user-supplied output base for CLI writes and returns the canonical
|
|
31
|
+
* path all subsequent writes should use (#2344).
|
|
32
|
+
*
|
|
33
|
+
* Two regimes, split by what the user lexically named:
|
|
34
|
+
*
|
|
35
|
+
* - Base inside the anchor (relative outputs like the './anthropic-skills'
|
|
36
|
+
* default): the canonical base must stay inside the canonical anchor.
|
|
37
|
+
* A symlink that redirects it elsewhere — including one whose target
|
|
38
|
+
* already contains matching subdirectories, the case per-component lstat
|
|
39
|
+
* checks miss — is rejected. Comparing in canonical space means system
|
|
40
|
+
* links above the anchor (macOS /tmp -> /private/tmp) never false-positive.
|
|
41
|
+
*
|
|
42
|
+
* - Base outside the anchor (explicit absolute or ../ outputs): the user
|
|
43
|
+
* named that destination, so there is no boundary to defend. Instead of
|
|
44
|
+
* guessing intent, the real destination is disclosed via `onDisclose`
|
|
45
|
+
* whenever it differs from the lexical path, and the canonical path is
|
|
46
|
+
* returned so what was vetted is what gets written.
|
|
47
|
+
*/
|
|
48
|
+
export declare function vetOutputBase(baseDir: string, options?: {
|
|
49
|
+
anchor?: string;
|
|
50
|
+
onDisclose?: (canonicalBase: string) => void;
|
|
51
|
+
}): string;
|
|
9
52
|
//# sourceMappingURL=pathSecurity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathSecurity.d.ts","sourceRoot":"","sources":["../../src/utils/pathSecurity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pathSecurity.d.ts","sourceRoot":"","sources":["../../src/utils/pathSecurity.ts"],"names":[],"mappings":"AAkFA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CA4BpF;AASD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsB1D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAC1E,MAAM,CA0BR"}
|
|
@@ -1,21 +1,65 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
+
function isMissingPathError(error) {
|
|
4
|
+
const code = typeof error === 'object' && error !== null && 'code' in error
|
|
5
|
+
? error.code
|
|
6
|
+
: undefined;
|
|
7
|
+
return code === 'ENOENT' || code === 'ENOTDIR';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* lstat of the deepest ancestor of `startPath` that exists, or null when
|
|
11
|
+
* nothing up to the filesystem root exists. Used to vet paths that will be
|
|
12
|
+
* created later: their containment depends on the directory they will be
|
|
13
|
+
* created inside.
|
|
14
|
+
*
|
|
15
|
+
* KNOWN LIMIT (#2344): this stops at the first ancestor lstat can see, and
|
|
16
|
+
* lstat resolves intermediate symlinks — so a symlink whose target already
|
|
17
|
+
* contains a matching subdirectory is reported as a plain directory and the
|
|
18
|
+
* symlink component itself is never inspected. Walking every lexical ancestor
|
|
19
|
+
* instead is not an option: system symlinks (macOS /tmp -> /private/tmp,
|
|
20
|
+
* /var -> /private/var) sit above every temp path and would false-positive.
|
|
21
|
+
* Full protection needs a caller-known boundary, which is exactly what
|
|
22
|
+
* vetOutputBase() provides — see the contract note on resolvePathWithinBase.
|
|
23
|
+
*/
|
|
24
|
+
function nearestExistingAncestorStats(startPath) {
|
|
25
|
+
let previous = startPath;
|
|
26
|
+
let current = path.dirname(startPath);
|
|
27
|
+
while (current !== previous) {
|
|
28
|
+
try {
|
|
29
|
+
return fs.lstatSync(current);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (!isMissingPathError(error)) {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
previous = current;
|
|
37
|
+
current = path.dirname(current);
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
3
41
|
function assertNotSymlink(pathToCheck, message) {
|
|
42
|
+
let stats;
|
|
4
43
|
try {
|
|
5
|
-
|
|
6
|
-
if (stats.isSymbolicLink()) {
|
|
7
|
-
throw new Error(message);
|
|
8
|
-
}
|
|
44
|
+
stats = fs.lstatSync(pathToCheck);
|
|
9
45
|
}
|
|
10
46
|
catch (error) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
47
|
+
if (isMissingPathError(error)) {
|
|
48
|
+
// The path does not exist yet, so it will be created by a later
|
|
49
|
+
// mkdir/write. That is only safe if the directory it gets created
|
|
50
|
+
// inside is real: a symlinked existing ancestor would redirect the
|
|
51
|
+
// recursive create outside the containment boundary (#2342).
|
|
52
|
+
const ancestorStats = nearestExistingAncestorStats(pathToCheck);
|
|
53
|
+
if (ancestorStats?.isSymbolicLink()) {
|
|
54
|
+
throw new Error(message);
|
|
55
|
+
}
|
|
15
56
|
return;
|
|
16
57
|
}
|
|
17
58
|
throw error;
|
|
18
59
|
}
|
|
60
|
+
if (stats.isSymbolicLink()) {
|
|
61
|
+
throw new Error(message);
|
|
62
|
+
}
|
|
19
63
|
}
|
|
20
64
|
function assertNoSymlinkedDescendants(resolvedBase, resolvedTarget) {
|
|
21
65
|
const relativePath = path.relative(resolvedBase, resolvedTarget);
|
|
@@ -36,7 +80,18 @@ function assertNoSymlinkedDescendants(resolvedBase, resolvedTarget) {
|
|
|
36
80
|
* directory. This is separator-aware, so sibling paths such as `/tmp/base2`
|
|
37
81
|
* are not treated as children of `/tmp/base`. Existing symlinked base paths
|
|
38
82
|
* and symlinked descendants under the base are rejected because writes would
|
|
39
|
-
* follow them outside the lexical containment boundary.
|
|
83
|
+
* follow them outside the lexical containment boundary. A base that does not
|
|
84
|
+
* exist yet is vetted through its nearest existing ancestor: if that ancestor
|
|
85
|
+
* is a symlink, the recursive mkdir/write that follows would be redirected
|
|
86
|
+
* outside the intended tree, so it is rejected too (#2342).
|
|
87
|
+
*
|
|
88
|
+
* CONTRACT (#2344): the base's own ancestry can only be best-effort vetted
|
|
89
|
+
* here — a symlink whose target pre-contains matching subdirectories is not
|
|
90
|
+
* detectable without a caller-known boundary (see nearestExistingAncestorStats
|
|
91
|
+
* for why walking every ancestor false-positives on system symlinks). Do NOT
|
|
92
|
+
* pass user-controlled base paths directly to this function: vet them first
|
|
93
|
+
* with vetOutputBase(), which contains them canonically against an anchor and
|
|
94
|
+
* returns the canonical base to use here. Every current caller does this.
|
|
40
95
|
*/
|
|
41
96
|
export function resolvePathWithinBase(baseDir, ...segments) {
|
|
42
97
|
if (!baseDir || typeof baseDir !== 'string') {
|
|
@@ -63,4 +118,83 @@ export function resolvePathWithinBase(baseDir, ...segments) {
|
|
|
63
118
|
}
|
|
64
119
|
throw new Error('Resolved path escapes the base directory');
|
|
65
120
|
}
|
|
66
|
-
|
|
121
|
+
/** True when a base-relative path points outside the base. */
|
|
122
|
+
function escapesBase(relativePath) {
|
|
123
|
+
return relativePath === '..'
|
|
124
|
+
|| relativePath.startsWith('..' + path.sep)
|
|
125
|
+
|| path.isAbsolute(relativePath);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Canonical (realpath) form of a path that may not fully exist yet: the
|
|
129
|
+
* deepest existing ancestor is resolved through every symlink, and the
|
|
130
|
+
* not-yet-created suffix is appended unchanged. This answers "where would a
|
|
131
|
+
* recursive mkdir/write on this path REALLY land?" — which per-component
|
|
132
|
+
* lstat checks cannot, because lstat resolves intermediate symlinks and only
|
|
133
|
+
* reports on the final component (#2344).
|
|
134
|
+
*/
|
|
135
|
+
export function canonicalizePath(inputPath) {
|
|
136
|
+
const resolved = path.resolve(inputPath);
|
|
137
|
+
const missing = [];
|
|
138
|
+
let current = resolved;
|
|
139
|
+
for (;;) {
|
|
140
|
+
try {
|
|
141
|
+
const canonical = fs.realpathSync(current);
|
|
142
|
+
return missing.length ? path.join(canonical, ...missing) : canonical;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (!isMissingPathError(error)) {
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const parent = path.dirname(current);
|
|
150
|
+
if (parent === current) {
|
|
151
|
+
// Nothing on the chain exists (should not happen for absolute paths —
|
|
152
|
+
// the root exists — but keep a lexical fallback rather than throwing).
|
|
153
|
+
return missing.length ? path.join(current, ...missing) : current;
|
|
154
|
+
}
|
|
155
|
+
missing.unshift(path.basename(current));
|
|
156
|
+
current = parent;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Vets a user-supplied output base for CLI writes and returns the canonical
|
|
161
|
+
* path all subsequent writes should use (#2344).
|
|
162
|
+
*
|
|
163
|
+
* Two regimes, split by what the user lexically named:
|
|
164
|
+
*
|
|
165
|
+
* - Base inside the anchor (relative outputs like the './anthropic-skills'
|
|
166
|
+
* default): the canonical base must stay inside the canonical anchor.
|
|
167
|
+
* A symlink that redirects it elsewhere — including one whose target
|
|
168
|
+
* already contains matching subdirectories, the case per-component lstat
|
|
169
|
+
* checks miss — is rejected. Comparing in canonical space means system
|
|
170
|
+
* links above the anchor (macOS /tmp -> /private/tmp) never false-positive.
|
|
171
|
+
*
|
|
172
|
+
* - Base outside the anchor (explicit absolute or ../ outputs): the user
|
|
173
|
+
* named that destination, so there is no boundary to defend. Instead of
|
|
174
|
+
* guessing intent, the real destination is disclosed via `onDisclose`
|
|
175
|
+
* whenever it differs from the lexical path, and the canonical path is
|
|
176
|
+
* returned so what was vetted is what gets written.
|
|
177
|
+
*/
|
|
178
|
+
export function vetOutputBase(baseDir, options) {
|
|
179
|
+
if (!baseDir || typeof baseDir !== 'string') {
|
|
180
|
+
throw new TypeError('Base directory must be a non-empty string');
|
|
181
|
+
}
|
|
182
|
+
if (baseDir.includes('\0')) {
|
|
183
|
+
throw new Error('Path segment contains a null byte');
|
|
184
|
+
}
|
|
185
|
+
const resolvedAnchor = path.resolve(options?.anchor ?? process.cwd());
|
|
186
|
+
const resolvedBase = path.resolve(baseDir);
|
|
187
|
+
const canonicalBase = canonicalizePath(resolvedBase);
|
|
188
|
+
if (!escapesBase(path.relative(resolvedAnchor, resolvedBase))) {
|
|
189
|
+
const canonicalAnchor = canonicalizePath(resolvedAnchor);
|
|
190
|
+
if (escapesBase(path.relative(canonicalAnchor, canonicalBase))) {
|
|
191
|
+
throw new Error(`Output path resolves outside the working directory through a symbolic link (real destination: ${canonicalBase})`);
|
|
192
|
+
}
|
|
193
|
+
return canonicalBase;
|
|
194
|
+
}
|
|
195
|
+
if (canonicalBase !== resolvedBase) {
|
|
196
|
+
options?.onDisclose?.(canonicalBase);
|
|
197
|
+
}
|
|
198
|
+
return canonicalBase;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aFNlY3VyaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3BhdGhTZWN1cml0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUVsQyxTQUFTLGtCQUFrQixDQUFDLEtBQWM7SUFDeEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksTUFBTSxJQUFJLEtBQUs7UUFDekUsQ0FBQyxDQUFFLEtBQStCLENBQUMsSUFBSTtRQUN2QyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2QsT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksS0FBSyxTQUFTLENBQUM7QUFDakQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsU0FBUyw0QkFBNEIsQ0FBQyxTQUFpQjtJQUNyRCxJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUM7SUFDekIsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUM7WUFDSCxPQUFPLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxLQUFLLENBQUM7WUFDZCxDQUFDO1FBQ0gsQ0FBQztRQUNELFFBQVEsR0FBRyxPQUFPLENBQUM7UUFDbkIsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztB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QyxRQUFRLENBQUMsZUFBZSxFQUFFLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMvRCxNQUFNLElBQUksS0FBSyxDQUNiLGlHQUFpRyxhQUFhLEdBQUcsQ0FDbEgsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBRUQsSUFBSSxhQUFhLEtBQUssWUFBWSxFQUFFLENBQUM7UUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFDRCxPQUFPLGFBQWEsQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmZ1bmN0aW9uIGlzTWlzc2luZ1BhdGhFcnJvcihlcnJvcjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBjb25zdCBjb2RlID0gdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJiBlcnJvciAhPT0gbnVsbCAmJiAnY29kZScgaW4gZXJyb3JcbiAgICA/IChlcnJvciBhcyBOb2RlSlMuRXJybm9FeGNlcHRpb24pLmNvZGVcbiAgICA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIGNvZGUgPT09ICdFTk9FTlQnIHx8IGNvZGUgPT09ICdFTk9URElSJztcbn1cblxuLyoqXG4gKiBsc3RhdCBvZiB0aGUgZGVlcGVzdCBhbmNlc3RvciBvZiBgc3RhcnRQYXRoYCB0aGF0IGV4aXN0cywgb3IgbnVsbCB3aGVuXG4gKiBub3RoaW5nIHVwIHRvIHRoZSBmaWxlc3lzdGVtIHJvb3QgZXhpc3RzLiBVc2VkIHRvIHZldCBwYXRocyB0aGF0IHdpbGwgYmVcbiAqIGNyZWF0ZWQgbGF0ZXI6IHRoZWlyIGNvbnRhaW5tZW50IGRlcGVuZHMgb24gdGhlIGRpcmVjdG9yeSB0aGV5IHdpbGwgYmVcbiAqIGNyZWF0ZWQgaW5zaWRlLlxuICpcbiAqIEtOT1dOIExJTUlUICgjMjM0NCk6IHRoaXMgc3RvcHMgYXQgdGhlIGZpcnN0IGFuY2VzdG9yIGxzdGF0IGNhbiBzZWUsIGFuZFxuICogbHN0YXQgcmVzb2x2ZXMgaW50ZXJtZWRpYXRlIHN5bWxpbmtzIOKAlCBzbyBhIHN5bWxpbmsgd2hvc2UgdGFyZ2V0IGFscmVhZHlcbiAqIGNvbnRhaW5zIGEgbWF0Y2hpbmcgc3ViZGlyZWN0b3J5IGlzIHJlcG9ydGVkIGFzIGEgcGxhaW4gZGlyZWN0b3J5IGFuZCB0aGVcbiAqIHN5bWxpbmsgY29tcG9uZW50IGl0c2VsZiBpcyBuZXZlciBpbnNwZWN0ZWQuIFdhbGtpbmcgZXZlcnkgbGV4aWNhbCBhbmNlc3RvclxuICogaW5zdGVhZCBpcyBub3QgYW4gb3B0aW9uOiBzeXN0ZW0gc3ltbGlua3MgKG1hY09TIC90bXAgLT4gL3ByaXZhdGUvdG1wLFxuICogL3ZhciAtPiAvcHJpdmF0ZS92YXIpIHNpdCBhYm92ZSBldmVyeSB0ZW1wIHBhdGggYW5kIHdvdWxkIGZhbHNlLXBvc2l0aXZlLlxuICogRnVsbCBwcm90ZWN0aW9uIG5lZWRzIGEgY2FsbGVyLWtub3duIGJvdW5kYXJ5LCB3aGljaCBpcyBleGFjdGx5IHdoYXRcbiAqIHZldE91dHB1dEJhc2UoKSBwcm92aWRlcyDigJQgc2VlIHRoZSBjb250cmFjdCBub3RlIG9uIHJlc29sdmVQYXRoV2l0aGluQmFzZS5cbiAqL1xuZnVuY3Rpb24gbmVhcmVzdEV4aXN0aW5nQW5jZXN0b3JTdGF0cyhzdGFydFBhdGg6IHN0cmluZyk6IGZzLlN0YXRzIHwgbnVsbCB7XG4gIGxldCBwcmV2aW91cyA9IHN0YXJ0UGF0aDtcbiAgbGV0IGN1cnJlbnQgPSBwYXRoLmRpcm5hbWUoc3RhcnRQYXRoKTtcbiAgd2hpbGUgKGN1cnJlbnQgIT09IHByZXZpb3VzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBmcy5sc3RhdFN5bmMoY3VycmVudCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmICghaXNNaXNzaW5nUGF0aEVycm9yKGVycm9yKSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcHJldmlvdXMgPSBjdXJyZW50O1xuICAgIGN1cnJlbnQgPSBwYXRoLmRpcm5hbWUoY3VycmVudCk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGFzc2VydE5vdFN5bWxpbmsocGF0aFRvQ2hlY2s6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gIGxldCBzdGF0czogZnMuU3RhdHM7XG4gIHRyeSB7XG4gICAgc3RhdHMgPSBmcy5sc3RhdFN5bmMocGF0aFRvQ2hlY2spO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChpc01pc3NpbmdQYXRoRXJyb3IoZXJyb3IpKSB7XG4gICAgICAvLyBUaGUgcGF0aCBkb2VzIG5vdCBleGlzdCB5ZXQsIHNvIGl0IHdpbGwgYmUgY3JlYXRlZCBieSBhIGxhdGVyXG4gICAgICAvLyBta2Rpci93cml0ZS4gVGhhdCBpcyBvbmx5IHNhZmUgaWYgdGhlIGRpcmVjdG9yeSBpdCBnZXRzIGNyZWF0ZWRcbiAgICAgIC8vIGluc2lkZSBpcyByZWFsOiBhIHN5bWxpbmtlZCBleGlzdGluZyBhbmNlc3RvciB3b3VsZCByZWRpcmVjdCB0aGVcbiAgICAgIC8vIHJlY3Vyc2l2ZSBjcmVhdGUgb3V0c2lkZSB0aGUgY29udGFpbm1lbnQgYm91bmRhcnkgKCMyMzQyKS5cbiAgICAgIGNvbnN0IGFuY2VzdG9yU3RhdHMgPSBuZWFyZXN0RXhpc3RpbmdBbmNlc3RvclN0YXRzKHBhdGhUb0NoZWNrKTtcbiAgICAgIGlmIChhbmNlc3RvclN0YXRzPy5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgaWYgKHN0YXRzLmlzU3ltYm9saWNMaW5rKCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0Tm9TeW1saW5rZWREZXNjZW5kYW50cyhyZXNvbHZlZEJhc2U6IHN0cmluZywgcmVzb2x2ZWRUYXJnZXQ6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHJlc29sdmVkQmFzZSwgcmVzb2x2ZWRUYXJnZXQpO1xuICBpZiAoIXJlbGF0aXZlUGF0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBjdXJyZW50UGF0aCA9IHJlc29sdmVkQmFzZTtcbiAgZm9yIChjb25zdCBzZWdtZW50IG9mIHJlbGF0aXZlUGF0aC5zcGxpdChwYXRoLnNlcCkpIHtcbiAgICBpZiAoIXNlZ21lbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGN1cnJlbnRQYXRoID0gcGF0aC5qb2luKGN1cnJlbnRQYXRoLCBzZWdtZW50KTtcbiAgICBhc3NlcnROb3RTeW1saW5rKGN1cnJlbnRQYXRoLCAnUGF0aCBzZWdtZW50IHJlc29sdmVzIHRocm91Z2ggYSBzeW1ib2xpYyBsaW5rJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgdGFyZ2V0IHBhdGggYW5kIHZlcmlmeSB0aGF0IGl0IHJlbWFpbnMgaW5zaWRlIHRoZSBpbnRlbmRlZCBiYXNlXG4gKiBkaXJlY3RvcnkuIFRoaXMgaXMgc2VwYXJhdG9yLWF3YXJlLCBzbyBzaWJsaW5nIHBhdGhzIHN1Y2ggYXMgYC90bXAvYmFzZTJgXG4gKiBhcmUgbm90IHRyZWF0ZWQgYXMgY2hpbGRyZW4gb2YgYC90bXAvYmFzZWAuIEV4aXN0aW5nIHN5bWxpbmtlZCBiYXNlIHBhdGhzXG4gKiBhbmQgc3ltbGlua2VkIGRlc2NlbmRhbnRzIHVuZGVyIHRoZSBiYXNlIGFyZSByZWplY3RlZCBiZWNhdXNlIHdyaXRlcyB3b3VsZFxuICogZm9sbG93IHRoZW0gb3V0c2lkZSB0aGUgbGV4aWNhbCBjb250YWlubWVudCBib3VuZGFyeS4gQSBiYXNlIHRoYXQgZG9lcyBub3RcbiAqIGV4aXN0IHlldCBpcyB2ZXR0ZWQgdGhyb3VnaCBpdHMgbmVhcmVzdCBleGlzdGluZyBhbmNlc3RvcjogaWYgdGhhdCBhbmNlc3RvclxuICogaXMgYSBzeW1saW5rLCB0aGUgcmVjdXJzaXZlIG1rZGlyL3dyaXRlIHRoYXQgZm9sbG93cyB3b3VsZCBiZSByZWRpcmVjdGVkXG4gKiBvdXRzaWRlIHRoZSBpbnRlbmRlZCB0cmVlLCBzbyBpdCBpcyByZWplY3RlZCB0b28gKCMyMzQyKS5cbiAqXG4gKiBDT05UUkFDVCAoIzIzNDQpOiB0aGUgYmFzZSdzIG93biBhbmNlc3RyeSBjYW4gb25seSBiZSBiZXN0LWVmZm9ydCB2ZXR0ZWRcbiAqIGhlcmUg4oCUIGEgc3ltbGluayB3aG9zZSB0YXJnZXQgcHJlLWNvbnRhaW5zIG1hdGNoaW5nIHN1YmRpcmVjdG9yaWVzIGlzIG5vdFxuICogZGV0ZWN0YWJsZSB3aXRob3V0IGEgY2FsbGVyLWtub3duIGJvdW5kYXJ5IChzZWUgbmVhcmVzdEV4aXN0aW5nQW5jZXN0b3JTdGF0c1xuICogZm9yIHdoeSB3YWxraW5nIGV2ZXJ5IGFuY2VzdG9yIGZhbHNlLXBvc2l0aXZlcyBvbiBzeXN0ZW0gc3ltbGlua3MpLiBEbyBOT1RcbiAqIHBhc3MgdXNlci1jb250cm9sbGVkIGJhc2UgcGF0aHMgZGlyZWN0bHkgdG8gdGhpcyBmdW5jdGlvbjogdmV0IHRoZW0gZmlyc3RcbiAqIHdpdGggdmV0T3V0cHV0QmFzZSgpLCB3aGljaCBjb250YWlucyB0aGVtIGNhbm9uaWNhbGx5IGFnYWluc3QgYW4gYW5jaG9yIGFuZFxuICogcmV0dXJucyB0aGUgY2Fub25pY2FsIGJhc2UgdG8gdXNlIGhlcmUuIEV2ZXJ5IGN1cnJlbnQgY2FsbGVyIGRvZXMgdGhpcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVQYXRoV2l0aGluQmFzZShiYXNlRGlyOiBzdHJpbmcsIC4uLnNlZ21lbnRzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmICghYmFzZURpciB8fCB0eXBlb2YgYmFzZURpciAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYXNlIGRpcmVjdG9yeSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICB9XG5cbiAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgaWYgKHR5cGVvZiBzZWdtZW50ICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUGF0aCBzZWdtZW50cyBtdXN0IGJlIHN0cmluZ3MnKTtcbiAgICB9XG4gICAgaWYgKHNlZ21lbnQuaW5jbHVkZXMoJ1xcMCcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhdGggc2VnbWVudCBjb250YWlucyBhIG51bGwgYnl0ZScpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJlc29sdmVkQmFzZSA9IHBhdGgucmVzb2x2ZShiYXNlRGlyKTtcbiAgY29uc3QgcmVzb2x2ZWRUYXJnZXQgPSBwYXRoLnJlc29sdmUocmVzb2x2ZWRCYXNlLCAuLi5zZWdtZW50cyk7XG4gIGNvbnN0IHJlbGF0aXZlUGF0aCA9IHBhdGgucmVsYXRpdmUocmVzb2x2ZWRCYXNlLCByZXNvbHZlZFRhcmdldCk7XG4gIGNvbnN0IGlzVHJhdmVyc2FsID0gcmVsYXRpdmVQYXRoID09PSAnLi4nXG4gICAgfHwgcmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoJy4uJyArIHBhdGguc2VwKVxuICAgIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZVBhdGgpO1xuXG4gIGlmICghaXNUcmF2ZXJzYWwpIHtcbiAgICBhc3NlcnROb3RTeW1saW5rKHJlc29sdmVkQmFzZSwgJ0Jhc2UgZGlyZWN0b3J5IHJlc29sdmVzIHRocm91Z2ggYSBzeW1ib2xpYyBsaW5rJyk7XG4gICAgYXNzZXJ0Tm9TeW1saW5rZWREZXNjZW5kYW50cyhyZXNvbHZlZEJhc2UsIHJlc29sdmVkVGFyZ2V0KTtcbiAgICByZXR1cm4gcmVzb2x2ZWRUYXJnZXQ7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc29sdmVkIHBhdGggZXNjYXBlcyB0aGUgYmFzZSBkaXJlY3RvcnknKTtcbn1cblxuLyoqIFRydWUgd2hlbiBhIGJhc2UtcmVsYXRpdmUgcGF0aCBwb2ludHMgb3V0c2lkZSB0aGUgYmFzZS4gKi9cbmZ1bmN0aW9uIGVzY2FwZXNCYXNlKHJlbGF0aXZlUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiByZWxhdGl2ZVBhdGggPT09ICcuLidcbiAgICB8fCByZWxhdGl2ZVBhdGguc3RhcnRzV2l0aCgnLi4nICsgcGF0aC5zZXApXG4gICAgfHwgcGF0aC5pc0Fic29sdXRlKHJlbGF0aXZlUGF0aCk7XG59XG5cbi8qKlxuICogQ2Fub25pY2FsIChyZWFscGF0aCkgZm9ybSBvZiBhIHBhdGggdGhhdCBtYXkgbm90IGZ1bGx5IGV4aXN0IHlldDogdGhlXG4gKiBkZWVwZXN0IGV4aXN0aW5nIGFuY2VzdG9yIGlzIHJlc29sdmVkIHRocm91Z2ggZXZlcnkgc3ltbGluaywgYW5kIHRoZVxuICogbm90LXlldC1jcmVhdGVkIHN1ZmZpeCBpcyBhcHBlbmRlZCB1bmNoYW5nZWQuIFRoaXMgYW5zd2VycyBcIndoZXJlIHdvdWxkIGFcbiAqIHJlY3Vyc2l2ZSBta2Rpci93cml0ZSBvbiB0aGlzIHBhdGggUkVBTExZIGxhbmQ/XCIg4oCUIHdoaWNoIHBlci1jb21wb25lbnRcbiAqIGxzdGF0IGNoZWNrcyBjYW5ub3QsIGJlY2F1c2UgbHN0YXQgcmVzb2x2ZXMgaW50ZXJtZWRpYXRlIHN5bWxpbmtzIGFuZCBvbmx5XG4gKiByZXBvcnRzIG9uIHRoZSBmaW5hbCBjb21wb25lbnQgKCMyMzQ0KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbm9uaWNhbGl6ZVBhdGgoaW5wdXRQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCByZXNvbHZlZCA9IHBhdGgucmVzb2x2ZShpbnB1dFBhdGgpO1xuICBjb25zdCBtaXNzaW5nOiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgY3VycmVudCA9IHJlc29sdmVkO1xuICBmb3IgKDs7KSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNhbm9uaWNhbCA9IGZzLnJlYWxwYXRoU3luYyhjdXJyZW50KTtcbiAgICAgIHJldHVybiBtaXNzaW5nLmxlbmd0aCA/IHBhdGguam9pbihjYW5vbmljYWwsIC4uLm1pc3NpbmcpIDogY2Fub25pY2FsO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoIWlzTWlzc2luZ1BhdGhFcnJvcihlcnJvcikpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHBhcmVudCA9IHBhdGguZGlybmFtZShjdXJyZW50KTtcbiAgICBpZiAocGFyZW50ID09PSBjdXJyZW50KSB7XG4gICAgICAvLyBOb3RoaW5nIG9uIHRoZSBjaGFpbiBleGlzdHMgKHNob3VsZCBub3QgaGFwcGVuIGZvciBhYnNvbHV0ZSBwYXRocyDigJRcbiAgICAgIC8vIHRoZSByb290IGV4aXN0cyDigJQgYnV0IGtlZXAgYSBsZXhpY2FsIGZhbGxiYWNrIHJhdGhlciB0aGFuIHRocm93aW5nKS5cbiAgICAgIHJldHVybiBtaXNzaW5nLmxlbmd0aCA/IHBhdGguam9pbihjdXJyZW50LCAuLi5taXNzaW5nKSA6IGN1cnJlbnQ7XG4gICAgfVxuICAgIG1pc3NpbmcudW5zaGlmdChwYXRoLmJhc2VuYW1lKGN1cnJlbnQpKTtcbiAgICBjdXJyZW50ID0gcGFyZW50O1xuICB9XG59XG5cbi8qKlxuICogVmV0cyBhIHVzZXItc3VwcGxpZWQgb3V0cHV0IGJhc2UgZm9yIENMSSB3cml0ZXMgYW5kIHJldHVybnMgdGhlIGNhbm9uaWNhbFxuICogcGF0aCBhbGwgc3Vic2VxdWVudCB3cml0ZXMgc2hvdWxkIHVzZSAoIzIzNDQpLlxuICpcbiAqIFR3byByZWdpbWVzLCBzcGxpdCBieSB3aGF0IHRoZSB1c2VyIGxleGljYWxseSBuYW1lZDpcbiAqXG4gKiAgLSBCYXNlIGluc2lkZSB0aGUgYW5jaG9yIChyZWxhdGl2ZSBvdXRwdXRzIGxpa2UgdGhlICcuL2FudGhyb3BpYy1za2lsbHMnXG4gKiAgICBkZWZhdWx0KTogdGhlIGNhbm9uaWNhbCBiYXNlIG11c3Qgc3RheSBpbnNpZGUgdGhlIGNhbm9uaWNhbCBhbmNob3IuXG4gKiAgICBBIHN5bWxpbmsgdGhhdCByZWRpcmVjdHMgaXQgZWxzZXdoZXJlIOKAlCBpbmNsdWRpbmcgb25lIHdob3NlIHRhcmdldFxuICogICAgYWxyZWFkeSBjb250YWlucyBtYXRjaGluZyBzdWJkaXJlY3RvcmllcywgdGhlIGNhc2UgcGVyLWNvbXBvbmVudCBsc3RhdFxuICogICAgY2hlY2tzIG1pc3Mg4oCUIGlzIHJlamVjdGVkLiBDb21wYXJpbmcgaW4gY2Fub25pY2FsIHNwYWNlIG1lYW5zIHN5c3RlbVxuICogICAgbGlua3MgYWJvdmUgdGhlIGFuY2hvciAobWFjT1MgL3RtcCAtPiAvcHJpdmF0ZS90bXApIG5ldmVyIGZhbHNlLXBvc2l0aXZlLlxuICpcbiAqICAtIEJhc2Ugb3V0c2lkZSB0aGUgYW5jaG9yIChleHBsaWNpdCBhYnNvbHV0ZSBvciAuLi8gb3V0cHV0cyk6IHRoZSB1c2VyXG4gKiAgICBuYW1lZCB0aGF0IGRlc3RpbmF0aW9uLCBzbyB0aGVyZSBpcyBubyBib3VuZGFyeSB0byBkZWZlbmQuIEluc3RlYWQgb2ZcbiAqICAgIGd1ZXNzaW5nIGludGVudCwgdGhlIHJlYWwgZGVzdGluYXRpb24gaXMgZGlzY2xvc2VkIHZpYSBgb25EaXNjbG9zZWBcbiAqICAgIHdoZW5ldmVyIGl0IGRpZmZlcnMgZnJvbSB0aGUgbGV4aWNhbCBwYXRoLCBhbmQgdGhlIGNhbm9uaWNhbCBwYXRoIGlzXG4gKiAgICByZXR1cm5lZCBzbyB3aGF0IHdhcyB2ZXR0ZWQgaXMgd2hhdCBnZXRzIHdyaXR0ZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXRPdXRwdXRCYXNlKFxuICBiYXNlRGlyOiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7IGFuY2hvcj86IHN0cmluZzsgb25EaXNjbG9zZT86IChjYW5vbmljYWxCYXNlOiBzdHJpbmcpID0+IHZvaWQgfSxcbik6IHN0cmluZyB7XG4gIGlmICghYmFzZURpciB8fCB0eXBlb2YgYmFzZURpciAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYXNlIGRpcmVjdG9yeSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICB9XG4gIGlmIChiYXNlRGlyLmluY2x1ZGVzKCdcXDAnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGF0aCBzZWdtZW50IGNvbnRhaW5zIGEgbnVsbCBieXRlJyk7XG4gIH1cblxuICBjb25zdCByZXNvbHZlZEFuY2hvciA9IHBhdGgucmVzb2x2ZShvcHRpb25zPy5hbmNob3IgPz8gcHJvY2Vzcy5jd2QoKSk7XG4gIGNvbnN0IHJlc29sdmVkQmFzZSA9IHBhdGgucmVzb2x2ZShiYXNlRGlyKTtcbiAgY29uc3QgY2Fub25pY2FsQmFzZSA9IGNhbm9uaWNhbGl6ZVBhdGgocmVzb2x2ZWRCYXNlKTtcblxuICBpZiAoIWVzY2FwZXNCYXNlKHBhdGgucmVsYXRpdmUocmVzb2x2ZWRBbmNob3IsIHJlc29sdmVkQmFzZSkpKSB7XG4gICAgY29uc3QgY2Fub25pY2FsQW5jaG9yID0gY2Fub25pY2FsaXplUGF0aChyZXNvbHZlZEFuY2hvcik7XG4gICAgaWYgKGVzY2FwZXNCYXNlKHBhdGgucmVsYXRpdmUoY2Fub25pY2FsQW5jaG9yLCBjYW5vbmljYWxCYXNlKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE91dHB1dCBwYXRoIHJlc29sdmVzIG91dHNpZGUgdGhlIHdvcmtpbmcgZGlyZWN0b3J5IHRocm91Z2ggYSBzeW1ib2xpYyBsaW5rIChyZWFsIGRlc3RpbmF0aW9uOiAke2Nhbm9uaWNhbEJhc2V9KWAsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gY2Fub25pY2FsQmFzZTtcbiAgfVxuXG4gIGlmIChjYW5vbmljYWxCYXNlICE9PSByZXNvbHZlZEJhc2UpIHtcbiAgICBvcHRpb25zPy5vbkRpc2Nsb3NlPy4oY2Fub25pY2FsQmFzZSk7XG4gIH1cbiAgcmV0dXJuIGNhbm9uaWNhbEJhc2U7XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dollhousemcp/mcp-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.39",
|
|
4
4
|
"description": "DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/server.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "io.github.DollhouseMCP/mcp-server",
|
|
4
4
|
"title": "DollhouseMCP",
|
|
5
5
|
"description": "OSS to create Personas, Skills, Templates, Agents, and Memories to customize your AI experience.",
|
|
6
|
-
"version": "2.0.
|
|
6
|
+
"version": "2.0.39",
|
|
7
7
|
"homepage": "https://dollhousemcp.com",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
{
|
|
30
30
|
"registryType": "npm",
|
|
31
31
|
"identifier": "@dollhousemcp/mcp-server",
|
|
32
|
-
"version": "2.0.
|
|
32
|
+
"version": "2.0.39",
|
|
33
33
|
"transport": {
|
|
34
34
|
"type": "stdio"
|
|
35
35
|
}
|