tracelattice 1.3.3 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/ServerConfig.d.ts +14 -0
  2. package/dist/ServerConfig.d.ts.map +1 -1
  3. package/dist/ServerConfig.js +12 -1
  4. package/dist/ServerConfig.js.map +1 -1
  5. package/dist/__tests__/core/HistoryManager.ownership.test.d.ts +2 -0
  6. package/dist/__tests__/core/HistoryManager.ownership.test.d.ts.map +1 -0
  7. package/dist/__tests__/core/SessionLock.test.d.ts +6 -0
  8. package/dist/__tests__/core/SessionLock.test.d.ts.map +1 -0
  9. package/dist/__tests__/core/SessionManager.test.d.ts +8 -0
  10. package/dist/__tests__/core/SessionManager.test.d.ts.map +1 -0
  11. package/dist/__tests__/core/ThoughtProcessor.toolAllowlist.test.d.ts +2 -0
  12. package/dist/__tests__/core/ThoughtProcessor.toolAllowlist.test.d.ts.map +1 -0
  13. package/dist/__tests__/helpers/factories.d.ts +7 -0
  14. package/dist/__tests__/helpers/factories.d.ts.map +1 -1
  15. package/dist/__tests__/sanitize.enforceJsonShape.test.d.ts +2 -0
  16. package/dist/__tests__/sanitize.enforceJsonShape.test.d.ts.map +1 -0
  17. package/dist/__tests__/transport-owner-context.test.d.ts +8 -0
  18. package/dist/__tests__/transport-owner-context.test.d.ts.map +1 -0
  19. package/dist/cli.js +176 -57
  20. package/dist/config/ConfigLoader.d.ts +7 -0
  21. package/dist/config/ConfigLoader.d.ts.map +1 -1
  22. package/dist/config/ConfigLoader.js +6 -1
  23. package/dist/config/ConfigLoader.js.map +1 -1
  24. package/dist/context/RequestContext.d.ts +26 -0
  25. package/dist/context/RequestContext.d.ts.map +1 -1
  26. package/dist/context/RequestContext.js +7 -1
  27. package/dist/context/RequestContext.js.map +1 -1
  28. package/dist/contracts/features.d.ts +2 -2
  29. package/dist/contracts/features.js.map +1 -1
  30. package/dist/contracts/interfaces.d.ts +42 -0
  31. package/dist/contracts/interfaces.d.ts.map +1 -1
  32. package/dist/core/HistoryManager.d.ts +13 -1
  33. package/dist/core/HistoryManager.d.ts.map +1 -1
  34. package/dist/core/HistoryManager.js +25 -14
  35. package/dist/core/HistoryManager.js.map +1 -1
  36. package/dist/core/InputNormalizer.d.ts.map +1 -1
  37. package/dist/core/InputNormalizer.js +5 -2
  38. package/dist/core/InputNormalizer.js.map +1 -1
  39. package/dist/core/SessionLock.d.ts +56 -0
  40. package/dist/core/SessionLock.d.ts.map +1 -0
  41. package/dist/core/SessionLock.js +43 -0
  42. package/dist/core/SessionLock.js.map +1 -0
  43. package/dist/core/SessionManager.d.ts +18 -3
  44. package/dist/core/SessionManager.d.ts.map +1 -1
  45. package/dist/core/SessionManager.js +34 -1
  46. package/dist/core/SessionManager.js.map +1 -1
  47. package/dist/core/ThoughtProcessor.d.ts +21 -2
  48. package/dist/core/ThoughtProcessor.d.ts.map +1 -1
  49. package/dist/core/ThoughtProcessor.js +33 -13
  50. package/dist/core/ThoughtProcessor.js.map +1 -1
  51. package/dist/di/ServiceRegistry.d.ts +3 -3
  52. package/dist/di/ServiceRegistry.d.ts.map +1 -1
  53. package/dist/errors.d.ts +48 -0
  54. package/dist/errors.d.ts.map +1 -1
  55. package/dist/errors.js +38 -2
  56. package/dist/errors.js.map +1 -1
  57. package/dist/lib.d.ts.map +1 -1
  58. package/dist/lib.js +9 -3
  59. package/dist/lib.js.map +1 -1
  60. package/dist/registry/ToolRegistry.d.ts +1 -0
  61. package/dist/registry/ToolRegistry.d.ts.map +1 -1
  62. package/dist/registry/ToolRegistry.js +3 -0
  63. package/dist/registry/ToolRegistry.js.map +1 -1
  64. package/dist/sanitize.d.ts +70 -0
  65. package/dist/sanitize.d.ts.map +1 -1
  66. package/dist/sanitize.js +77 -1
  67. package/dist/sanitize.js.map +1 -1
  68. package/dist/schema.d.ts +35 -35
  69. package/dist/schema.d.ts.map +1 -1
  70. package/dist/schema.js +15 -5
  71. package/dist/schema.js.map +1 -1
  72. package/dist/transport/HttpTransport.d.ts.map +1 -1
  73. package/dist/transport/HttpTransport.js +9 -3
  74. package/dist/transport/HttpTransport.js.map +1 -1
  75. package/dist/transport/SseTransport.d.ts.map +1 -1
  76. package/dist/transport/SseTransport.js +10 -3
  77. package/dist/transport/SseTransport.js.map +1 -1
  78. package/dist/transport/StreamableHttpTransport.d.ts.map +1 -1
  79. package/dist/transport/StreamableHttpTransport.js +8 -3
  80. package/dist/transport/StreamableHttpTransport.js.map +1 -1
  81. package/dist/types/tool.d.ts +1 -1
  82. package/dist/types/tool.d.ts.map +1 -1
  83. package/package.json +2 -1
