@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.
@@ -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.37";
6
- export declare const BUILD_TIMESTAMP = "2026-07-04T17:06:33.872Z";
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.37';
6
- export const BUILD_TIMESTAMP = '2026-07-04T17:06:33.872Z';
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZW5lcmF0ZWQvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDO0FBQ3hDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUMxRCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQWtCLEtBQUssQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsMEJBQTBCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEF1dG8tZ2VuZXJhdGVkIGZpbGUgLSBETyBOT1QgRURJVFxuICogR2VuZXJhdGVkIGF0IGJ1aWxkIHRpbWUgYnkgc2NyaXB0cy9nZW5lcmF0ZS12ZXJzaW9uLmpzXG4gKi9cblxuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9ICcyLjAuMzcnO1xuZXhwb3J0IGNvbnN0IEJVSUxEX1RJTUVTVEFNUCA9ICcyMDI2LTA3LTA0VDE3OjA2OjMzLjg3MlonO1xuZXhwb3J0IGNvbnN0IEJVSUxEX1RZUEU6ICducG0nIHwgJ2dpdCcgPSAnbnBtJztcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSAnQGRvbGxob3VzZW1jcC9tY3Atc2VydmVyJztcbiJdfQ==
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":"AAqCA;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CA4BpF"}
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
- const stats = fs.lstatSync(pathToCheck);
6
- if (stats.isSymbolicLink()) {
7
- throw new Error(message);
8
- }
44
+ stats = fs.lstatSync(pathToCheck);
9
45
  }
