@wrongstack/tools 0.275.1 → 0.276.2

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 (47) hide show
  1. package/dist/{background-indexer-BoTUw0EM.d.ts → background-indexer-BeDBxfSh.d.ts} +6 -0
  2. package/dist/builtin.js +1007 -204
  3. package/dist/builtin.js.map +1 -1
  4. package/dist/codebase-index/index.d.ts +30 -2
  5. package/dist/codebase-index/index.js +201 -24
  6. package/dist/codebase-index/index.js.map +1 -1
  7. package/dist/codebase-index/worker.js +196 -23
  8. package/dist/codebase-index/worker.js.map +1 -1
  9. package/dist/document.js +2 -2
  10. package/dist/document.js.map +1 -1
  11. package/dist/edit.js +52 -15
  12. package/dist/edit.js.map +1 -1
  13. package/dist/fetch.js +89 -18
  14. package/dist/fetch.js.map +1 -1
  15. package/dist/glob.js +35 -1
  16. package/dist/glob.js.map +1 -1
  17. package/dist/grep.js +15 -4
  18. package/dist/grep.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +1041 -213
  21. package/dist/index.js.map +1 -1
  22. package/dist/install.d.ts +7 -0
  23. package/dist/install.js +6 -0
  24. package/dist/install.js.map +1 -1
  25. package/dist/json.d.ts +26 -1
  26. package/dist/json.js +396 -44
  27. package/dist/json.js.map +1 -1
  28. package/dist/memory.js +26 -4
  29. package/dist/memory.js.map +1 -1
  30. package/dist/outdated.js +2 -2
  31. package/dist/outdated.js.map +1 -1
  32. package/dist/pack.js +1007 -204
  33. package/dist/pack.js.map +1 -1
  34. package/dist/read.js +36 -6
  35. package/dist/read.js.map +1 -1
  36. package/dist/replace.js +27 -9
  37. package/dist/replace.js.map +1 -1
  38. package/dist/search.d.ts +5 -1
  39. package/dist/search.js +179 -62
  40. package/dist/search.js.map +1 -1
  41. package/dist/tool-help.js +2 -2
  42. package/dist/tool-help.js.map +1 -1
  43. package/dist/tool-search.js +2 -2
  44. package/dist/tool-search.js.map +1 -1
  45. package/dist/write.js +13 -3
  46. package/dist/write.js.map +1 -1
  47. package/package.json +2 -2
package/dist/json.d.ts CHANGED
@@ -1,18 +1,43 @@
1
1
  import { Tool } from '@wrongstack/core';
2
2
 
3
+ type JsonAction = 'parse' | 'query' | 'validate' | 'transform' | 'merge';
3
4
  interface JsonInput {
5
+ /** Operation to perform. Defaults to 'parse'. */
6
+ action?: JsonAction | undefined;
7
+ /** Path to JSON/JSON5/YAML file (alternative to `data`). */
4
8
  file?: string | undefined;
9
+ /** Inline JSON/JSON5/YAML string (alternative to `file`). */
5
10
  data?: string | undefined;
6
- query?: string | undefined;
11
+ /** Output format for parse/query/transform results. */
7
12
  format?: 'json' | 'json5' | 'yaml' | undefined;
8
13
  validate?: boolean | undefined;
14
+ /** JMESPath-like query expression. */
15
+ query?: string | undefined;
16
+ /** Ordered JMESPath transforms (transform action only). */
17
+ transforms?: string[] | undefined;
18
+ /** JSON Schema to validate against. */
19
+ schema?: Record<string, unknown> | undefined;
20
+ /** Base object for merge. */
21
+ base?: unknown | undefined;
22
+ /** Patch object for merge. */
23
+ patch?: unknown | undefined;
24
+ /** Merge conflict resolution: 'prefer-patch' (default) or 'prefer-base'. */
25
+ conflictResolution?: 'prefer-base' | 'prefer-patch' | undefined;
9
26
  }
10
27
  interface JsonOutput {
11
28
  data: unknown;
12
29
  formatted: string;
13
30
  type: string;
31
+ action: string;
14
32
  keys?: string[] | undefined;
15
33
  query_result?: unknown | undefined;
34
+ result?: unknown | undefined;
35
+ valid?: boolean | undefined;
36
+ errors?: string[] | undefined;
37
+ steps?: Array<{
38
+ transform: string;
39
+ result: unknown;
40
+ }> | undefined;
16
41
  error?: string | undefined;
17
42
  }
18
43
  declare const jsonTool: Tool<JsonInput, JsonOutput>;
package/dist/json.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as fs from 'node:fs/promises';
2
+ import { deepMerge } from '@wrongstack/core';
2
3
 
3
4
  // src/json.ts