@@ -60,4 +60,74 @@ export declare function stripControlChars(input: string): string;
60
60
  * ```
61
61
  */
62
62
  export declare function sanitizeString(input: string): string;
63
+ export interface EnforceJsonShapeOptions {
64
+ maxDepth?: number;
65
+ maxBytes?: number;
66
+ }
67
+ export declare class JsonShapeError extends Error {
68
+ readonly reason: string;
69
+ constructor(reason: string);
70
+ }
71
+ /**
72
+ * Enforce safety constraints on a JSON-shaped value.
73
+ *
74
+ * Rejects:
75
+ * - Prototype-pollution keys (`__proto__`, `constructor`, `prototype`) at any depth
76
+ * - Nesting deeper than `maxDepth` (default 8)
77
+ * - Serialized JSON byte length exceeding `maxBytes` (default 16384)
78
+ * - Functions, symbols, and other non-JSON-safe values
79
+ *
80
+ * Used as a defense-in-depth gate for untrusted structured input such as
81
+ * `tool_arguments` from an LLM.
82
+ *
83
+ * @param value - The value to validate
84
+ * @param opts - Optional limits
85
+ * @throws {JsonShapeError} when any constraint is violated
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * enforceJsonShape({ q: 'hello' }); // ok
90
+ * enforceJsonShape({ __proto__: { polluted: true } }); // throws
91
+ * enforceJsonShape({ a: { b: { c: { d: { e: { f: { g: { h: { i: 1 } } } } } } } } }); // throws (depth)
92
+ * ```
93
+ */
94
+ export declare function enforceJsonShape(value: unknown, opts?: EnforceJsonShapeOptions): void;
95
+ /**
96
+ * Sanitize a rationale string by stripping urgency phrases, capping length,
97
+ * and applying standard string sanitization.
98
+ *
99
+ * Applied to `recommended_tools[].rationale` and `recommended_skills[].rationale`
100
+ * to prevent prompt-injection via urgency language.
101
+ *
102
+ * @param input - The rationale string to sanitize
103
+ * @param truncated - Optional object to receive truncation signal (sets `.value = true` if truncated)
104
+ * @returns The sanitized rationale
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * sanitizeRationale('URGENT: run this now'); // '[redacted-urgency] run this now'
109
+ * sanitizeRationale('Best for web search'); // 'Best for web search' (unchanged)
110
+ * ```
111
+ */
112
+ export declare function sanitizeRationale(input: string, truncated?: {
113
+ value: boolean;
114
+ }): string;
115
+ /**
116
+ * Sanitize suggested_inputs: cap string value lengths, strip control chars and dangerous tags.
117
+ *
118
+ * Only processes flat primitive values (string | number | boolean | null).
119
+ * Non-primitive values (nested objects, arrays) are silently skipped — schema validation
120
+ * is expected to reject them upstream.
121
+ *
122
+ * @param inputs - The suggested_inputs record to sanitize
123
+ * @returns The sanitized record with cleaned string values
124
+ * @throws {Error} if string value exceeds max length, or if more than 32 keys are present
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * sanitizeSuggestedInputs({ url: 'x', limit: 5 }); // { url: 'x', limit: 5 }
129
+ * sanitizeSuggestedInputs({ url: '<script>alert(1)</script>' }); // { url: 'alert(1)' }
130
+ * ```
131
+ */
132
+ export declare function sanitizeSuggestedInputs(inputs: Record<string, unknown>): Record<string, string | number | boolean | null>;
63
133
  //# sourceMappingURL=sanitize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAgBD,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAe,SAAQ,KAAK;IACxC,SAAgB,MAAM,EAAE,MAAM,CAAC;gBACnB,MAAM,EAAE,MAAM;CAK1B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,uBAA4B,GAAG,IAAI,CAoDzF;AAcD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAQvF;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAuBlD"}
