@paretools/shared 0.3.0 → 0.6.0
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/README.md +6 -3
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +20 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +20 -0
- package/dist/limits.js.map +1 -0
- package/dist/output.d.ts +20 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +33 -0
- package/dist/output.js.map +1 -1
- package/dist/runner.d.ts +20 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +46 -3
- package/dist/runner.js.map +1 -1
- package/dist/sanitize.d.ts +13 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +23 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/validation.d.ts +13 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +20 -1
- package/dist/validation.js.map +1 -1
- package/package.json +13 -8
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# @paretools/shared
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@paretools/shared)
|
|
4
|
+
[](https://github.com/Dave-London/Pare/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
Shared utilities for [Pare](https://github.com/Dave-London/Pare) MCP servers.
|
|
4
7
|
|
|
5
8
|
## Exports
|
|
6
9
|
|
|
@@ -18,8 +21,8 @@ import { run, dualOutput, stripAnsi } from "@paretools/shared";
|
|
|
18
21
|
|
|
19
22
|
## Links
|
|
20
23
|
|
|
21
|
-
- [Pare monorepo](https://github.com/Dave-London/
|
|
24
|
+
- [Pare monorepo](https://github.com/Dave-London/Pare)
|
|
22
25
|
|
|
23
26
|
## License
|
|
24
27
|
|
|
25
|
-
[MIT](https://github.com/Dave-London/
|
|
28
|
+
[MIT](https://github.com/Dave-London/Pare/blob/main/LICENSE)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
export { dualOutput } from "./output.js";
|
|
2
|
-
export { run, type RunResult, type RunOptions } from "./runner.js";
|
|
1
|
+
export { dualOutput, estimateTokens, compactDualOutput } from "./output.js";
|
|
2
|
+
export { run, escapeCmdArg, type RunResult, type RunOptions } from "./runner.js";
|
|
3
3
|
export { stripAnsi } from "./ansi.js";
|
|
4
4
|
export { assertNoFlagInjection, assertAllowedCommand } from "./validation.js";
|
|
5
|
+
export { INPUT_LIMITS } from "./limits.js";
|
|
6
|
+
export { sanitizeErrorOutput } from "./sanitize.js";
|
|
5
7
|
export type { ToolOutput } from "./types.js";
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { dualOutput } from "./output.js";
|
|
2
|
-
export { run } from "./runner.js";
|
|
1
|
+
export { dualOutput, estimateTokens, compactDualOutput } from "./output.js";
|
|
2
|
+
export { run, escapeCmdArg } from "./runner.js";
|
|
3
3
|
export { stripAnsi } from "./ansi.js";
|
|
4
4
|
export { assertNoFlagInjection, assertAllowedCommand } from "./validation.js";
|
|
5
|
+
export { INPUT_LIMITS } from "./limits.js";
|
|
6
|
+
export { sanitizeErrorOutput } from "./sanitize.js";
|
|
5
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,GAAG,EAAE,YAAY,EAAmC,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/limits.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared input-validation limits for all Pare MCP servers.
|
|
3
|
+
*
|
|
4
|
+
* These provide defense-in-depth against DoS via extremely long inputs.
|
|
5
|
+
* Applied to Zod input schemas with `.max()` — output schemas are NOT
|
|
6
|
+
* constrained because their size is determined by tool output, not user input.
|
|
7
|
+
*/
|
|
8
|
+
export declare const INPUT_LIMITS: {
|
|
9
|
+
/** Maximum length for any general string parameter (64 KB). */
|
|
10
|
+
readonly STRING_MAX: 65536;
|
|
11
|
+
/** Maximum items in any array parameter. */
|
|
12
|
+
readonly ARRAY_MAX: 1000;
|
|
13
|
+
/** Maximum length for file system paths. */
|
|
14
|
+
readonly PATH_MAX: 4096;
|
|
15
|
+
/** Maximum length for commit messages (generous to allow long messages). */
|
|
16
|
+
readonly MESSAGE_MAX: 72000;
|
|
17
|
+
/** Maximum length for short identifiers (branch names, package names, etc.). */
|
|
18
|
+
readonly SHORT_STRING_MAX: 255;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,YAAY;IACvB,+DAA+D;;IAG/D,4CAA4C;;IAG5C,4CAA4C;;IAG5C,4EAA4E;;IAG5E,gFAAgF;;CAExE,CAAC"}
|
package/dist/limits.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared input-validation limits for all Pare MCP servers.
|
|
3
|
+
*
|
|
4
|
+
* These provide defense-in-depth against DoS via extremely long inputs.
|
|
5
|
+
* Applied to Zod input schemas with `.max()` — output schemas are NOT
|
|
6
|
+
* constrained because their size is determined by tool output, not user input.
|
|
7
|
+
*/
|
|
8
|
+
export const INPUT_LIMITS = {
|
|
9
|
+
/** Maximum length for any general string parameter (64 KB). */
|
|
10
|
+
STRING_MAX: 65_536,
|
|
11
|
+
/** Maximum items in any array parameter. */
|
|
12
|
+
ARRAY_MAX: 1_000,
|
|
13
|
+
/** Maximum length for file system paths. */
|
|
14
|
+
PATH_MAX: 4_096,
|
|
15
|
+
/** Maximum length for commit messages (generous to allow long messages). */
|
|
16
|
+
MESSAGE_MAX: 72_000,
|
|
17
|
+
/** Maximum length for short identifiers (branch names, package names, etc.). */
|
|
18
|
+
SHORT_STRING_MAX: 255,
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,+DAA+D;IAC/D,UAAU,EAAE,MAAM;IAElB,4CAA4C;IAC5C,SAAS,EAAE,KAAK;IAEhB,4CAA4C;IAC5C,QAAQ,EAAE,KAAK;IAEf,4EAA4E;IAC5E,WAAW,EAAE,MAAM;IAEnB,gFAAgF;IAChF,gBAAgB,EAAE,GAAG;CACb,CAAC"}
|
package/dist/output.d.ts
CHANGED
|
@@ -9,4 +9,24 @@ import type { ToolOutput } from "./types.js";
|
|
|
9
9
|
* @param humanFormat - A function that formats `data` as human-readable text.
|
|
10
10
|
*/
|
|
11
11
|
export declare function dualOutput<T>(data: T, humanFormat: (d: T) => string): ToolOutput<T>;
|
|
12
|
+
/**
|
|
13
|
+
* Estimates the token count of a string using the ~4 chars/token heuristic.
|
|
14
|
+
*/
|
|
15
|
+
export declare function estimateTokens(text: string): number;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a dual-output response with automatic compact mode.
|
|
18
|
+
*
|
|
19
|
+
* Compares the token cost of the full structured JSON against the raw CLI stdout.
|
|
20
|
+
* When the structured output would use more tokens than raw, applies a compact
|
|
21
|
+
* projection to reduce the schema. Setting `forceFullSchema` to true always
|
|
22
|
+
* returns the full (non-compact) data.
|
|
23
|
+
*
|
|
24
|
+
* @param data - The full structured data parsed from CLI output.
|
|
25
|
+
* @param rawStdout - The ANSI-stripped stdout from the CLI command.
|
|
26
|
+
* @param humanFormat - Formatter for full data (used when not compacting).
|
|
27
|
+
* @param compactMap - Projects full data into a compact shape.
|
|
28
|
+
* @param compactFormat - Formatter for compact data.
|
|
29
|
+
* @param forceFullSchema - When true, skip auto-detection and return full data.
|
|
30
|
+
*/
|
|
31
|
+
export declare function compactDualOutput<T, C>(data: T, rawStdout: string, humanFormat: (d: T) => string, compactMap: (d: T) => C, compactFormat: (d: C) => string, forceFullSchema: boolean): ToolOutput<T | C>;
|
|
12
32
|
//# sourceMappingURL=output.d.ts.map
|
package/dist/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAKnF"}
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAKnF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EACpC,IAAI,EAAE,CAAC,EACP,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAC7B,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACvB,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAC/B,eAAe,EAAE,OAAO,GACvB,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAcnB"}
|
package/dist/output.js
CHANGED
|
@@ -13,4 +13,37 @@ export function dualOutput(data, humanFormat) {
|
|
|
13
13
|
structuredContent: data,
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Estimates the token count of a string using the ~4 chars/token heuristic.
|
|
18
|
+
*/
|
|
19
|
+
export function estimateTokens(text) {
|
|
20
|
+
return Math.ceil(text.length / 4);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a dual-output response with automatic compact mode.
|
|
24
|
+
*
|
|
25
|
+
* Compares the token cost of the full structured JSON against the raw CLI stdout.
|
|
26
|
+
* When the structured output would use more tokens than raw, applies a compact
|
|
27
|
+
* projection to reduce the schema. Setting `forceFullSchema` to true always
|
|
28
|
+
* returns the full (non-compact) data.
|
|
29
|
+
*
|
|
30
|
+
* @param data - The full structured data parsed from CLI output.
|
|
31
|
+
* @param rawStdout - The ANSI-stripped stdout from the CLI command.
|
|
32
|
+
* @param humanFormat - Formatter for full data (used when not compacting).
|
|
33
|
+
* @param compactMap - Projects full data into a compact shape.
|
|
34
|
+
* @param compactFormat - Formatter for compact data.
|
|
35
|
+
* @param forceFullSchema - When true, skip auto-detection and return full data.
|
|
36
|
+
*/
|
|
37
|
+
export function compactDualOutput(data, rawStdout, humanFormat, compactMap, compactFormat, forceFullSchema) {
|
|
38
|
+
if (forceFullSchema) {
|
|
39
|
+
return dualOutput(data, humanFormat);
|
|
40
|
+
}
|
|
41
|
+
const structuredTokens = estimateTokens(JSON.stringify(data));
|
|
42
|
+
const rawTokens = estimateTokens(rawStdout);
|
|
43
|
+
if (structuredTokens >= rawTokens) {
|
|
44
|
+
const compact = compactMap(data);
|
|
45
|
+
return dualOutput(compact, compactFormat);
|
|
46
|
+
}
|
|
47
|
+
return dualOutput(data, humanFormat);
|
|
48
|
+
}
|
|
16
49
|
//# sourceMappingURL=output.js.map
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAI,IAAO,EAAE,WAA6B;IAClE,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,iBAAiB,EAAE,IAAI;KACxB,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAI,IAAO,EAAE,WAA6B;IAClE,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,iBAAiB,EAAE,IAAI;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAO,EACP,SAAiB,EACjB,WAA6B,EAC7B,UAAuB,EACvB,aAA+B,EAC/B,eAAwB;IAExB,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,UAAU,CAAC,IAAI,EAAE,WAAW,CAAsB,CAAC;IAC5D,CAAC;IAED,MAAM,gBAAgB,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAE5C,IAAI,gBAAgB,IAAI,SAAS,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QACjC,OAAO,UAAU,CAAC,OAAO,EAAE,aAAa,CAAsB,CAAC;IACjE,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,EAAE,WAAW,CAAsB,CAAC;AAC5D,CAAC"}
|
package/dist/runner.d.ts
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
|
+
/** Options for the command runner, including working directory, timeout, and environment overrides. */
|
|
1
2
|
export interface RunOptions {
|
|
2
3
|
cwd?: string;
|
|
3
4
|
timeout?: number;
|
|
4
5
|
env?: Record<string, string>;
|
|
5
6
|
}
|
|
7
|
+
/** Result of a command execution, containing the exit code and ANSI-stripped stdout/stderr. */
|
|
6
8
|
export interface RunResult {
|
|
7
9
|
exitCode: number;
|
|
8
10
|
stdout: string;
|
|
9
11
|
stderr: string;
|
|
10
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Escapes a single argument for safe use with cmd.exe on Windows.
|
|
15
|
+
*
|
|
16
|
+
* When `shell: true` is used with `execFile` on Windows, Node.js wraps each
|
|
17
|
+
* argument in double quotes. Inside double quotes cmd.exe still interprets:
|
|
18
|
+
* - `%VAR%` for environment variable expansion
|
|
19
|
+
* - `^` as the escape character itself
|
|
20
|
+
* - `&`, `|`, `<`, `>` as pipeline / redirection operators
|
|
21
|
+
*
|
|
22
|
+
* We neutralise these by:
|
|
23
|
+
* 1. Replacing `%` with `%%` (disables env-var expansion inside quotes).
|
|
24
|
+
* 2. Prefixing `^`, `&`, `|`, `<`, `>`, `!` with the cmd.exe escape char `^`.
|
|
25
|
+
* (`!` must be escaped to prevent delayed expansion of `!VAR!`.)
|
|
26
|
+
*
|
|
27
|
+
* Parentheses `(` `)` are NOT escaped here because inside double-quoted
|
|
28
|
+
* strings they are literal characters and do not affect grouping.
|
|
29
|
+
*/
|
|
30
|
+
export declare function escapeCmdArg(arg: string): string;
|
|
11
31
|
/**
|
|
12
32
|
* Executes a command and returns cleaned output with ANSI codes stripped.
|
|
13
33
|
* Uses execFile (not exec) to avoid shell injection. On Windows, shell is
|
package/dist/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAIA,uGAAuG;AACvG,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,+FAA+F;AAC/F,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBhD;AAED;;;;;;;;GAQG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAkEtF"}
|
package/dist/runner.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import { stripAnsi } from "./ansi.js";
|
|
3
|
+
import { sanitizeErrorOutput } from "./sanitize.js";
|
|
4
|
+
/**
|
|
5
|
+
* Escapes a single argument for safe use with cmd.exe on Windows.
|
|
6
|
+
*
|
|
7
|
+
* When `shell: true` is used with `execFile` on Windows, Node.js wraps each
|
|
8
|
+
* argument in double quotes. Inside double quotes cmd.exe still interprets:
|
|
9
|
+
* - `%VAR%` for environment variable expansion
|
|
10
|
+
* - `^` as the escape character itself
|
|
11
|
+
* - `&`, `|`, `<`, `>` as pipeline / redirection operators
|
|
12
|
+
*
|
|
13
|
+
* We neutralise these by:
|
|
14
|
+
* 1. Replacing `%` with `%%` (disables env-var expansion inside quotes).
|
|
15
|
+
* 2. Prefixing `^`, `&`, `|`, `<`, `>`, `!` with the cmd.exe escape char `^`.
|
|
16
|
+
* (`!` must be escaped to prevent delayed expansion of `!VAR!`.)
|
|
17
|
+
*
|
|
18
|
+
* Parentheses `(` `)` are NOT escaped here because inside double-quoted
|
|
19
|
+
* strings they are literal characters and do not affect grouping.
|
|
20
|
+
*/
|
|
21
|
+
export function escapeCmdArg(arg) {
|
|
22
|
+
// Step 1: Escape % → %% to prevent %VAR% expansion
|
|
23
|
+
let escaped = arg.replace(/%/g, "%%");
|
|
24
|
+
// Step 2: Caret-escape cmd.exe metacharacters that are dangerous
|
|
25
|
+
// even inside double quotes. The caret itself must be escaped first
|
|
26
|
+
// so that carets we insert are not themselves re-escaped.
|
|
27
|
+
escaped = escaped.replace(/\^/g, "^^");
|
|
28
|
+
escaped = escaped.replace(/&/g, "^&");
|
|
29
|
+
escaped = escaped.replace(/\|/g, "^|");
|
|
30
|
+
escaped = escaped.replace(/</g, "^<");
|
|
31
|
+
escaped = escaped.replace(/>/g, "^>");
|
|
32
|
+
// Step 3: Escape ! to prevent delayed expansion (!VAR!)
|
|
33
|
+
escaped = escaped.replace(/!/g, "^!");
|
|
34
|
+
return escaped;
|
|
35
|
+
}
|
|
3
36
|
/**
|
|
4
37
|
* Executes a command and returns cleaned output with ANSI codes stripped.
|
|
5
38
|
* Uses execFile (not exec) to avoid shell injection. On Windows, shell is
|
|
@@ -11,9 +44,13 @@ import { stripAnsi } from "./ansi.js";
|
|
|
11
44
|
*/
|
|
12
45
|
export function run(cmd, args, opts) {
|
|
13
46
|
return new Promise((resolve, reject) => {
|
|
14
|
-
|
|
47
|
+
// On Windows with shell mode, escape cmd.exe metacharacters to prevent
|
|
48
|
+
// environment variable expansion and command injection via special chars.
|
|
49
|
+
// See escapeCmdArg() for details on what is escaped and why.
|
|
50
|
+
const safeArgs = process.platform === "win32" ? args.map(escapeCmdArg) : args;
|
|
51
|
+
execFile(cmd, safeArgs, {
|
|
15
52
|
cwd: opts?.cwd,
|
|
16
|
-
timeout: opts?.timeout ??
|
|
53
|
+
timeout: opts?.timeout ?? 60_000,
|
|
17
54
|
env: opts?.env ? { ...process.env, ...opts.env } : undefined,
|
|
18
55
|
maxBuffer: 10 * 1024 * 1024, // 10 MB
|
|
19
56
|
shell: process.platform === "win32",
|
|
@@ -29,6 +66,12 @@ export function run(cmd, args, opts) {
|
|
|
29
66
|
reject(new Error(`Permission denied executing "${cmd}": ${errno.message}`));
|
|
30
67
|
return;
|
|
31
68
|
}
|
|
69
|
+
// Timeout: execFile killed the child after the configured timeout.
|
|
70
|
+
// Surface this clearly instead of silently returning exitCode 1.
|
|
71
|
+
if (error.killed && error.signal) {
|
|
72
|
+
reject(new Error(`Command "${cmd}" timed out after ${opts?.timeout ?? 60_000}ms and was killed (${error.signal}).`));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
32
75
|
// Windows: cmd.exe masks ENOENT — detect via stderr message
|
|
33
76
|
const cleanStderr = stripAnsi(stderr);
|
|
34
77
|
if (cleanStderr.includes("is not recognized")) {
|
|
@@ -39,7 +82,7 @@ export function run(cmd, args, opts) {
|
|
|
39
82
|
resolve({
|
|
40
83
|
exitCode: error ? (typeof error.code === "number" ? error.code : 1) : 0,
|
|
41
84
|
stdout: stripAnsi(stdout),
|
|
42
|
-
stderr: stripAnsi(stderr),
|
|
85
|
+
stderr: sanitizeErrorOutput(stripAnsi(stderr)),
|
|
43
86
|
});
|
|
44
87
|
});
|
|
45
88
|
});
|
package/dist/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes error output by replacing sensitive filesystem paths with
|
|
3
|
+
* home-relative equivalents. This prevents leaking usernames and absolute
|
|
4
|
+
* home directory paths in error messages returned to MCP clients.
|
|
5
|
+
*
|
|
6
|
+
* Replacements:
|
|
7
|
+
* /home/<user>/... → ~/...
|
|
8
|
+
* /Users/<user>/... → ~/...
|
|
9
|
+
* /root/... → ~/...
|
|
10
|
+
* C:\Users\<user>\... → ~\...
|
|
11
|
+
*/
|
|
12
|
+
export declare function sanitizeErrorOutput(text: string): string;
|
|
13
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcxD"}
|
package/dist/sanitize.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes error output by replacing sensitive filesystem paths with
|
|
3
|
+
* home-relative equivalents. This prevents leaking usernames and absolute
|
|
4
|
+
* home directory paths in error messages returned to MCP clients.
|
|
5
|
+
*
|
|
6
|
+
* Replacements:
|
|
7
|
+
* /home/<user>/... → ~/...
|
|
8
|
+
* /Users/<user>/... → ~/...
|
|
9
|
+
* /root/... → ~/...
|
|
10
|
+
* C:\Users\<user>\... → ~\...
|
|
11
|
+
*/
|
|
12
|
+
export function sanitizeErrorOutput(text) {
|
|
13
|
+
// Unix: /home/<username>/rest → ~/rest
|
|
14
|
+
let result = text.replace(/\/home\/[^/\s]+\//g, "~/");
|
|
15
|
+
// macOS: /Users/<username>/rest → ~/rest
|
|
16
|
+
result = result.replace(/\/Users\/[^/\s]+\//g, "~/");
|
|
17
|
+
// Unix: /root/rest → ~/rest
|
|
18
|
+
result = result.replace(/\/root\//g, "~/");
|
|
19
|
+
// Windows: C:\Users\<username>\rest → ~\rest (with escaped or literal backslashes)
|
|
20
|
+
result = result.replace(/[A-Z]:\\Users\\[^\\:\s]+\\/gi, "~\\");
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,uCAAuC;IACvC,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;IAEtD,yCAAyC;IACzC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;IAErD,4BAA4B;IAC5B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAE3C,mFAAmF;IACnF,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;IAE/D,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/validation.d.ts
CHANGED
|
@@ -4,5 +4,18 @@
|
|
|
4
4
|
* See: CVE-2025-68144, CVE-2025-68145
|
|
5
5
|
*/
|
|
6
6
|
export declare function assertNoFlagInjection(value: string, paramName: string): void;
|
|
7
|
+
/**
|
|
8
|
+
* Validates that a command is in the allowlist of safe build tools to prevent arbitrary command execution.
|
|
9
|
+
*
|
|
10
|
+
* Known limitation: only the basename is checked, so a path like `/tmp/evil/npm` would pass.
|
|
11
|
+
* Rejecting paths entirely would break legitimate use cases (NixOS store paths, `C:\Program Files\...`,
|
|
12
|
+
* non-PATH installs). Exploiting this requires placing a malicious binary on disk, which already
|
|
13
|
+
* implies the system is compromised.
|
|
14
|
+
*
|
|
15
|
+
* Security note: When a full path is provided (containing `/` or `\`), a warning is logged because
|
|
16
|
+
* basename-only validation cannot guarantee the binary at that path is the genuine tool. An attacker
|
|
17
|
+
* with write access to the filesystem could place a malicious binary at a path like `/tmp/evil/npm`.
|
|
18
|
+
* The warning serves as an audit trail for security-conscious deployments.
|
|
19
|
+
*/
|
|
7
20
|
export declare function assertAllowedCommand(command: string): void;
|
|
8
21
|
//# sourceMappingURL=validation.d.ts.map
|
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAM5E;AAiCD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAM5E;AAiCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAwB1D"}
|
package/dist/validation.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* See: CVE-2025-68144, CVE-2025-68145
|
|
5
5
|
*/
|
|
6
6
|
export function assertNoFlagInjection(value, paramName) {
|
|
7
|
-
if (value.startsWith("-")) {
|
|
7
|
+
if (value.trimStart().startsWith("-")) {
|
|
8
8
|
throw new Error(`Invalid ${paramName}: "${value}". Values must not start with "-" to prevent argument injection.`);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
@@ -38,6 +38,19 @@ const ALLOWED_BUILD_COMMANDS = new Set([
|
|
|
38
38
|
"nx",
|
|
39
39
|
"bazel",
|
|
40
40
|
]);
|
|
41
|
+
/**
|
|
42
|
+
* Validates that a command is in the allowlist of safe build tools to prevent arbitrary command execution.
|
|
43
|
+
*
|
|
44
|
+
* Known limitation: only the basename is checked, so a path like `/tmp/evil/npm` would pass.
|
|
45
|
+
* Rejecting paths entirely would break legitimate use cases (NixOS store paths, `C:\Program Files\...`,
|
|
46
|
+
* non-PATH installs). Exploiting this requires placing a malicious binary on disk, which already
|
|
47
|
+
* implies the system is compromised.
|
|
48
|
+
*
|
|
49
|
+
* Security note: When a full path is provided (containing `/` or `\`), a warning is logged because
|
|
50
|
+
* basename-only validation cannot guarantee the binary at that path is the genuine tool. An attacker
|
|
51
|
+
* with write access to the filesystem could place a malicious binary at a path like `/tmp/evil/npm`.
|
|
52
|
+
* The warning serves as an audit trail for security-conscious deployments.
|
|
53
|
+
*/
|
|
41
54
|
export function assertAllowedCommand(command) {
|
|
42
55
|
// Extract the base command name (handle paths like /usr/bin/npm or C:\npm.cmd)
|
|
43
56
|
const base = command
|
|
@@ -49,5 +62,11 @@ export function assertAllowedCommand(command) {
|
|
|
49
62
|
throw new Error(`Command "${command}" is not in the allowed build commands list. ` +
|
|
50
63
|
`Allowed: ${[...ALLOWED_BUILD_COMMANDS].sort().join(", ")}`);
|
|
51
64
|
}
|
|
65
|
+
// Warn when a full path is used — basename-only validation cannot verify the actual binary
|
|
66
|
+
if (command.includes("/") || command.includes("\\")) {
|
|
67
|
+
console.warn(`[pare:security] Command uses a full path: "${command}". ` +
|
|
68
|
+
`Only the basename "${base}" was validated against the allowlist. ` +
|
|
69
|
+
`Ensure this path points to a trusted binary.`);
|
|
70
|
+
}
|
|
52
71
|
}
|
|
53
72
|
//# sourceMappingURL=validation.js.map
|
package/dist/validation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,SAAiB;IACpE,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,SAAiB;IACpE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,WAAW,SAAS,MAAM,KAAK,kEAAkE,CAClG,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACrC,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,KAAK;IACL,KAAK;IACL,OAAO;IACP,IAAI;IACJ,QAAQ;IACR,SAAS;IACT,KAAK;IACL,SAAS;IACT,MAAM;IACN,SAAS;IACT,QAAQ;IACR,OAAO;IACP,IAAI;IACJ,OAAO;CACR,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,+EAA+E;IAC/E,MAAM,IAAI,GACR,OAAO;SACJ,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,EAAE;QACN,EAAE,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAEhD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CACb,YAAY,OAAO,+CAA+C;YAChE,YAAY,CAAC,GAAG,sBAAsB,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9D,CAAC;IACJ,CAAC;IAED,2FAA2F;IAC3F,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,IAAI,CACV,8CAA8C,OAAO,KAAK;YACxD,sBAAsB,IAAI,yCAAyC;YACnE,8CAA8C,CACjD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paretools/shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Shared utilities for Pare MCP servers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
8
8
|
"mcp-server",
|
|
9
9
|
"model-context-protocol",
|
|
10
|
-
"structured-output"
|
|
10
|
+
"structured-output",
|
|
11
|
+
"ai",
|
|
12
|
+
"ai-agent",
|
|
13
|
+
"token-efficient",
|
|
14
|
+
"devtools",
|
|
15
|
+
"cli"
|
|
11
16
|
],
|
|
12
|
-
"homepage": "https://github.com/Dave-London/
|
|
17
|
+
"homepage": "https://github.com/Dave-London/Pare/tree/main/packages/shared",
|
|
13
18
|
"engines": {
|
|
14
|
-
"node": ">=
|
|
19
|
+
"node": ">=20"
|
|
15
20
|
},
|
|
16
21
|
"type": "module",
|
|
17
22
|
"exports": {
|
|
@@ -25,7 +30,7 @@
|
|
|
25
30
|
},
|
|
26
31
|
"repository": {
|
|
27
32
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/Dave-London/
|
|
33
|
+
"url": "https://github.com/Dave-London/Pare.git",
|
|
29
34
|
"directory": "packages/shared"
|
|
30
35
|
},
|
|
31
36
|
"files": [
|
|
@@ -33,12 +38,12 @@
|
|
|
33
38
|
],
|
|
34
39
|
"dependencies": {
|
|
35
40
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
36
|
-
"zod": "^3.
|
|
41
|
+
"zod": "^4.3.6"
|
|
37
42
|
},
|
|
38
43
|
"devDependencies": {
|
|
39
|
-
"@types/node": "^
|
|
44
|
+
"@types/node": "^25.2.3",
|
|
40
45
|
"typescript": "^5.7.0",
|
|
41
|
-
"vitest": "^
|
|
46
|
+
"vitest": "^4.0.18",
|
|
42
47
|
"@paretools/tsconfig": "0.0.0"
|
|
43
48
|
},
|
|
44
49
|
"scripts": {
|