4
5
  var jsonTool = {
5
6
  name: "json",
6
7
  category: "Data",
7
- description: "Parse, pretty-print, query, and convert between JSON, JSON5, and YAML. Supports simple path-based queries.",
8
- usageHint: "VERY USEFUL FOR DATA INSPECTION:\n\n- Use on package.json, tsconfig, config files, or any structured data.\n- `query` lets you extract specific values without reading the whole file.\n- Great for validating that a file has the expected structure.\nPrefer this over raw `read` + manual parsing when dealing with configuration or data files.",
8
+ description: "Parse, pretty-print, query, validate, transform, and merge JSON/JSON5/YAML. Use `action` to select the operation: parse (default), query, validate, transform, or merge.",
9
+ usageHint: 'VERY USEFUL FOR DATA INSPECTION:\n\n- `action: "parse"` (default): read/pretty-print/convert JSON, JSON5, or YAML from `file` or `data`.\n- `action: "query"`: JMESPath-like query (`a.b[0].c`, `items[*].name`, filters, functions).\n- `action: "validate"`: validate data against a JSON Schema (`schema` param).\n- `action: "transform"`: chain multiple JMESPath transforms (`transforms` param).\n- `action: "merge"`: deep merge `base` and `patch` objects (`conflictResolution` param).\nPrefer this over raw `read` + manual parsing when dealing with configuration or data files.',
9
10
  permission: "auto",
10
11
  mutating: false,
11
12
  timeoutMs: 5e3,
@@ -14,69 +15,420 @@ var jsonTool = {
14
15
  inputSchema: {
15
16
  type: "object",
16
17
  properties: {
17
- file: { type: "string", description: "Path to JSON/JSON5/YAML file" },
18
- data: { type: "string", description: "JSON/JSON5/YAML string (alternative to file)" },
19
- query: {
18
+ action: {
20
19
  type: "string",
21
- description: 'JMESPath-like query (e.g. "a.b[0].c" or "a[*].name")'
20
+ enum: ["parse", "query", "validate", "transform", "merge"],
21
+ description: "Operation (default: parse). parse=read/pretty-print, query=JMESPath, validate=schema, transform=chained queries, merge=deep merge."
22
22
  },
23
+ file: { type: "string", description: "Path to JSON/JSON5/YAML file (parse/query/validate)" },
24
+ data: { type: "string", description: "JSON/JSON5/YAML string (parse/query/validate, alternative to file)" },
23
25
  format: {
24
26
  type: "string",
25
27
  enum: ["json", "json5", "yaml"],
26
- description: "Output format (default: json)"
28
+ description: "Output format for parse/query/transform (default: json)"
29
+ },
30
+ query: {
31
+ type: "string",
32
+ description: "JMESPath-like query expression (query action)"
33
+ },
34
+ transforms: {
35
+ type: "array",
36
+ items: { type: "string" },
37
+ description: "Ordered JMESPath query strings (transform action)"
38
+ },
39
+ schema: {
40
+ type: "object",
41
+ description: "JSON Schema to validate against (validate action)"
42
+ },
43
+ base: { description: "Base JSON object (merge action)" },
44
+ patch: { description: "Patch JSON object to merge in (merge action)" },
45
+ conflictResolution: {
46
+ type: "string",
47
+ enum: ["prefer-base", "prefer-patch"],
48
+ description: "Merge conflict resolution (default: prefer-patch)"
27
49
  },
28
50
  validate: {
29
51
  type: "boolean",
30
- description: "Validate syntax only, no output (default: false)"
52
+ description: "Validate syntax only, no output (parse action, default: false)"
31
53
  }
32
54
  }
33
55
  },
34
56
  async execute(input) {
35
- const format = input.format ?? "json";
36
- let parsed;
37
- let raw;
38
- if (input.file) {
39
- try {
40
- raw = await fs.readFile(input.file, "utf8");
41
- } catch {
42
- return { data: null, formatted: "", type: "unknown", error: `Could not read file` };
43
- }
44
- } else if (input.data) {
45
- raw = input.data;
46
- } else {
47
- return { data: null, formatted: "", type: "unknown", error: "Provide file or data" };
57
+ const action = input.action ?? "parse";
58
+ switch (action) {
59
+ case "query":
60
+ return executeQuery(input);
61
+ case "validate":
62
+ return executeValidate(input);
63
+ case "transform":
64
+ return executeTransform(input);
65
+ case "merge":
66
+ return executeMerge(input);
67
+ case "parse":
68
+ default:
69
+ return executeParse(input);
48
70
  }
71
+ }
72
+ };
73
+ async function executeParse(input) {
74
+ const format = input.format ?? "json";
75
+ let parsed;
76
+ let raw;
77
+ if (input.file) {
49
78
  try {
50
- parsed = JSON.parse(raw);
51
- } catch (e) {
52
- return {
53
- data: null,
54
- formatted: "",
55
- type: "unknown",
56
- /* v8 ignore next -- JSON.parse only throws SyntaxError (an Error); the String(e) side is defensive. */
57
- error: `Parse failed: ${e instanceof Error ? e.message : String(e)}`
58
- };
59
- }
60
- if (input.validate) {
61
- return {
62
- data: parsed,
63
- formatted: "valid",
64
- type: Array.isArray(parsed) ? "array" : typeof parsed,
65
- keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0
66
- };
67
- }
68
- const queryResult = input.query ? query(parsed, input.query) : void 0;
69
- const formatted = formatOutput(queryResult ?? parsed, format);
79
+ raw = await fs.readFile(input.file, "utf8");
80
+ } catch {
81
+ return { data: null, formatted: "", type: "unknown", action: "parse", error: "Could not read file" };
82
+ }
83
+ } else if (input.data) {
84
+ raw = input.data;
85
+ } else {
86
+ return { data: null, formatted: "", type: "unknown", action: "parse", error: "Provide file or data" };
87
+ }
88
+ try {
89
+ parsed = JSON.parse(raw);
90
+ } catch (e) {
91
+ return {
92
+ data: null,
93
+ formatted: "",
94
+ type: "unknown",
95
+ action: "parse",
96
+ /* v8 ignore next -- JSON.parse only throws SyntaxError (an Error); the String(e) side is defensive. */
97
+ error: `Parse failed: ${e instanceof Error ? e.message : String(e)}`
98
+ };
99
+ }
100
+ if (input.validate) {
70
101
  return {
71
102
  data: parsed,
72
- formatted,
103
+ formatted: "valid",
73
104
  type: Array.isArray(parsed) ? "array" : typeof parsed,
105
+ action: "parse",
106
+ keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0
107
+ };
108
+ }
109
+ if (input.query) {
110
+ const queryResult = simpleQuery(parsed, input.query);
111
+ const formatted2 = formatOutput(queryResult, format);
112
+ return {
113
+ data: parsed,
114
+ formatted: formatted2,
115
+ type: Array.isArray(parsed) ? "array" : typeof parsed,
116
+ action: "parse",
74
117
  keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0,
75
118
  query_result: queryResult
76
119
  };
77
120
  }
78
- };
79
- function query(data, path) {
121
+ const formatted = formatOutput(parsed, format);
122
+ return {
123
+ data: parsed,
124
+ formatted,
125
+ type: Array.isArray(parsed) ? "array" : typeof parsed,
126
+ action: "parse",
127
+ keys: typeof parsed === "object" && parsed !== null ? Object.keys(parsed) : void 0
128
+ };
129
+ }
130
+ async function executeQuery(input) {
131
+ if (!input.query) {
132
+ return { data: null, formatted: "", type: "unknown", action: "query", error: "query is required for action: query" };
133
+ }
134
+ let parsed;
135
+ if (input.file) {
136
+ try {
137
+ const raw = await fs.readFile(input.file, "utf8");
138
+ parsed = JSON.parse(raw);
139
+ } catch {
140
+ return { data: null, formatted: "", type: "unknown", action: "query", error: "Could not read/parse file" };
141
+ }
142
+ } else if (input.data) {
143
+ try {
144
+ parsed = JSON.parse(input.data);
145
+ } catch {
146
+ return { data: null, formatted: "", type: "unknown", action: "query", error: "Could not parse data string" };
147
+ }
148
+ } else {
149
+ return { data: null, formatted: "", type: "unknown", action: "query", error: "Provide file or data" };
150
+ }
151
+ try {
152
+ const result = jmespathSearch(parsed, input.query);
153
+ const format = input.format ?? "json";
154
+ return {
155
+ data: parsed,
156
+ formatted: formatOutput(result, format),
157
+ type: result === null ? "null" : Array.isArray(result) ? "array" : typeof result,
158
+ action: "query",
159
+ query_result: result
160
+ };
161
+ } catch (e) {
162
+ return {
163
+ data: null,
164
+ formatted: "",
165
+ type: "unknown",
166
+ action: "query",
167
+ /* v8 ignore next -- defensive String(e) */
168
+ error: `Query failed: ${e instanceof Error ? e.message : String(e)}`
169
+ };
170
+ }
171
+ }
172
+ async function executeValidate(input) {
173
+ if (!input.schema) {
174
+ return { data: null, formatted: "", type: "unknown", action: "validate", error: "schema is required for action: validate" };
175
+ }
176
+ let parsed;
177
+ if (input.file) {
178
+ try {
179
+ const raw = await fs.readFile(input.file, "utf8");
180
+ parsed = JSON.parse(raw);
181
+ } catch {
182
+ return { data: null, formatted: "", type: "unknown", action: "validate", error: "Could not read/parse file" };
183
+ }
184
+ } else if (input.data) {
185
+ try {
186
+ parsed = JSON.parse(input.data);
187
+ } catch {
188
+ return { data: null, formatted: "", type: "unknown", action: "validate", error: "Could not parse data string" };
189
+ }
190
+ } else {
191
+ return { data: null, formatted: "", type: "unknown", action: "validate", error: "Provide file or data" };
192
+ }
193
+ try {
194
+ const { valid, errors } = validateJsonSchema(parsed, input.schema);
195
+ return {
196
+ data: parsed,
197
+ formatted: valid ? "valid" : "invalid",
198
+ type: Array.isArray(parsed) ? "array" : typeof parsed,
199
+ action: "validate",
200
+ valid,
201
+ errors
202
+ };
203
+ } catch (e) {
204
+ return {
205
+ data: null,
206
+ formatted: "",
207
+ type: "unknown",
208
+ action: "validate",
209
+ /* v8 ignore next -- defensive String(e) */
210
+ error: `Validation failed: ${e instanceof Error ? e.message : String(e)}`
211
+ };
212
+ }
213
+ }
214
+ async function executeTransform(input) {
215
+ if (!input.transforms || input.transforms.length === 0) {
216
+ return { data: null, formatted: "", type: "unknown", action: "transform", error: "transforms array is required for action: transform" };
217
+ }
218
+ let parsed;
219
+ if (input.file) {
220
+ try {
221
+ const raw = await fs.readFile(input.file, "utf8");
222
+ parsed = JSON.parse(raw);
223
+ } catch {
224
+ return { data: null, formatted: "", type: "unknown", action: "transform", error: "Could not read/parse file" };
225
+ }
226
+ } else if (input.data) {
227
+ try {
228
+ parsed = JSON.parse(input.data);
229
+ } catch {
230
+ return { data: null, formatted: "", type: "unknown", action: "transform", error: "Could not parse data string" };
231
+ }
232
+ } else {
233
+ return { data: null, formatted: "", type: "unknown", action: "transform", error: "Provide file or data" };
234
+ }
235
+ try {
236
+ let current = parsed;
237
+ const steps = [];
238
+ for (const t of input.transforms) {
239
+ current = jmespathSearch(current, t);
240
+ steps.push({ transform: t, result: current });
241
+ }
242
+ const format = input.format ?? "json";
243
+ return {
244
+ data: parsed,
245
+ formatted: formatOutput(current, format),
246
+ type: current === null ? "null" : Array.isArray(current) ? "array" : typeof current,
247
+ action: "transform",
248
+ result: current,
249
+ steps
250
+ };
251
+ } catch (e) {
252
+ return {
253
+ data: null,
254
+ formatted: "",
255
+ type: "unknown",
256
+ action: "transform",
257
+ /* v8 ignore next -- defensive String(e) */
258
+ error: `Transform failed: ${e instanceof Error ? e.message : String(e)}`
259
+ };
260
+ }
261
+ }
262
+ async function executeMerge(input) {
263
+ if (input.base === void 0 || input.patch === void 0) {
264
+ return { data: null, formatted: "", type: "unknown", action: "merge", error: "base and patch are required for action: merge" };
265
+ }
266
+ const conflictResolution = input.conflictResolution ?? "prefer-patch";
267
+ try {
268
+ const result = deepMerge(input.base, input.patch, { conflictResolution });
269
+ const format = input.format ?? "json";
270
+ return {
271
+ data: result,
272
+ formatted: formatOutput(result, format),
273
+ type: result === null ? "null" : Array.isArray(result) ? "array" : typeof result,
274
+ action: "merge",
275
+ result
276
+ };
277
+ } catch (e) {
278
+ return {
279
+ data: null,
280
+ formatted: "",
281
+ type: "unknown",
282
+ action: "merge",
283
+ /* v8 ignore next -- defensive String(e) */
284
+ error: `Merge failed: ${e instanceof Error ? e.message : String(e)}`
285
+ };
286
+ }
287
+ }
288
+ function jmespathSearch(data, query) {
289
+ if (!query || query === "@") return data;
290
+ if (query === "$") return data;
291
+ const dotMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)(?:\.(.+))?$/);
292
+ if (dotMatch) {
293
+ const key = dotMatch[1];
294
+ const rest = dotMatch[2];
295
+ const val = data?.[key];
296
+ if (rest === void 0) return val;
297
+ return jmespathSearch(val, rest);
298
+ }
299
+ const arrMatch = query.match(/^\[(\d+)\](?:\.(.+))?$/);
300
+ if (arrMatch) {
301
+ const idx = Number.parseInt(arrMatch[1], 10);
302
+ const rest = arrMatch[2];
303
+ const arr = data;
304
+ const val = arr?.[idx];
305
+ if (rest === void 0) return val;
306
+ return jmespathSearch(val, rest);
307
+ }
308
+ if (query === "[*]") {
309
+ if (Array.isArray(data)) {
310
+ return data;
311
+ }
312
+ return data;
313
+ }
314
+ const multiMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\[\*\](?:\.(.+))?$/);
315
+ if (multiMatch) {
316
+ const key = multiMatch[1];
317
+ const rest = multiMatch[2];
318
+ const arr = data?.[key];
319
+ if (!Array.isArray(arr)) return [];
320
+ if (rest === void 0) return arr;
321
+ return arr.map((item) => jmespathSearch(item, rest));
322
+ }
323
+ const filterMatch = query.match(/^\[\\?([a-zA-Z_][a-zA-Z0-9_]*)(==|!=|<|>|<=|>=)(`[^`]+`|'[^']*')\](?:\.(.+))?$/);
324
+ if (filterMatch) {
325
+ const field = filterMatch[1];
326
+ const op = filterMatch[2];
327
+ const rawVal = filterMatch[3];
328
+ const rest = filterMatch[4];
329
+ const cmpVal = JSON.parse(rawVal.slice(1, -1));
330
+ const arr = data;
331
+ if (!Array.isArray(arr)) return [];
332
+ const filtered = arr.filter((item) => {
333
+ const itemVal = item[field];
334
+ switch (op) {
335
+ case "==":
336
+ return itemVal === cmpVal;
337
+ case "!=":
338
+ return itemVal !== cmpVal;
339
+ case ">":
340
+ return Number(itemVal) > Number(cmpVal);
341
+ case "<":
342
+ return Number(itemVal) < Number(cmpVal);
343
+ case ">=":
344
+ return Number(itemVal) >= Number(cmpVal);
345
+ case "<=":
346
+ return Number(itemVal) <= Number(cmpVal);
347
+ /* v8 ignore next -- op is constrained to the six operators by the filter regex; default is unreachable. */
348
+ default:
349
+ return true;
350
+ }
351
+ });
352
+ if (rest === void 0) return filtered;
353
+ return filtered.map((item) => jmespathSearch(item, rest));
354
+ }
355
+ const fnMatch = query.match(/^(length|keys|values|type)\(@\)$/);
356
+ if (fnMatch) {
357
+ const fn = fnMatch[1];
358
+ switch (fn) {
359
+ case "length":
360
+ if (Array.isArray(data)) return data.length;
361
+ if (typeof data === "string") return data.length;
362
+ if (typeof data === "object" && data !== null) return Object.keys(data).length;
363
+ return 0;
364
+ case "keys":
365
+ if (typeof data === "object" && data !== null && !Array.isArray(data)) return Object.keys(data);
366
+ return [];
367
+ case "values":
368
+ if (typeof data === "object" && data !== null && !Array.isArray(data)) return Object.values(data);
369
+ return [];
370
+ case "type":
371
+ if (data === null) return "null";
372
+ if (Array.isArray(data)) return "array";
373
+ return typeof data;
374
+ /* v8 ignore next 2 -- fn is constrained to the four names by the function regex; default is unreachable. */
375
+ default:
376
+ return null;
377
+ }
378
+ }
379
+ return null;
380
+ }
381
+ function validateJsonSchema(data, schema) {
382
+ const errors = [];
383
+ function check(value, s, path) {
384
+ if (s["type"]) {
385
+ const expectedType = s["type"];
386
+ const actualType = Array.isArray(value) ? "array" : value === null ? "null" : typeof value;
387
+ if (expectedType === "integer") {
388
+ if (!Number.isInteger(value)) errors.push(`${path}: expected integer, got ${actualType}`);
389
+ } else if (expectedType !== actualType) {
390
+ errors.push(`${path}: expected ${expectedType}, got ${actualType}`);
391
+ }
392
+ }
393
+ if (typeof value === "string" && s["format"] === "uri" && value) {
394
+ try {
395
+ new URL(value);
396
+ } catch {
397
+ errors.push(`${path}: not a valid URI`);
398
+ }
399
+ }
400
+ if (typeof value === "string" && s["pattern"]) {
401
+ const re = new RegExp(s["pattern"]);
402
+ if (!re.test(value)) errors.push(`${path}: does not match pattern ${s["pattern"]}`);
403
+ }
404
+ if (typeof value === "string" && s["minLength"] !== void 0 && value.length < s["minLength"]) {
405
+ errors.push(`${path}: string too short (min ${s["minLength"]})`);
406
+ }
407
+ if (typeof value === "string" && s["maxLength"] !== void 0 && value.length > s["maxLength"]) {
408
+ errors.push(`${path}: string too long (max ${s["maxLength"]})`);
409
+ }
410
+ if (typeof value === "number" && s["minimum"] !== void 0 && value < s["minimum"]) {
411
+ errors.push(`${path}: below minimum ${s["minimum"]}`);
412
+ }
413
+ if (typeof value === "number" && s["maximum"] !== void 0 && value > s["maximum"]) {
414
+ errors.push(`${path}: above maximum ${s["maximum"]}`);
415
+ }
416
+ if (Array.isArray(value) && s["items"] && Array.isArray(s["items"])) {
417
+ for (let i = 0; i < value.length; i++) {
418
+ check(value[i], s["items"], `${path}[${i}]`);
419
+ }
420
+ }
421
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && s["properties"]) {
422
+ const props = s["properties"];
423
+ for (const [k, propSchema] of Object.entries(props)) {
424
+ check(value[k], propSchema, `${path}.${k}`);
425
+ }
426
+ }
427
+ }
428
+ check(data, schema, "$");
429
+ return { valid: errors.length === 0, errors };
430
+ }
431
+ function simpleQuery(data, path) {
80
432
  const parts = path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
81
433
  let current = data;
82
434
  for (const part of parts) {
package/dist/json.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/json.ts"],"names":[],"mappings":"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","file":"json.js","sourcesContent":["import * as fs from 'node:fs/promises';\nimport type { Tool } from '@wrongstack/core';\n\ninterface JsonInput {\n file?: string | undefined;\n data?: string | undefined;\n query?: string | undefined;\n format?: 'json' | 'json5' | 'yaml' | undefined;\n validate?: boolean | undefined;\n}\n\ninterface JsonOutput {\n data: unknown;\n formatted: string;\n type: string;\n keys?: string[] | undefined;\n query_result?: unknown | undefined;\n error?: string | undefined;\n}\n\nexport const jsonTool: Tool<JsonInput, JsonOutput> = {\n name: 'json',\n category: 'Data',\n description:\n 'Parse, pretty-print, query, and convert between JSON, JSON5, and YAML. Supports simple path-based queries.',\n usageHint:\n 'VERY USEFUL FOR DATA INSPECTION:\\n\\n' +\n '- Use on package.json, tsconfig, config files, or any structured data.\\n' +\n '- `query` lets you extract specific values without reading the whole file.\\n' +\n '- Great for validating that a file has the expected structure.\\n' +\n 'Prefer this over raw `read` + manual parsing when dealing with configuration or data files.',\n permission: 'auto',\n mutating: false,\n timeoutMs: 5_000,\n capabilities: ['fs.read'],\n icon: 'json',\n inputSchema: {\n type: 'object',\n properties: {\n file: { type: 'string', description: 'Path to JSON/JSON5/YAML file' },\n data: { type: 'string', description: 'JSON/JSON5/YAML string (alternative to file)' },\n query: {\n type: 'string',\n description: 'JMESPath-like query (e.g. \"a.b[0].c\" or \"a[*].name\")',\n },\n format: {\n type: 'string',\n enum: ['json', 'json5', 'yaml'],\n description: 'Output format (default: json)',\n },\n validate: {\n type: 'boolean',\n description: 'Validate syntax only, no output (default: false)',\n },\n },\n },\n async execute(input) {\n const format = input.format ?? 'json';\n\n let parsed: unknown;\n let raw: string;\n\n if (input.file) {\n try {\n raw = await fs.readFile(input.file, 'utf8');\n } catch {\n return { data: null, formatted: '', type: 'unknown', error: `Could not read file` };\n }\n } else if (input.data) {\n raw = input.data;\n } else {\n return { data: null, formatted: '', type: 'unknown', error: 'Provide file or data' };\n }\n\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n return {\n data: null,\n formatted: '',\n type: 'unknown',\n /* v8 ignore next -- JSON.parse only throws SyntaxError (an Error); the String(e) side is defensive. */\n error: `Parse failed: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n\n if (input.validate) {\n return {\n data: parsed,\n formatted: 'valid',\n type: Array.isArray(parsed) ? 'array' : typeof parsed,\n keys:\n typeof parsed === 'object' && parsed !== null ? Object.keys(parsed as object) : undefined,\n };\n }\n\n const queryResult = input.query ? query(parsed, input.query) : undefined;\n const formatted = formatOutput(queryResult ?? parsed, format);\n\n return {\n data: parsed,\n formatted,\n type: Array.isArray(parsed) ? 'array' : typeof parsed,\n keys:\n typeof parsed === 'object' && parsed !== null ? Object.keys(parsed as object) : undefined,\n query_result: queryResult,\n };\n },\n};\n\nfunction query(data: unknown, path: string): unknown {\n const parts = path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean);\n let current: unknown = data;\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n\n const idx = Number(part);\n if (!Number.isNaN(idx) && Array.isArray(current)) {\n current = current[idx];\n } else if (typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\nfunction formatOutput(data: unknown, format: string): string {\n if (format === 'json5') {\n return JSON.stringify(data, null, 2)\n .replace(/,\\s*}/g, '}')\n .replace(/,\\s*\\]/g, ']');\n }\n if (format === 'yaml') {\n return toYaml(data);\n }\n return JSON.stringify(data, null, 2);\n}\n\nfunction toYaml(data: unknown, indent = 0): string {\n if (data === null) return 'null\\n';\n /* v8 ignore next -- parsed JSON never contains `undefined`; defensive for recursive calls. */\n if (data === undefined) return '';\n if (typeof data === 'boolean') return String(data) + '\\n';\n if (typeof data === 'number') return String(data) + '\\n';\n if (typeof data === 'string') {\n if (data.includes('\\n') || data.includes(':') || data.includes('#')) {\n return `\"${data.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"\\n`;\n }\n return data + '\\n';\n }\n if (Array.isArray(data)) {\n if (data.length === 0) return '[]\\n';\n const prefix = ' '.repeat(indent);\n return data.map((item) => `${prefix}- ${toYaml(item, indent + 1).trimStart()}`).join('');\n }\n if (typeof data === 'object') {\n const prefix = ' '.repeat(indent);\n const entries = Object.entries(data as Record<string, unknown>);\n return entries.map(([k, v]) => `${prefix}${k}: ${toYaml(v, indent + 1)}`).join('');\n }\n /* v8 ignore next -- JSON.parse only yields null/bool/number/string/array/object; this fallback is defensive. */\n return String(data) + '\\n';\n}\n"]}
1
+ {"version":3,"sources":["../src/json.ts"],"names":["formatted","deepMergeCore"],"mappings":"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","file":"json.js","sourcesContent":["import * as fs from 'node:fs/promises';\nimport { deepMerge as deepMergeCore } from '@wrongstack/core';\nimport type { Tool } from '@wrongstack/core';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype JsonAction = 'parse' | 'query' | 'validate' | 'transform' | 'merge';\n\ninterface JsonInput {\n /** Operation to perform. Defaults to 'parse'. */\n action?: JsonAction | undefined;\n\n // --- parse / query / validate (single data source) ---\n /** Path to JSON/JSON5/YAML file (alternative to `data`). */\n file?: string | undefined;\n /** Inline JSON/JSON5/YAML string (alternative to `file`). */\n data?: string | undefined;\n /** Output format for parse/query/transform results. */\n format?: 'json' | 'json5' | 'yaml' | undefined;\n\n // --- parse: validate syntax only ---\n validate?: boolean | undefined;\n\n // --- query / transform ---\n /** JMESPath-like query expression. */\n query?: string | undefined;\n /** Ordered JMESPath transforms (transform action only). */\n transforms?: string[] | undefined;\n\n // --- validate against schema ---\n /** JSON Schema to validate against. */\n schema?: Record<string, unknown> | undefined;\n\n // --- merge ---\n /** Base object for merge. */\n base?: unknown | undefined;\n /** Patch object for merge. */\n patch?: unknown | undefined;\n /** Merge conflict resolution: 'prefer-patch' (default) or 'prefer-base'. */\n conflictResolution?: 'prefer-base' | 'prefer-patch' | undefined;\n}\n\ninterface JsonOutput {\n data: unknown;\n formatted: string;\n type: string;\n action: string;\n keys?: string[] | undefined;\n query_result?: unknown | undefined;\n result?: unknown | undefined;\n valid?: boolean | undefined;\n errors?: string[] | undefined;\n steps?: Array<{ transform: string; result: unknown }> | undefined;\n error?: string | undefined;\n}\n\nexport const jsonTool: Tool<JsonInput, JsonOutput> = {\n name: 'json',\n category: 'Data',\n description:\n 'Parse, pretty-print, query, validate, transform, and merge JSON/JSON5/YAML. Use `action` to select the operation: parse (default), query, validate, transform, or merge.',\n usageHint:\n 'VERY USEFUL FOR DATA INSPECTION:\\n\\n' +\n '- `action: \"parse\"` (default): read/pretty-print/convert JSON, JSON5, or YAML from `file` or `data`.\\n' +\n '- `action: \"query\"`: JMESPath-like query (`a.b[0].c`, `items[*].name`, filters, functions).\\n' +\n '- `action: \"validate\"`: validate data against a JSON Schema (`schema` param).\\n' +\n '- `action: \"transform\"`: chain multiple JMESPath transforms (`transforms` param).\\n' +\n '- `action: \"merge\"`: deep merge `base` and `patch` objects (`conflictResolution` param).\\n' +\n 'Prefer this over raw `read` + manual parsing when dealing with configuration or data files.',\n permission: 'auto',\n mutating: false,\n timeoutMs: 5_000,\n capabilities: ['fs.read'],\n icon: 'json',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['parse', 'query', 'validate', 'transform', 'merge'],\n description: 'Operation (default: parse). parse=read/pretty-print, query=JMESPath, validate=schema, transform=chained queries, merge=deep merge.',\n },\n file: { type: 'string', description: 'Path to JSON/JSON5/YAML file (parse/query/validate)' },\n data: { type: 'string', description: 'JSON/JSON5/YAML string (parse/query/validate, alternative to file)' },\n format: {\n type: 'string',\n enum: ['json', 'json5', 'yaml'],\n description: 'Output format for parse/query/transform (default: json)',\n },\n query: {\n type: 'string',\n description: 'JMESPath-like query expression (query action)',\n },\n transforms: {\n type: 'array',\n items: { type: 'string' },\n description: 'Ordered JMESPath query strings (transform action)',\n },\n schema: {\n type: 'object',\n description: 'JSON Schema to validate against (validate action)',\n },\n base: { description: 'Base JSON object (merge action)' },\n patch: { description: 'Patch JSON object to merge in (merge action)' },\n conflictResolution: {\n type: 'string',\n enum: ['prefer-base', 'prefer-patch'],\n description: 'Merge conflict resolution (default: prefer-patch)',\n },\n validate: {\n type: 'boolean',\n description: 'Validate syntax only, no output (parse action, default: false)',\n },\n },\n },\n async execute(input) {\n const action = input.action ?? 'parse';\n\n switch (action) {\n case 'query':\n return executeQuery(input);\n case 'validate':\n return executeValidate(input);\n case 'transform':\n return executeTransform(input);\n case 'merge':\n return executeMerge(input);\n case 'parse':\n default:\n return executeParse(input);\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Action: parse (default — the original json tool behavior)\n// ---------------------------------------------------------------------------\n\nasync function executeParse(input: JsonInput): Promise<JsonOutput> {\n const format = input.format ?? 'json';\n\n let parsed: unknown;\n let raw: string;\n\n if (input.file) {\n try {\n raw = await fs.readFile(input.file, 'utf8');\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'parse', error: 'Could not read file' };\n }\n } else if (input.data) {\n raw = input.data;\n } else {\n return { data: null, formatted: '', type: 'unknown', action: 'parse', error: 'Provide file or data' };\n }\n\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n return {\n data: null,\n formatted: '',\n type: 'unknown',\n action: 'parse',\n /* v8 ignore next -- JSON.parse only throws SyntaxError (an Error); the String(e) side is defensive. */\n error: `Parse failed: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n\n if (input.validate) {\n return {\n data: parsed,\n formatted: 'valid',\n type: Array.isArray(parsed) ? 'array' : typeof parsed,\n action: 'parse',\n keys:\n typeof parsed === 'object' && parsed !== null ? Object.keys(parsed as object) : undefined,\n };\n }\n\n // Backward compat: if `query` is provided without an explicit action,\n // use the original simple path-based query (supports `a.b[0].c` notation).\n if (input.query) {\n const queryResult = simpleQuery(parsed, input.query);\n const formatted = formatOutput(queryResult, format);\n return {\n data: parsed,\n formatted,\n type: Array.isArray(parsed) ? 'array' : typeof parsed,\n action: 'parse',\n keys:\n typeof parsed === 'object' && parsed !== null ? Object.keys(parsed as object) : undefined,\n query_result: queryResult,\n };\n }\n\n const formatted = formatOutput(parsed, format);\n\n return {\n data: parsed,\n formatted,\n type: Array.isArray(parsed) ? 'array' : typeof parsed,\n action: 'parse',\n keys:\n typeof parsed === 'object' && parsed !== null ? Object.keys(parsed as object) : undefined,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Action: query (JMESPath-like — from json-path plugin)\n// ---------------------------------------------------------------------------\n\nasync function executeQuery(input: JsonInput): Promise<JsonOutput> {\n if (!input.query) {\n return { data: null, formatted: '', type: 'unknown', action: 'query', error: 'query is required for action: query' };\n }\n\n let parsed: unknown;\n if (input.file) {\n try {\n const raw = await fs.readFile(input.file, 'utf8');\n parsed = JSON.parse(raw);\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'query', error: 'Could not read/parse file' };\n }\n } else if (input.data) {\n try {\n parsed = JSON.parse(input.data);\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'query', error: 'Could not parse data string' };\n }\n } else {\n return { data: null, formatted: '', type: 'unknown', action: 'query', error: 'Provide file or data' };\n }\n\n try {\n const result = jmespathSearch(parsed, input.query);\n const format = input.format ?? 'json';\n return {\n data: parsed,\n formatted: formatOutput(result, format),\n type: result === null ? 'null' : Array.isArray(result) ? 'array' : typeof result,\n action: 'query',\n query_result: result,\n };\n } catch (e) {\n return {\n data: null,\n formatted: '',\n type: 'unknown',\n action: 'query',\n /* v8 ignore next -- defensive String(e) */\n error: `Query failed: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Action: validate (JSON Schema — from json-path plugin)\n// ---------------------------------------------------------------------------\n\nasync function executeValidate(input: JsonInput): Promise<JsonOutput> {\n if (!input.schema) {\n return { data: null, formatted: '', type: 'unknown', action: 'validate', error: 'schema is required for action: validate' };\n }\n\n let parsed: unknown;\n if (input.file) {\n try {\n const raw = await fs.readFile(input.file, 'utf8');\n parsed = JSON.parse(raw);\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'validate', error: 'Could not read/parse file' };\n }\n } else if (input.data) {\n try {\n parsed = JSON.parse(input.data);\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'validate', error: 'Could not parse data string' };\n }\n } else {\n return { data: null, formatted: '', type: 'unknown', action: 'validate', error: 'Provide file or data' };\n }\n\n try {\n const { valid, errors } = validateJsonSchema(parsed, input.schema as Record<string, unknown>);\n return {\n data: parsed,\n formatted: valid ? 'valid' : 'invalid',\n type: Array.isArray(parsed) ? 'array' : typeof parsed,\n action: 'validate',\n valid,\n errors,\n };\n } catch (e) {\n return {\n data: null,\n formatted: '',\n type: 'unknown',\n action: 'validate',\n /* v8 ignore next -- defensive String(e) */\n error: `Validation failed: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Action: transform (chained JMESPath — from json-path plugin)\n// ---------------------------------------------------------------------------\n\nasync function executeTransform(input: JsonInput): Promise<JsonOutput> {\n if (!input.transforms || input.transforms.length === 0) {\n return { data: null, formatted: '', type: 'unknown', action: 'transform', error: 'transforms array is required for action: transform' };\n }\n\n let parsed: unknown;\n if (input.file) {\n try {\n const raw = await fs.readFile(input.file, 'utf8');\n parsed = JSON.parse(raw);\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'transform', error: 'Could not read/parse file' };\n }\n } else if (input.data) {\n try {\n parsed = JSON.parse(input.data);\n } catch {\n return { data: null, formatted: '', type: 'unknown', action: 'transform', error: 'Could not parse data string' };\n }\n } else {\n return { data: null, formatted: '', type: 'unknown', action: 'transform', error: 'Provide file or data' };\n }\n\n try {\n let current: unknown = parsed;\n const steps: Array<{ transform: string; result: unknown }> = [];\n\n for (const t of input.transforms) {\n current = jmespathSearch(current, t);\n steps.push({ transform: t, result: current });\n }\n\n const format = input.format ?? 'json';\n return {\n data: parsed,\n formatted: formatOutput(current, format),\n type: current === null ? 'null' : Array.isArray(current) ? 'array' : typeof current,\n action: 'transform',\n result: current,\n steps,\n };\n } catch (e) {\n return {\n data: null,\n formatted: '',\n type: 'unknown',\n action: 'transform',\n /* v8 ignore next -- defensive String(e) */\n error: `Transform failed: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Action: merge (deep merge — from json-path plugin)\n// ---------------------------------------------------------------------------\n\nasync function executeMerge(input: JsonInput): Promise<JsonOutput> {\n if (input.base === undefined || input.patch === undefined) {\n return { data: null, formatted: '', type: 'unknown', action: 'merge', error: 'base and patch are required for action: merge' };\n }\n\n const conflictResolution = input.conflictResolution ?? 'prefer-patch';\n\n try {\n const result = deepMergeCore(input.base, input.patch, { conflictResolution });\n const format = input.format ?? 'json';\n return {\n data: result,\n formatted: formatOutput(result, format),\n type: result === null ? 'null' : Array.isArray(result) ? 'array' : typeof result,\n action: 'merge',\n result,\n };\n } catch (e) {\n return {\n data: null,\n formatted: '',\n type: 'unknown',\n action: 'merge',\n /* v8 ignore next -- defensive String(e) */\n error: `Merge failed: ${e instanceof Error ? e.message : String(e)}`,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// JMESPath implementation (from json-path plugin)\n// ---------------------------------------------------------------------------\n\nfunction jmespathSearch(data: unknown, query: string): unknown {\n // Handle basic JMESPath expressions\n if (!query || query === '@') return data;\n\n // Root access\n if (query === '$') return data;\n\n // Dot notation: foo.bar\n const dotMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)(?:\\.(.+))?$/);\n if (dotMatch) {\n const key = dotMatch[1]!;\n const rest = dotMatch[2];\n const val = (data as Record<string, unknown> | undefined)?.[key];\n if (rest === undefined) return val;\n return jmespathSearch(val, rest);\n }\n\n // Array access: [0]\n const arrMatch = query.match(/^\\[(\\d+)\\](?:\\.(.+))?$/);\n if (arrMatch) {\n const idx = Number.parseInt(arrMatch[1]!, 10);\n const rest = arrMatch[2];\n const arr = data as unknown[];\n const val = arr?.[idx];\n if (rest === undefined) return val;\n return jmespathSearch(val, rest);\n }\n\n // Wildcard: [*]\n if (query === '[*]') {\n if (Array.isArray(data)) {\n return data;\n }\n return data;\n }\n\n // Multi-select: foo.bar[*].baz\n const multiMatch = query.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\\[\\*\\](?:\\.(.+))?$/);\n if (multiMatch) {\n const key = multiMatch[1]!;\n const rest = multiMatch[2];\n const arr = (data as Record<string, unknown[]> | undefined)?.[key];\n if (!Array.isArray(arr)) return [];\n if (rest === undefined) return arr;\n return arr.map((item) => jmespathSearch(item, rest));\n }\n\n // Filter: [?foo==`bar`]\n const filterMatch = query.match(/^\\[\\\\?([a-zA-Z_][a-zA-Z0-9_]*)(==|!=|<|>|<=|>=)(`[^`]+`|'[^']*')\\](?:\\.(.+))?$/);\n if (filterMatch) {\n const field = filterMatch[1]!;\n const op = filterMatch[2]!;\n const rawVal = filterMatch[3]!;\n const rest = filterMatch[4];\n const cmpVal = JSON.parse(rawVal.slice(1, -1));\n const arr = data as Record<string, unknown>[];\n if (!Array.isArray(arr)) return [];\n const filtered = arr.filter((item) => {\n const itemVal = (item as Record<string, unknown>)[field];\n switch (op) {\n case '==': return itemVal === cmpVal;\n case '!=': return itemVal !== cmpVal;\n case '>': return Number(itemVal) > Number(cmpVal);\n case '<': return Number(itemVal) < Number(cmpVal);\n case '>=': return Number(itemVal) >= Number(cmpVal);\n case '<=': return Number(itemVal) <= Number(cmpVal);\n /* v8 ignore next -- op is constrained to the six operators by the filter regex; default is unreachable. */\n default: return true;\n }\n });\n if (rest === undefined) return filtered;\n return filtered.map((item) => jmespathSearch(item, rest));\n }\n\n // Function calls: length(@)\n const fnMatch = query.match(/^(length|keys|values|type)\\(@\\)$/);\n if (fnMatch) {\n const fn = fnMatch[1]!;\n switch (fn) {\n case 'length':\n if (Array.isArray(data)) return data.length;\n if (typeof data === 'string') return data.length;\n if (typeof data === 'object' && data !== null) return Object.keys(data as object).length;\n return 0;\n case 'keys':\n if (typeof data === 'object' && data !== null && !Array.isArray(data)) return Object.keys(data as object);\n return [];\n case 'values':\n if (typeof data === 'object' && data !== null && !Array.isArray(data)) return Object.values(data as object);\n return [];\n case 'type':\n if (data === null) return 'null';\n if (Array.isArray(data)) return 'array';\n return typeof data;\n /* v8 ignore next 2 -- fn is constrained to the four names by the function regex; default is unreachable. */\n default:\n return null;\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// JSON Schema validator (from json-path plugin)\n// ---------------------------------------------------------------------------\n\nfunction validateJsonSchema(data: unknown, schema: Record<string, unknown>): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n function check(value: unknown, s: Record<string, unknown>, path: string): void {\n if (s['type']) {\n const expectedType = s['type'] as string;\n const actualType = Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value;\n if (expectedType === 'integer') {\n if (!Number.isInteger(value)) errors.push(`${path}: expected integer, got ${actualType}`);\n } else if (expectedType !== actualType) {\n errors.push(`${path}: expected ${expectedType}, got ${actualType}`);\n }\n }\n\n if (typeof value === 'string' && s['format'] === 'uri' && value) {\n try { new URL(value); } catch { errors.push(`${path}: not a valid URI`); }\n }\n\n if (typeof value === 'string' && s['pattern']) {\n const re = new RegExp(s['pattern'] as string);\n if (!re.test(value)) errors.push(`${path}: does not match pattern ${s['pattern']}`);\n }\n\n if (typeof value === 'string' && s['minLength'] !== undefined && value.length < (s['minLength'] as number)) {\n errors.push(`${path}: string too short (min ${s['minLength']})`);\n }\n\n if (typeof value === 'string' && s['maxLength'] !== undefined && value.length > (s['maxLength'] as number)) {\n errors.push(`${path}: string too long (max ${s['maxLength']})`);\n }\n\n if (typeof value === 'number' && s['minimum'] !== undefined && value < (s['minimum'] as number)) {\n errors.push(`${path}: below minimum ${s['minimum']}`);\n }\n\n if (typeof value === 'number' && s['maximum'] !== undefined && value > (s['maximum'] as number)) {\n errors.push(`${path}: above maximum ${s['maximum']}`);\n }\n\n if (Array.isArray(value) && s['items'] && Array.isArray(s['items'])) {\n for (let i = 0; i < value.length; i++) {\n check(value[i], s['items'] as never as Record<string, unknown>, `${path}[${i}]`);\n }\n }\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value) && s['properties']) {\n const props = s['properties'] as Record<string, Record<string, unknown>>;\n for (const [k, propSchema] of Object.entries(props)) {\n check((value as Record<string, unknown>)[k], propSchema, `${path}.${k}`);\n }\n }\n }\n\n check(data, schema, '$');\n return { valid: errors.length === 0, errors };\n}\n\n// ---------------------------------------------------------------------------\n// Simple path-based query (original json tool query, backward compat)\n// ---------------------------------------------------------------------------\n\nfunction simpleQuery(data: unknown, path: string): unknown {\n const parts = path\n .replace(/\\[(\\d+)\\]/g, '.$1')\n .split('.')\n .filter(Boolean);\n let current: unknown = data;\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n\n const idx = Number(part);\n if (!Number.isNaN(idx) && Array.isArray(current)) {\n current = current[idx];\n } else if (typeof current === 'object' && current !== null) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// Output formatting (original json tool helpers)\n// ---------------------------------------------------------------------------\n\nfunction formatOutput(data: unknown, format: string): string {\n if (format === 'json5') {\n return JSON.stringify(data, null, 2)\n .replace(/,\\s*}/g, '}')\n .replace(/,\\s*\\]/g, ']');\n }\n if (format === 'yaml') {\n return toYaml(data);\n }\n return JSON.stringify(data, null, 2);\n}\n\nfunction toYaml(data: unknown, indent = 0): string {\n if (data === null) return 'null\\n';\n /* v8 ignore next -- parsed JSON never contains `undefined`; defensive for recursive calls. */\n if (data === undefined) return '';\n if (typeof data === 'boolean') return String(data) + '\\n';\n if (typeof data === 'number') return String(data) + '\\n';\n if (typeof data === 'string') {\n if (data.includes('\\n') || data.includes(':') || data.includes('#')) {\n return `\"${data.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"\\n`;\n }\n return data + '\\n';\n }\n if (Array.isArray(data)) {\n if (data.length === 0) return '[]\\n';\n const prefix = ' '.repeat(indent);\n return data.map((item) => `${prefix}- ${toYaml(item, indent + 1).trimStart()}`).join('');\n }\n if (typeof data === 'object') {\n const prefix = ' '.repeat(indent);\n const entries = Object.entries(data as Record<string, unknown>);\n return entries.map(([k, v]) => `${prefix}${k}: ${toYaml(v, indent + 1)}`).join('');\n }\n /* v8 ignore next -- JSON.parse only yields null/bool/number/string/array/object; this fallback is defensive. */\n return String(data) + '\\n';\n}\n"]}