package/dist/sanitize.js CHANGED
@@ -9,6 +9,82 @@ function stripControlChars(input) {
9
9
  function sanitizeString(input) {
10
10
  return stripDangerousTags(stripControlChars(input));
11
11
  }
12
- export { sanitizeString, stripControlChars, stripDangerousTags };
12
+ const FORBIDDEN_KEYS = new Set([
13
+ '__proto__',
14
+ 'constructor',
15
+ 'prototype'
16
+ ]);
17
+ const DEFAULT_MAX_DEPTH = 8;
18
+ const DEFAULT_MAX_BYTES = 16384;
19
+ class JsonShapeError extends Error {
20
+ reason;
21
+ constructor(reason){
22
+ super(reason);
23
+ this.name = 'JsonShapeError';
24
+ this.reason = reason;
25
+ }
26
+ }
27
+ function enforceJsonShape(value, opts = {}) {
28
+ const maxDepth = opts.maxDepth ?? DEFAULT_MAX_DEPTH;
29
+ const maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
30
+ const seen = new WeakSet();
31
+ const walk = (node, depth)=>{
32
+ if (depth > maxDepth) throw new JsonShapeError(`exceeds max depth of ${maxDepth}`);
33
+ if (null === node) return;
34
+ const type = typeof node;
35
+ if ('string' === type || 'number' === type || 'boolean' === type) return;
36
+ if ('undefined' === type) return;
37
+ if ('function' === type || 'symbol' === type || 'bigint' === type) throw new JsonShapeError(`unsupported value type '${type}'`);
38
+ if ('object' !== type) throw new JsonShapeError(`unsupported value type '${type}'`);
39
+ const obj = node;
40
+ if (seen.has(obj)) throw new JsonShapeError('circular reference detected');
41
+ seen.add(obj);
42
+ if (Array.isArray(node)) {
43
+ for (const item of node)walk(item, depth + 1);
44
+ return;
45
+ }
46
+ for (const key of Object.keys(obj)){
47
+ if (FORBIDDEN_KEYS.has(key)) throw new JsonShapeError(`forbidden key '${key}'`);
48
+ walk(obj[key], depth + 1);
49
+ }
50
+ };
51
+ walk(value, 0);
52
+ let serialized;
53
+ try {
54
+ serialized = JSON.stringify(value);
55
+ } catch {
56
+ throw new JsonShapeError('value is not JSON-serializable');
57
+ }
58
+ if (void 0 === serialized) return;
59
+ const bytes = Buffer.byteLength(serialized, 'utf8');
60
+ if (bytes > maxBytes) throw new JsonShapeError(`exceeds max serialized size of ${maxBytes} bytes (got ${bytes})`);
61
+ }
62
+ const URGENCY_PHRASES = /\b(URGENT(?:LY)?|IMMEDIATELY|MUST\s+RUN|CRITICAL:|ACTION\s+REQUIRED|DO\s+NOT\s+IGNORE|EXECUTE\s+NOW|RUN\s+THIS\s+NOW)/gi;
63
+ const MAX_RATIONALE_LENGTH = 2000;
64
+ function sanitizeRationale(input, truncated) {
65
+ let result = sanitizeString(input);
66
+ result = result.replace(URGENCY_PHRASES, '[redacted-urgency]');
67
+ if (result.length > MAX_RATIONALE_LENGTH) {
68
+ result = result.slice(0, MAX_RATIONALE_LENGTH);
69
+ if (truncated) truncated.value = true;
70
+ }
71
+ return result;
72
+ }
73
+ const MAX_SUGGESTED_INPUTS_KEYS = 32;
74
+ const MAX_SUGGESTED_INPUT_VALUE_LENGTH = 512;
75
+ function sanitizeSuggestedInputs(inputs) {
76
+ const keys = Object.keys(inputs);
77
+ if (keys.length > MAX_SUGGESTED_INPUTS_KEYS) throw new Error(`suggested_inputs exceeds max keys of ${MAX_SUGGESTED_INPUTS_KEYS} (got ${keys.length})`);
78
+ const result = {};
79
+ for (const key of keys){
80
+ const value = inputs[key];
81
+ if ('string' == typeof value) {
82
+ if (value.length > MAX_SUGGESTED_INPUT_VALUE_LENGTH) throw new Error(`suggested_inputs value for key '${key}' exceeds max length of ${MAX_SUGGESTED_INPUT_VALUE_LENGTH}`);
83
+ result[key] = sanitizeString(value);
84
+ } else if ('number' == typeof value || 'boolean' == typeof value || null === value) result[key] = value;
85
+ }
86
+ return result;
87
+ }
88
+ export { JsonShapeError, enforceJsonShape, sanitizeRationale, sanitizeString, sanitizeSuggestedInputs, stripControlChars, stripDangerousTags };
13
89
 
14
90
  //# sourceMappingURL=sanitize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sources":["../src/sanitize.ts"],"sourcesContent":["/**\n * Input sanitization for the sequential thinking MCP tool.\n *\n * Provides pure functions for stripping dangerous content from free-text fields.\n * Uses a targeted blocklist approach: only removes HTML tags that can execute code,\n * while preserving generic angle-bracket content like TypeScript generics (`Array<string>`),\n * mathematical comparisons (`x < 5`), and markdown formatting.\n *\n * @module sanitize\n */\n\n/**\n * Regex matching dangerous HTML tags that can execute JavaScript or load external resources.\n * Targets: script, iframe, img, style, svg, embed, object, link, meta, base, form.\n * Preserves: `Array<string>`, `x < 5 && y > 3`, `<details>`, `<code>`, `<pre>`, etc.\n */\nconst DANGEROUS_TAG_REGEX =\n\t/<\\/?(script|iframe|img|style|svg|embed|object|link|meta|base|form)(\\s[^>]*)?\\s*\\/?>/gi;\n\n/**\n * Null bytes and C0 control characters (except tab \\t, newline \\n, carriage return \\r).\n * These can cause truncation in C bindings, file I/O, and some databases.\n */\n// eslint-disable-next-line no-control-regex -- intentional: matches C0 control chars to strip them\nconst CONTROL_CHAR_REGEX = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/g;\n\n/**\n * Strip dangerous HTML tags that can execute JavaScript or load external resources.\n *\n * Uses a targeted blocklist to remove only tags known to be dangerous (script, iframe,\n * img, style, svg, embed, object, link, meta, base, form) while preserving safe\n * angle-bracket content like TypeScript generics and mathematical comparisons.\n *\n * @param input - The string to sanitize\n * @returns The input with dangerous HTML tags removed\n *\n * @example\n * ```ts\n * stripDangerousTags('<script>alert(1)</script>hello'); // 'hello'\n * stripDangerousTags('Array<string>'); // 'Array<string>' (preserved)\n * stripDangerousTags('x < 5 && y > 3'); // 'x < 5 && y > 3' (preserved)\n * ```\n */\nexport function stripDangerousTags(input: string): string {\n\treturn input.replace(DANGEROUS_TAG_REGEX, '');\n}\n\n/**\n * Strip null bytes and C0 control characters from a string.\n *\n * Removes characters in the range U+0000–U+0008, U+000B, U+000C, U+000E–U+001F.\n * Preserves tab (`\\t`, U+0009), newline (`\\n`, U+000A), and carriage return (`\\r`, U+000D)\n * as these are commonly used in thought content.\n *\n * @param input - The string to sanitize\n * @returns The input with control characters removed\n *\n * @example\n * ```ts\n * stripControlChars('a\\x00b'); // 'ab'\n * stripControlChars('a\\tb\\nc'); // 'a\\tb\\nc' (tab and newline preserved)\n * ```\n */\nexport function stripControlChars(input: string): string {\n\treturn input.replace(CONTROL_CHAR_REGEX, '');\n}\n\n/**\n * Sanitize a string by stripping both control characters and dangerous HTML tags.\n *\n * Composes {@link stripControlChars} and {@link stripDangerousTags} in sequence.\n * Does not trim whitespace — thought content may depend on leading/trailing spaces.\n * Always returns a string, even if the input is empty.\n *\n * @param input - The string to sanitize\n * @returns The fully sanitized string\n *\n * @example\n * ```ts\n * sanitizeString('<script>alert(1)</script>hello\\x00world'); // 'helloworld'\n * sanitizeString('Array<string>\\x00'); // 'Array<string>'\n * ```\n */\nexport function sanitizeString(input: string): string {\n\treturn stripDangerousTags(stripControlChars(input));\n}\n"],"names":["DANGEROUS_TAG_REGEX","CONTROL_CHAR_REGEX","stripDangerousTags","input","stripControlChars","sanitizeString"],"mappings":"AAgBA,MAAMA,sBACL;AAOD,MAAMC,qBAAqB;AAmBpB,SAASC,mBAAmBC,KAAa;IAC/C,OAAOA,MAAM,OAAO,CAACH,qBAAqB;AAC3C;AAkBO,SAASI,kBAAkBD,KAAa;IAC9C,OAAOA,MAAM,OAAO,CAACF,oBAAoB;AAC1C;AAkBO,SAASI,eAAeF,KAAa;IAC3C,OAAOD,mBAAmBE,kBAAkBD;AAC7C"}
1
+ {"version":3,"file":"sanitize.js","sources":["../src/sanitize.ts"],"sourcesContent":["/**\n * Input sanitization for the sequential thinking MCP tool.\n *\n * Provides pure functions for stripping dangerous content from free-text fields.\n * Uses a targeted blocklist approach: only removes HTML tags that can execute code,\n * while preserving generic angle-bracket content like TypeScript generics (`Array<string>`),\n * mathematical comparisons (`x < 5`), and markdown formatting.\n *\n * @module sanitize\n */\n\n/**\n * Regex matching dangerous HTML tags that can execute JavaScript or load external resources.\n * Targets: script, iframe, img, style, svg, embed, object, link, meta, base, form.\n * Preserves: `Array<string>`, `x < 5 && y > 3`, `<details>`, `<code>`, `<pre>`, etc.\n */\nconst DANGEROUS_TAG_REGEX =\n\t/<\\/?(script|iframe|img|style|svg|embed|object|link|meta|base|form)(\\s[^>]*)?\\s*\\/?>/gi;\n\n/**\n * Null bytes and C0 control characters (except tab \\t, newline \\n, carriage return \\r).\n * These can cause truncation in C bindings, file I/O, and some databases.\n */\n// eslint-disable-next-line no-control-regex -- intentional: matches C0 control chars to strip them\nconst CONTROL_CHAR_REGEX = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/g;\n\n/**\n * Strip dangerous HTML tags that can execute JavaScript or load external resources.\n *\n * Uses a targeted blocklist to remove only tags known to be dangerous (script, iframe,\n * img, style, svg, embed, object, link, meta, base, form) while preserving safe\n * angle-bracket content like TypeScript generics and mathematical comparisons.\n *\n * @param input - The string to sanitize\n * @returns The input with dangerous HTML tags removed\n *\n * @example\n * ```ts\n * stripDangerousTags('<script>alert(1)</script>hello'); // 'hello'\n * stripDangerousTags('Array<string>'); // 'Array<string>' (preserved)\n * stripDangerousTags('x < 5 && y > 3'); // 'x < 5 && y > 3' (preserved)\n * ```\n */\nexport function stripDangerousTags(input: string): string {\n\treturn input.replace(DANGEROUS_TAG_REGEX, '');\n}\n\n/**\n * Strip null bytes and C0 control characters from a string.\n *\n * Removes characters in the range U+0000–U+0008, U+000B, U+000C, U+000E–U+001F.\n * Preserves tab (`\\t`, U+0009), newline (`\\n`, U+000A), and carriage return (`\\r`, U+000D)\n * as these are commonly used in thought content.\n *\n * @param input - The string to sanitize\n * @returns The input with control characters removed\n *\n * @example\n * ```ts\n * stripControlChars('a\\x00b'); // 'ab'\n * stripControlChars('a\\tb\\nc'); // 'a\\tb\\nc' (tab and newline preserved)\n * ```\n */\nexport function stripControlChars(input: string): string {\n\treturn input.replace(CONTROL_CHAR_REGEX, '');\n}\n\n/**\n * Sanitize a string by stripping both control characters and dangerous HTML tags.\n *\n * Composes {@link stripControlChars} and {@link stripDangerousTags} in sequence.\n * Does not trim whitespace — thought content may depend on leading/trailing spaces.\n * Always returns a string, even if the input is empty.\n *\n * @param input - The string to sanitize\n * @returns The fully sanitized string\n *\n * @example\n * ```ts\n * sanitizeString('<script>alert(1)</script>hello\\x00world'); // 'helloworld'\n * sanitizeString('Array<string>\\x00'); // 'Array<string>'\n * ```\n */\nexport function sanitizeString(input: string): string {\n\treturn stripDangerousTags(stripControlChars(input));\n}\n\n\n/**\n * Forbidden object keys that enable prototype pollution.\n * These keys allow attackers to inject properties onto Object.prototype,\n * affecting all subsequent objects in the runtime.\n */\nconst FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Default options for {@link enforceJsonShape}.\n */\nconst DEFAULT_MAX_DEPTH = 8;\nconst DEFAULT_MAX_BYTES = 16384;\n\nexport interface EnforceJsonShapeOptions {\n\tmaxDepth?: number;\n\tmaxBytes?: number;\n}\n\nexport class JsonShapeError extends Error {\n\tpublic readonly reason: string;\n\tconstructor(reason: string) {\n\t\tsuper(reason);\n\t\tthis.name = 'JsonShapeError';\n\t\tthis.reason = reason;\n\t}\n}\n\n/**\n * Enforce safety constraints on a JSON-shaped value.\n *\n * Rejects:\n * - Prototype-pollution keys (`__proto__`, `constructor`, `prototype`) at any depth\n * - Nesting deeper than `maxDepth` (default 8)\n * - Serialized JSON byte length exceeding `maxBytes` (default 16384)\n * - Functions, symbols, and other non-JSON-safe values\n *\n * Used as a defense-in-depth gate for untrusted structured input such as\n * `tool_arguments` from an LLM.\n *\n * @param value - The value to validate\n * @param opts - Optional limits\n * @throws {JsonShapeError} when any constraint is violated\n *\n * @example\n * ```ts\n * enforceJsonShape({ q: 'hello' }); // ok\n * enforceJsonShape({ __proto__: { polluted: true } }); // throws\n * enforceJsonShape({ a: { b: { c: { d: { e: { f: { g: { h: { i: 1 } } } } } } } } }); // throws (depth)\n * ```\n */\nexport function enforceJsonShape(value: unknown, opts: EnforceJsonShapeOptions = {}): void {\n\tconst maxDepth = opts.maxDepth ?? DEFAULT_MAX_DEPTH;\n\tconst maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;\n\n\tconst seen = new WeakSet<object>();\n\n\tconst walk = (node: unknown, depth: number): void => {\n\t\tif (depth > maxDepth) {\n\t\t\tthrow new JsonShapeError(`exceeds max depth of ${maxDepth}`);\n\t\t}\n\t\tif (node === null) return;\n\t\tconst type = typeof node;\n\t\tif (type === 'string' || type === 'number' || type === 'boolean') return;\n\t\tif (type === 'undefined') return;\n\t\tif (type === 'function' || type === 'symbol' || type === 'bigint') {\n\t\t\tthrow new JsonShapeError(`unsupported value type '${type}'`);\n\t\t}\n\t\tif (type !== 'object') {\n\t\t\tthrow new JsonShapeError(`unsupported value type '${type}'`);\n\t\t}\n\t\tconst obj = node as object;\n\t\tif (seen.has(obj)) {\n\t\t\tthrow new JsonShapeError('circular reference detected');\n\t\t}\n\t\tseen.add(obj);\n\n\t\tif (Array.isArray(node)) {\n\t\t\tfor (const item of node) walk(item, depth + 1);\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const key of Object.keys(obj)) {\n\t\t\tif (FORBIDDEN_KEYS.has(key)) {\n\t\t\t\tthrow new JsonShapeError(`forbidden key '${key}'`);\n\t\t\t}\n\t\t\twalk((obj as Record<string, unknown>)[key], depth + 1);\n\t\t}\n\t};\n\n\twalk(value, 0);\n\n\tlet serialized: string;\n\ttry {\n\t\tserialized = JSON.stringify(value);\n\t} catch {\n\t\tthrow new JsonShapeError('value is not JSON-serializable');\n\t}\n\tif (serialized === undefined) return;\n\tconst bytes = Buffer.byteLength(serialized, 'utf8');\n\tif (bytes > maxBytes) {\n\t\tthrow new JsonShapeError(`exceeds max serialized size of ${maxBytes} bytes (got ${bytes})`);\n\t}\n}\n\n/**\n * Urgency/imperative phrases that could be used for prompt injection.\n * Matched case-insensitively and replaced with [redacted-urgency].\n */\nconst URGENCY_PHRASES =\n\t/\\b(URGENT(?:LY)?|IMMEDIATELY|MUST\\s+RUN|CRITICAL:|ACTION\\s+REQUIRED|DO\\s+NOT\\s+IGNORE|EXECUTE\\s+NOW|RUN\\s+THIS\\s+NOW)/gi;\n\n/**\n * Maximum allowed length for rationale strings.\n */\nconst MAX_RATIONALE_LENGTH = 2000;\n\n/**\n * Sanitize a rationale string by stripping urgency phrases, capping length,\n * and applying standard string sanitization.\n *\n * Applied to `recommended_tools[].rationale` and `recommended_skills[].rationale`\n * to prevent prompt-injection via urgency language.\n *\n * @param input - The rationale string to sanitize\n * @param truncated - Optional object to receive truncation signal (sets `.value = true` if truncated)\n * @returns The sanitized rationale\n *\n * @example\n * ```ts\n * sanitizeRationale('URGENT: run this now'); // '[redacted-urgency] run this now'\n * sanitizeRationale('Best for web search'); // 'Best for web search' (unchanged)\n * ```\n */\nexport function sanitizeRationale(input: string, truncated?: { value: boolean }): string {\n\tlet result = sanitizeString(input);\n\tresult = result.replace(URGENCY_PHRASES, '[redacted-urgency]');\n\tif (result.length > MAX_RATIONALE_LENGTH) {\n\t\tresult = result.slice(0, MAX_RATIONALE_LENGTH);\n\t\tif (truncated) truncated.value = true;\n\t}\n\treturn result;\n}\n\n/**\n * Maximum number of keys allowed in suggested_inputs.\n */\nconst MAX_SUGGESTED_INPUTS_KEYS = 32;\n\n/**\n * Maximum string value length in suggested_inputs.\n */\nconst MAX_SUGGESTED_INPUT_VALUE_LENGTH = 512;\n\n/**\n * Sanitize suggested_inputs: cap string value lengths, strip control chars and dangerous tags.\n *\n * Only processes flat primitive values (string | number | boolean | null).\n * Non-primitive values (nested objects, arrays) are silently skipped — schema validation\n * is expected to reject them upstream.\n *\n * @param inputs - The suggested_inputs record to sanitize\n * @returns The sanitized record with cleaned string values\n * @throws {Error} if string value exceeds max length, or if more than 32 keys are present\n *\n * @example\n * ```ts\n * sanitizeSuggestedInputs({ url: 'x', limit: 5 }); // { url: 'x', limit: 5 }\n * sanitizeSuggestedInputs({ url: '<script>alert(1)</script>' }); // { url: 'alert(1)' }\n * ```\n */\nexport function sanitizeSuggestedInputs(\n\tinputs: Record<string, unknown>,\n): Record<string, string | number | boolean | null> {\n\tconst keys = Object.keys(inputs);\n\tif (keys.length > MAX_SUGGESTED_INPUTS_KEYS) {\n\t\tthrow new Error(\n\t\t\t`suggested_inputs exceeds max keys of ${MAX_SUGGESTED_INPUTS_KEYS} (got ${keys.length})`,\n\t\t);\n\t}\n\tconst result: Record<string, string | number | boolean | null> = {};\n\tfor (const key of keys) {\n\t\tconst value = inputs[key];\n\t\tif (typeof value === 'string') {\n\t\t\tif (value.length > MAX_SUGGESTED_INPUT_VALUE_LENGTH) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`suggested_inputs value for key '${key}' exceeds max length of ${MAX_SUGGESTED_INPUT_VALUE_LENGTH}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tresult[key] = sanitizeString(value);\n\t\t} else if (typeof value === 'number' || typeof value === 'boolean' || value === null) {\n\t\t\tresult[key] = value;\n\t\t}\n\t\t// Skip other types (shouldn't reach here if schema validates first)\n\t}\n\treturn result;\n}"],"names":["DANGEROUS_TAG_REGEX","CONTROL_CHAR_REGEX","stripDangerousTags","input","stripControlChars","sanitizeString","FORBIDDEN_KEYS","Set","DEFAULT_MAX_DEPTH","DEFAULT_MAX_BYTES","JsonShapeError","Error","reason","enforceJsonShape","value","opts","maxDepth","maxBytes","seen","WeakSet","walk","node","depth","type","obj","Array","item","key","Object","serialized","JSON","undefined","bytes","Buffer","URGENCY_PHRASES","MAX_RATIONALE_LENGTH","sanitizeRationale","truncated","result","MAX_SUGGESTED_INPUTS_KEYS","MAX_SUGGESTED_INPUT_VALUE_LENGTH","sanitizeSuggestedInputs","inputs","keys"],"mappings":"AAgBA,MAAMA,sBACL;AAOD,MAAMC,qBAAqB;AAmBpB,SAASC,mBAAmBC,KAAa;IAC/C,OAAOA,MAAM,OAAO,CAACH,qBAAqB;AAC3C;AAkBO,SAASI,kBAAkBD,KAAa;IAC9C,OAAOA,MAAM,OAAO,CAACF,oBAAoB;AAC1C;AAkBO,SAASI,eAAeF,KAAa;IAC3C,OAAOD,mBAAmBE,kBAAkBD;AAC7C;AAQA,MAAMG,iBAAiB,IAAIC,IAAI;IAAC;IAAa;IAAe;CAAY;AAKxE,MAAMC,oBAAoB;AAC1B,MAAMC,oBAAoB;AAOnB,MAAMC,uBAAuBC;IACnB,OAAe;IAC/B,YAAYC,MAAc,CAAE;QAC3B,KAAK,CAACA;QACN,IAAI,CAAC,IAAI,GAAG;QACZ,IAAI,CAAC,MAAM,GAAGA;IACf;AACD;AAyBO,SAASC,iBAAiBC,KAAc,EAAEC,OAAgC,CAAC,CAAC;IAClF,MAAMC,WAAWD,KAAK,QAAQ,IAAIP;IAClC,MAAMS,WAAWF,KAAK,QAAQ,IAAIN;IAElC,MAAMS,OAAO,IAAIC;IAEjB,MAAMC,OAAO,CAACC,MAAeC;QAC5B,IAAIA,QAAQN,UACX,MAAM,IAAIN,eAAe,CAAC,qBAAqB,EAAEM,UAAU;QAE5D,IAAIK,AAAS,SAATA,MAAe;QACnB,MAAME,OAAO,OAAOF;QACpB,IAAIE,AAAS,aAATA,QAAqBA,AAAS,aAATA,QAAqBA,AAAS,cAATA,MAAoB;QAClE,IAAIA,AAAS,gBAATA,MAAsB;QAC1B,IAAIA,AAAS,eAATA,QAAuBA,AAAS,aAATA,QAAqBA,AAAS,aAATA,MAC/C,MAAM,IAAIb,eAAe,CAAC,wBAAwB,EAAEa,KAAK,CAAC,CAAC;QAE5D,IAAIA,AAAS,aAATA,MACH,MAAM,IAAIb,eAAe,CAAC,wBAAwB,EAAEa,KAAK,CAAC,CAAC;QAE5D,MAAMC,MAAMH;QACZ,IAAIH,KAAK,GAAG,CAACM,MACZ,MAAM,IAAId,eAAe;QAE1BQ,KAAK,GAAG,CAACM;QAET,IAAIC,MAAM,OAAO,CAACJ,OAAO;YACxB,KAAK,MAAMK,QAAQL,KAAMD,KAAKM,MAAMJ,QAAQ;YAC5C;QACD;QAEA,KAAK,MAAMK,OAAOC,OAAO,IAAI,CAACJ,KAAM;YACnC,IAAIlB,eAAe,GAAG,CAACqB,MACtB,MAAM,IAAIjB,eAAe,CAAC,eAAe,EAAEiB,IAAI,CAAC,CAAC;YAElDP,KAAMI,GAA+B,CAACG,IAAI,EAAEL,QAAQ;QACrD;IACD;IAEAF,KAAKN,OAAO;IAEZ,IAAIe;IACJ,IAAI;QACHA,aAAaC,KAAK,SAAS,CAAChB;IAC7B,EAAE,OAAM;QACP,MAAM,IAAIJ,eAAe;IAC1B;IACA,IAAImB,AAAeE,WAAfF,YAA0B;IAC9B,MAAMG,QAAQC,OAAO,UAAU,CAACJ,YAAY;IAC5C,IAAIG,QAAQf,UACX,MAAM,IAAIP,eAAe,CAAC,+BAA+B,EAAEO,SAAS,YAAY,EAAEe,MAAM,CAAC,CAAC;AAE5F;AAMA,MAAME,kBACL;AAKD,MAAMC,uBAAuB;AAmBtB,SAASC,kBAAkBjC,KAAa,EAAEkC,SAA8B;IAC9E,IAAIC,SAASjC,eAAeF;IAC5BmC,SAASA,OAAO,OAAO,CAACJ,iBAAiB;IACzC,IAAII,OAAO,MAAM,GAAGH,sBAAsB;QACzCG,SAASA,OAAO,KAAK,CAAC,GAAGH;QACzB,IAAIE,WAAWA,UAAU,KAAK,GAAG;IAClC;IACA,OAAOC;AACR;AAKA,MAAMC,4BAA4B;AAKlC,MAAMC,mCAAmC;AAmBlC,SAASC,wBACfC,MAA+B;IAE/B,MAAMC,OAAOf,OAAO,IAAI,CAACc;IACzB,IAAIC,KAAK,MAAM,GAAGJ,2BACjB,MAAM,IAAI5B,MACT,CAAC,qCAAqC,EAAE4B,0BAA0B,MAAM,EAAEI,KAAK,MAAM,CAAC,CAAC,CAAC;IAG1F,MAAML,SAA2D,CAAC;IAClE,KAAK,MAAMX,OAAOgB,KAAM;QACvB,MAAM7B,QAAQ4B,MAAM,CAACf,IAAI;QACzB,IAAI,AAAiB,YAAjB,OAAOb,OAAoB;YAC9B,IAAIA,MAAM,MAAM,GAAG0B,kCAClB,MAAM,IAAI7B,MACT,CAAC,gCAAgC,EAAEgB,IAAI,wBAAwB,EAAEa,kCAAkC;YAGrGF,MAAM,CAACX,IAAI,GAAGtB,eAAeS;QAC9B,OAAO,IAAI,AAAiB,YAAjB,OAAOA,SAAsB,AAAiB,aAAjB,OAAOA,SAAuBA,AAAU,SAAVA,OACrEwB,MAAM,CAACX,IAAI,GAAGb;IAGhB;IACA,OAAOwB;AACR"}
package/dist/schema.d.ts CHANGED
@@ -58,11 +58,11 @@ import type { Tool } from './types/tool.js';
58
58
  export declare const ToolRecommendationSchema: v.ObjectSchema<{
59
59
  readonly tool_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the tool being recommended">]>;
60
60
  readonly confidence: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation">]>;
61
- readonly rationale: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this tool is recommended">]>;
61
+ readonly rationale: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this tool is recommended">]>;
62
62
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
63
- readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
64
- [x: string]: unknown;
65
- }, "Optional suggested parameters">]>, undefined>;
63
+ readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.NullSchema<undefined>], undefined>, undefined>, v.DescriptionAction<{
64
+ [x: string]: string | number | boolean | null;
65
+ }, "Optional suggested parameters (flat key-value pairs only)">]>, undefined>;
66
66
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative tools that could be used">]>, undefined>;
67
67
  }, undefined>;