10
46
  catch (error) {
11
- const code = typeof error === 'object' && error !== null && 'code' in error
12
- ? error.code
13
- : undefined;
14
- if (code === 'ENOENT' || code === 'ENOTDIR') {
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
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aFNlY3VyaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3BhdGhTZWN1cml0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUVsQyxTQUFTLGdCQUFnQixDQUFDLFdBQW1CLEVBQUUsT0FBZTtJQUM1RCxJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksR0FBRyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxNQUFNLElBQUksS0FBSztZQUN6RSxDQUFDLENBQUUsS0FBK0IsQ0FBQyxJQUFJO1lBQ3ZDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDZCxJQUFJLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVDLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsNEJBQTRCLENBQUMsWUFBb0IsRUFBRSxjQUFzQjtJQUNoRixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQztJQUNqRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEIsT0FBTztJQUNULENBQUM7SUFFRCxJQUFJLFdBQVcsR0FBRyxZQUFZLENBQUM7SUFDL0IsS0FBSyxNQUFNLE9BQU8sSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ25ELElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLFNBQVM7UUFDWCxDQUFDO1FBRUQsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSwrQ0FBK0MsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQixDQUFDLE9BQWUsRUFBRSxHQUFHLFFBQWtCO0lBQzFFLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDNUMsTUFBTSxJQUFJLFNBQVMsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRCxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQy9CLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLFNBQVMsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDdkQsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzNDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsUUFBUSxDQUFDLENBQUM7SUFDL0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDakUsTUFBTSxXQUFXLEdBQUcsWUFBWSxLQUFLLElBQUk7V0FDcEMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztXQUN4QyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRW5DLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQixnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsaURBQWlELENBQUMsQ0FBQztRQUNsRiw0QkFBNEIsQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDM0QsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztBQUM5RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmZ1bmN0aW9uIGFzc2VydE5vdFN5bWxpbmsocGF0aFRvQ2hlY2s6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc3RhdHMgPSBmcy5sc3RhdFN5bmMocGF0aFRvQ2hlY2spO1xuICAgIGlmIChzdGF0cy5pc1N5bWJvbGljTGluaygpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGNvZGUgPSB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmIGVycm9yICE9PSBudWxsICYmICdjb2RlJyBpbiBlcnJvclxuICAgICAgPyAoZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBpZiAoY29kZSA9PT0gJ0VOT0VOVCcgfHwgY29kZSA9PT0gJ0VOT1RESVInKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydE5vU3ltbGlua2VkRGVzY2VuZGFudHMocmVzb2x2ZWRCYXNlOiBzdHJpbmcsIHJlc29sdmVkVGFyZ2V0OiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZShyZXNvbHZlZEJhc2UsIHJlc29sdmVkVGFyZ2V0KTtcbiAgaWYgKCFyZWxhdGl2ZVBhdGgpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBsZXQgY3VycmVudFBhdGggPSByZXNvbHZlZEJhc2U7XG4gIGZvciAoY29uc3Qgc2VnbWVudCBvZiByZWxhdGl2ZVBhdGguc3BsaXQocGF0aC5zZXApKSB7XG4gICAgaWYgKCFzZWdtZW50KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjdXJyZW50UGF0aCA9IHBhdGguam9pbihjdXJyZW50UGF0aCwgc2VnbWVudCk7XG4gICAgYXNzZXJ0Tm90U3ltbGluayhjdXJyZW50UGF0aCwgJ1BhdGggc2VnbWVudCByZXNvbHZlcyB0aHJvdWdoIGEgc3ltYm9saWMgbGluaycpO1xuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHRhcmdldCBwYXRoIGFuZCB2ZXJpZnkgdGhhdCBpdCByZW1haW5zIGluc2lkZSB0aGUgaW50ZW5kZWQgYmFzZVxuICogZGlyZWN0b3J5LiBUaGlzIGlzIHNlcGFyYXRvci1hd2FyZSwgc28gc2libGluZyBwYXRocyBzdWNoIGFzIGAvdG1wL2Jhc2UyYFxuICogYXJlIG5vdCB0cmVhdGVkIGFzIGNoaWxkcmVuIG9mIGAvdG1wL2Jhc2VgLiBFeGlzdGluZyBzeW1saW5rZWQgYmFzZSBwYXRoc1xuICogYW5kIHN5bWxpbmtlZCBkZXNjZW5kYW50cyB1bmRlciB0aGUgYmFzZSBhcmUgcmVqZWN0ZWQgYmVjYXVzZSB3cml0ZXMgd291bGRcbiAqIGZvbGxvdyB0aGVtIG91dHNpZGUgdGhlIGxleGljYWwgY29udGFpbm1lbnQgYm91bmRhcnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUGF0aFdpdGhpbkJhc2UoYmFzZURpcjogc3RyaW5nLCAuLi5zZWdtZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICBpZiAoIWJhc2VEaXIgfHwgdHlwZW9mIGJhc2VEaXIgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQmFzZSBkaXJlY3RvcnkgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnKTtcbiAgfVxuXG4gIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykge1xuICAgIGlmICh0eXBlb2Ygc2VnbWVudCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1BhdGggc2VnbWVudHMgbXVzdCBiZSBzdHJpbmdzJyk7XG4gICAgfVxuICAgIGlmIChzZWdtZW50LmluY2x1ZGVzKCdcXDAnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXRoIHNlZ21lbnQgY29udGFpbnMgYSBudWxsIGJ5dGUnKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCByZXNvbHZlZEJhc2UgPSBwYXRoLnJlc29sdmUoYmFzZURpcik7XG4gIGNvbnN0IHJlc29sdmVkVGFyZ2V0ID0gcGF0aC5yZXNvbHZlKHJlc29sdmVkQmFzZSwgLi4uc2VnbWVudHMpO1xuICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHJlc29sdmVkQmFzZSwgcmVzb2x2ZWRUYXJnZXQpO1xuICBjb25zdCBpc1RyYXZlcnNhbCA9IHJlbGF0aXZlUGF0aCA9PT0gJy4uJ1xuICAgIHx8IHJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKCcuLicgKyBwYXRoLnNlcClcbiAgICB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmVQYXRoKTtcblxuICBpZiAoIWlzVHJhdmVyc2FsKSB7XG4gICAgYXNzZXJ0Tm90U3ltbGluayhyZXNvbHZlZEJhc2UsICdCYXNlIGRpcmVjdG9yeSByZXNvbHZlcyB0aHJvdWdoIGEgc3ltYm9saWMgbGluaycpO1xuICAgIGFzc2VydE5vU3ltbGlua2VkRGVzY2VuZGFudHMocmVzb2x2ZWRCYXNlLCByZXNvbHZlZFRhcmdldCk7XG4gICAgcmV0dXJuIHJlc29sdmVkVGFyZ2V0O1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdSZXNvbHZlZCBwYXRoIGVzY2FwZXMgdGhlIGJhc2UgZGlyZWN0b3J5Jyk7XG59XG4iXX0=
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.37",
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.37",
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.37",
32
+ "version": "2.0.39",
33
33
  "transport": {
34
34
  "type": "stdio"
35
35
  }