68
68
  /**
@@ -94,7 +94,7 @@ export declare const ToolRecommendationSchema: v.ObjectSchema<{
94
94
  export declare const SkillRecommendationSchema: v.ObjectSchema<{
95
95
  readonly skill_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the skill being recommended">]>;
96
96
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
97
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
97
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
98
98
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
99
99
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative skills that could be used">]>, undefined>;
100
100
  readonly allowed_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Tools this skill is allowed to use (from skill frontmatter)">]>, undefined>;
@@ -127,11 +127,11 @@ export declare const StepRecommendationSchema: v.ObjectSchema<{
127
127
  readonly recommended_tools: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
128
128
  readonly tool_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the tool being recommended">]>;
129
129
  readonly confidence: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation">]>;
130
- readonly rationale: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this tool is recommended">]>;
130
+ readonly rationale: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this tool is recommended">]>;
131
131
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
132
- readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
133
- [x: string]: unknown;
134
- }, "Optional suggested parameters">]>, undefined>;
132
+ readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.NullSchema<undefined>], undefined>, undefined>, v.DescriptionAction<{
133
+ [x: string]: string | number | boolean | null;
134
+ }, "Optional suggested parameters (flat key-value pairs only)">]>, undefined>;
135
135
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative tools that could be used">]>, undefined>;
136
136
  }, undefined>, undefined>, v.DescriptionAction<{
137
137
  tool_name: string;
@@ -139,14 +139,14 @@ export declare const StepRecommendationSchema: v.ObjectSchema<{
139
139
  rationale: string;
140
140
  priority?: number | undefined;
141
141
  suggested_inputs?: {
142
- [x: string]: unknown;
142
+ [x: string]: string | number | boolean | null;
143
143
  } | undefined;
144
144
  alternatives?: string[] | undefined;
145
145
  }[], "Tools recommended for this step">]>;
146
146
  readonly recommended_skills: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
147
147
  readonly skill_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the skill being recommended">]>;
148
148
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
149
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
149
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
150
150
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
151
151
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative skills that could be used">]>, undefined>;
152
152
  readonly allowed_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Tools this skill is allowed to use (from skill frontmatter)">]>, undefined>;
@@ -199,12 +199,12 @@ export declare const StepRecommendationSchema: v.ObjectSchema<{
199
199
  */
200
200
  export declare const PartialToolRecommendationSchema: v.ObjectSchema<{
201
201
  readonly tool_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the tool being recommended">]>;
202
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this tool is recommended (default: empty string)">]>, undefined>;
202
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this tool is recommended (default: empty string)">]>, undefined>;
203
203
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
204
204
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
205
- readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
206
- [x: string]: unknown;
207
- }, "Optional suggested parameters">]>, undefined>;
205
+ readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.NullSchema<undefined>], undefined>, undefined>, v.DescriptionAction<{
206
+ [x: string]: string | number | boolean | null;
207
+ }, "Optional suggested parameters (flat key-value pairs only)">]>, undefined>;
208
208
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative tools that could be used">]>, undefined>;
209
209
  }, undefined>;
210
210
  /**
@@ -248,12 +248,12 @@ export declare const PartialStepRecommendationSchema: v.ObjectSchema<{
248
248
  readonly step_description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "What needs to be done">]>;
249
249
  readonly recommended_tools: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
250
250
  readonly tool_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the tool being recommended">]>;
251
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this tool is recommended (default: empty string)">]>, undefined>;
251
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this tool is recommended (default: empty string)">]>, undefined>;
252
252
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
253
253
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
254
- readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
255
- [x: string]: unknown;
256
- }, "Optional suggested parameters">]>, undefined>;
254
+ readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.NullSchema<undefined>], undefined>, undefined>, v.DescriptionAction<{
255
+ [x: string]: string | number | boolean | null;
256
+ }, "Optional suggested parameters (flat key-value pairs only)">]>, undefined>;
257
257
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative tools that could be used">]>, undefined>;
258
258
  }, undefined>, undefined>, v.DescriptionAction<{
259
259
  tool_name: string;
@@ -261,14 +261,14 @@ export declare const PartialStepRecommendationSchema: v.ObjectSchema<{
261
261
  confidence?: number | undefined;
262
262
  priority?: number | undefined;
263
263
  suggested_inputs?: {
264
- [x: string]: unknown;
264
+ [x: string]: string | number | boolean | null;
265
265
  } | undefined;
266
266
  alternatives?: string[] | undefined;
267
267
  }[], "Tools recommended for this step">]>;
268
268
  readonly recommended_skills: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
269
269
  readonly skill_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the skill being recommended">]>;
270
270
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
271
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
271
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
272
272
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
273
273
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative skills that could be used">]>, undefined>;
274
274
  readonly allowed_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Tools this skill is allowed to use (from skill frontmatter)">]>, undefined>;
@@ -344,11 +344,11 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
344
344
  readonly recommended_tools: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
345
345
  readonly tool_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the tool being recommended">]>;
346
346
  readonly confidence: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation">]>;
347
- readonly rationale: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this tool is recommended">]>;
347
+ readonly rationale: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this tool is recommended">]>;
348
348
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
349
- readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
350
- [x: string]: unknown;
351
- }, "Optional suggested parameters">]>, undefined>;
349
+ readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.NullSchema<undefined>], undefined>, undefined>, v.DescriptionAction<{
350
+ [x: string]: string | number | boolean | null;
351
+ }, "Optional suggested parameters (flat key-value pairs only)">]>, undefined>;
352
352
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative tools that could be used">]>, undefined>;
353
353
  }, undefined>, undefined>, v.DescriptionAction<{
354
354
  tool_name: string;
@@ -356,14 +356,14 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
356
356
  rationale: string;
357
357
  priority?: number | undefined;
358
358
  suggested_inputs?: {
359
- [x: string]: unknown;
359
+ [x: string]: string | number | boolean | null;
360
360
  } | undefined;
361
361
  alternatives?: string[] | undefined;
362
362
  }[], "Tools recommended for this step">]>;
363
363
  readonly recommended_skills: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
364
364
  readonly skill_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the skill being recommended">]>;
365
365
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
366
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
366
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
367
367
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
368
368
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative skills that could be used">]>, undefined>;
369
369
  readonly allowed_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Tools this skill is allowed to use (from skill frontmatter)">]>, undefined>;
@@ -387,7 +387,7 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
387
387
  rationale: string;
388
388
  priority?: number | undefined;
389
389
  suggested_inputs?: {
390
- [x: string]: unknown;
390
+ [x: string]: string | number | boolean | null;
391
391
  } | undefined;
392
392
  alternatives?: string[] | undefined;
393
393
  }[];
@@ -407,12 +407,12 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
407
407
  readonly step_description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "What needs to be done">]>;
408
408
  readonly recommended_tools: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
409
409
  readonly tool_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the tool being recommended">]>;
410
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this tool is recommended (default: empty string)">]>, undefined>;
410
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this tool is recommended (default: empty string)">]>, undefined>;
411
411
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
412
412
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
413
- readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, v.DescriptionAction<{
414
- [x: string]: unknown;
415
- }, "Optional suggested parameters">]>, undefined>;
413
+ readonly suggested_inputs: v.OptionalSchema<v.SchemaWithPipe<readonly [v.RecordSchema<v.StringSchema<undefined>, v.UnionSchema<[v.StringSchema<undefined>, v.NumberSchema<undefined>, v.BooleanSchema<undefined>, v.NullSchema<undefined>], undefined>, undefined>, v.DescriptionAction<{
414
+ [x: string]: string | number | boolean | null;
415
+ }, "Optional suggested parameters (flat key-value pairs only)">]>, undefined>;
416
416
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative tools that could be used">]>, undefined>;
417
417
  }, undefined>, undefined>, v.DescriptionAction<{
418
418
  tool_name: string;
@@ -420,14 +420,14 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
420
420
  confidence?: number | undefined;
421
421
  priority?: number | undefined;
422
422
  suggested_inputs?: {
423
- [x: string]: unknown;
423
+ [x: string]: string | number | boolean | null;
424
424
  } | undefined;
425
425
  alternatives?: string[] | undefined;
426
426
  }[], "Tools recommended for this step">]>;
427
427
  readonly recommended_skills: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
428
428
  readonly skill_name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Name of the skill being recommended">]>;
429
429
  readonly confidence: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 1, undefined>, v.DescriptionAction<number, "0-1 indicating confidence in recommendation (default: 0.5)">]>, undefined>;
430
- readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
430
+ readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>, v.DescriptionAction<string, "Why this skill is recommended (default: empty string)">]>, undefined>;
431
431
  readonly priority: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.DescriptionAction<number, "Order in the recommendation sequence (default: 999)">]>, undefined>;
432
432
  readonly alternatives: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Alternative skills that could be used">]>, undefined>;
433
433
  readonly allowed_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Tools this skill is allowed to use (from skill frontmatter)">]>, undefined>;
@@ -451,7 +451,7 @@ export declare const SequentialThinkingSchema: v.ObjectSchema<{
451
451
  confidence?: number | undefined;
452
452
  priority?: number | undefined;
453
453
  suggested_inputs?: {
454
- [x: string]: unknown;
454
+ [x: string]: string | number | boolean | null;
455
455
  } | undefined;
456
456
  alternatives?: string[] | undefined;
457
457
  }[];
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAiH5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;aAkBnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;aA4BpC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAanC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;aAsB1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAe1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA0LnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,EAAE,IAItC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB;;;;;aAmB/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,kWASW,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;aAQmH,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAiH5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;aAqBnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;aA4BpC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAanC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;aAyB1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAe1C,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA0LnC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,EAAE,IAItC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB;;;;;aAmB/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,kWASW,CAAC;AAEvC;;GAEG;AACH,eAAO,MAAM,UAAU;;;;;;;;aAQmH,CAAC"}
package/dist/schema.js CHANGED
@@ -106,15 +106,20 @@ You should:
106
106
  const ToolRecommendationSchema = __rspack_external_valibot.object({
107
107
  tool_name: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.description('Name of the tool being recommended')),
108
108
  confidence: __rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(0), __rspack_external_valibot.maxValue(1), __rspack_external_valibot.description('0-1 indicating confidence in recommendation')),
109
- rationale: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.description('Why this tool is recommended')),
109
+ rationale: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.maxLength(2000), __rspack_external_valibot.description('Why this tool is recommended')),
110
110
  priority: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.description('Order in the recommendation sequence (default: 999)'))),
111
- suggested_inputs: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.record(__rspack_external_valibot.string(), __rspack_external_valibot.unknown()), __rspack_external_valibot.description('Optional suggested parameters'))),
111
+ suggested_inputs: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.record(__rspack_external_valibot.string(), __rspack_external_valibot.union([
112
+ __rspack_external_valibot.string(),
113
+ __rspack_external_valibot.number(),
114
+ __rspack_external_valibot.boolean(),
115
+ __rspack_external_valibot["null"]()
116
+ ])), __rspack_external_valibot.description('Optional suggested parameters (flat key-value pairs only)'))),
112
117
  alternatives: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.array(__rspack_external_valibot.string()), __rspack_external_valibot.description('Alternative tools that could be used')))
113
118
  });
114
119
  const SkillRecommendationSchema = __rspack_external_valibot.object({
115
120
  skill_name: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.description('Name of the skill being recommended')),
116
121
  confidence: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(0), __rspack_external_valibot.maxValue(1), __rspack_external_valibot.description('0-1 indicating confidence in recommendation (default: 0.5)'))),
117
- rationale: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.description('Why this skill is recommended (default: empty string)'))),
122
+ rationale: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.maxLength(2000), __rspack_external_valibot.description('Why this skill is recommended (default: empty string)'))),
118
123
  priority: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.description('Order in the recommendation sequence (default: 999)'))),
119
124
  alternatives: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.array(__rspack_external_valibot.string()), __rspack_external_valibot.description('Alternative skills that could be used'))),
120
125
  allowed_tools: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.array(__rspack_external_valibot.string()), __rspack_external_valibot.description('Tools this skill is allowed to use (from skill frontmatter)'))),
@@ -129,10 +134,15 @@ const StepRecommendationSchema = __rspack_external_valibot.object({
129
134
  });
130
135
  const PartialToolRecommendationSchema = __rspack_external_valibot.object({
131
136
  tool_name: __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.description('Name of the tool being recommended')),
132
- rationale: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.description('Why this tool is recommended (default: empty string)'))),
137
+ rationale: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.maxLength(2000), __rspack_external_valibot.description('Why this tool is recommended (default: empty string)'))),
133
138
  confidence: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.minValue(0), __rspack_external_valibot.maxValue(1), __rspack_external_valibot.description('0-1 indicating confidence in recommendation (default: 0.5)'))),
134
139
  priority: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.number(), __rspack_external_valibot.description('Order in the recommendation sequence (default: 999)'))),
135
- suggested_inputs: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.record(__rspack_external_valibot.string(), __rspack_external_valibot.unknown()), __rspack_external_valibot.description('Optional suggested parameters'))),
140
+ suggested_inputs: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.record(__rspack_external_valibot.string(), __rspack_external_valibot.union([
141
+ __rspack_external_valibot.string(),
142
+ __rspack_external_valibot.number(),
143
+ __rspack_external_valibot.boolean(),
144
+ __rspack_external_valibot["null"]()
145
+ ])), __rspack_external_valibot.description('Optional suggested parameters (flat key-value pairs only)'))),
136
146
  alternatives: __rspack_external_valibot.optional(__rspack_external_valibot.pipe(__rspack_external_valibot.array(__rspack_external_valibot.string()), __rspack_external_valibot.description('Alternative tools that could be used')))
137
147
  });
138
148
  const PartialStepRecommendationSchema = __rspack_external_valibot.object({