@j0hanz/fetch-url-mcp 1.11.1 → 1.11.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"task-handlers.d.ts","sourceRoot":"","sources":["../../src/lib/task-handlers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkCzE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAoC/B,UAAU,8BAA8B;IACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,6BAA6B;IACrC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,0BAA0B,EAAE,OAAO,CAAC;CACrC;AACD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,CAAC,EAAE,8BAA8B,GACvC,6BAA6B,CA+J/B"}
1
+ {"version":3,"file":"task-handlers.d.ts","sourceRoot":"","sources":["../../src/lib/task-handlers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkCzE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AA4D/B,UAAU,8BAA8B;IACtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,6BAA6B;IACrC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,0BAA0B,EAAE,OAAO,CAAC;CACrC;AACD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,OAAO,CAAC,EAAE,8BAA8B,GACvC,6BAA6B,CA+J/B"}
@@ -14,25 +14,25 @@ export { cancelTasksForOwner, abortAllTaskExecutions, } from '../tasks/execution
14
14
  * Task handler schemas and registration
15
15
  * ------------------------------------------------------------------------------------------------- */
16
16
  const TaskGetSchema = z.looseObject({
17
- method: z.literal('tasks/get'),
18
- params: z.looseObject({ taskId: z.string() }),
19
- });
17
+ method: z.literal('tasks/get', 'Expected "tasks/get"'),
18
+ params: z.looseObject({ taskId: z.string('Expected string') }, 'Expected object'),
19
+ }, 'Invalid request');
20
20
  const TaskListSchema = z.looseObject({
21
- method: z.literal('tasks/list'),
21
+ method: z.literal('tasks/list', 'Expected "tasks/list"'),
22
22
  params: z
23
23
  .looseObject({
24
- cursor: z.string().optional(),
25
- })
24
+ cursor: z.string('Expected string').optional(),
25
+ }, 'Expected object')
26
26
  .optional(),
27
- });
27
+ }, 'Invalid request');
28
28
  const TaskCancelSchema = z.looseObject({
29
- method: z.literal('tasks/cancel'),
30
- params: z.looseObject({ taskId: z.string() }),
31
- });
29
+ method: z.literal('tasks/cancel', 'Expected "tasks/cancel"'),
30
+ params: z.looseObject({ taskId: z.string('Expected string') }, 'Expected object'),
31
+ }, 'Invalid request');
32
32
  const TaskResultSchema = z.looseObject({
33
- method: z.literal('tasks/result'),
34
- params: z.looseObject({ taskId: z.string() }),
35
- });
33
+ method: z.literal('tasks/result', 'Expected "tasks/result"'),
34
+ params: z.looseObject({ taskId: z.string('Expected string') }, 'Expected object'),
35
+ }, 'Invalid request');
36
36
  function resolveOwnerScopedExtra(extra) {
37
37
  const parsedExtra = parseHandlerExtra(extra);
38
38
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAoD9D,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAG9D,CAAC;AAgBJ,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,SAAS,CAQ/B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;AAUD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,eAAO,MAAM,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAM1D,CAAC;AAwCL,eAAO,MAAM,mBAAmB;;;kBAU9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;kBAqC/B,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAkBpE;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAChD,MAAM,CAER;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC7D,MAAM,GAAG,IAAI,CAEf"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAoD9D,eAAO,MAAM,uBAAuB,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAG9D,CAAC;AAgBJ,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,SAAS,CAQ/B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;AAUD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,eAAO,MAAM,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAM1D,CAAC;AAwCL,eAAO,MAAM,mBAAmB;;;kBAgB/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;kBAqC/B,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAkBpE;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,GAChD,MAAM,CAER;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC7D,MAAM,GAAG,IAAI,CAEf"}
package/dist/schemas.js CHANGED
@@ -96,15 +96,15 @@ const cachedPayloadSchema = cachedPayloadCompatSchema
96
96
  }));
97
97
  export const fetchUrlInputSchema = z.strictObject({
98
98
  url: z
99
- .httpUrl()
100
- .min(1)
101
- .max(config.constants.maxUrlLength)
99
+ .httpUrl('Expected HTTP or HTTPS URL')
100
+ .min(1, 'URL required')
101
+ .max(config.constants.maxUrlLength, `URL exceeds ${config.constants.maxUrlLength} chars`)
102
102
  .describe(`Target URL. Max ${config.constants.maxUrlLength} chars.`),
103
103
  forceRefresh: z
104
- .boolean()
104
+ .boolean('Expected boolean')
105
105
  .optional()
106
106
  .describe('Bypass cache and fetch fresh content.'),
107
- });
107
+ }, 'Invalid input');
108
108
  export const fetchUrlOutputSchema = z.strictObject({
109
109
  url: z.httpUrl().max(config.constants.maxUrlLength).describe('Fetched URL.'),
110
110
  inputUrl: z
@@ -1 +1 @@
1
- {"version":3,"file":"call-contract.d.ts","sourceRoot":"","sources":["../../src/tasks/call-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;iBAiBxC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7E,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,OAAO,GACf,uBAAuB,CAQzB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,CAAC,EAAE,mBAAmB,GACzB,mBAAmB,GAAG,SAAS,CAMjC;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,mBAAmB,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,YAAY,CAQd"}
1
+ {"version":3,"file":"call-contract.d.ts","sourceRoot":"","sources":["../../src/tasks/call-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;iBA4BzC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;AAE7E,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,OAAO,GACf,uBAAuB,CAQzB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,CAAC,EAAE,mBAAmB,GACzB,mBAAmB,GAAG,SAAS,CAMjC;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,mBAAmB,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,GACb,YAAY,CAQd"}
@@ -11,23 +11,25 @@ const toolCallMetaSchema = z.looseObject({
11
11
  'io.modelcontextprotocol/related-task': relatedTaskMetaSchema.optional(),
12
12
  });
13
13
  export const extendedCallToolRequestSchema = z.looseObject({
14
- method: z.literal('tools/call'),
14
+ method: z.literal('tools/call', 'Expected "tools/call"'),
15
15
  params: z.strictObject({
16
- name: z.string().min(1),
17
- arguments: z.record(z.string(), z.unknown()).optional(),
16
+ name: z.string('Expected string').min(1, 'Tool name required'),
17
+ arguments: z
18
+ .record(z.string(), z.unknown(), 'Expected object')
19
+ .optional(),
18
20
  task: z
19
21
  .strictObject({
20
22
  ttl: z
21
- .number()
22
- .int()
23
- .min(MIN_TASK_TTL_MS)
24
- .max(MAX_TASK_TTL_MS)
23
+ .number('Expected number (ms)')
24
+ .int('Expected integer')
25
+ .min(MIN_TASK_TTL_MS, `Minimum ${MIN_TASK_TTL_MS}ms`)
26
+ .max(MAX_TASK_TTL_MS, `Maximum ${MAX_TASK_TTL_MS}ms`)
25
27
  .optional(),
26
- })
28
+ }, 'Expected object')
27
29
  .optional(),
28
30
  _meta: toolCallMetaSchema.optional(),
29
- }),
30
- });
31
+ }, 'Expected object'),
32
+ }, 'Invalid tool call request');
31
33
  export function parseExtendedCallToolRequest(request) {
32
34
  const parsed = extendedCallToolRequestSchema.safeParse(request);
33
35
  if (parsed.success)
@@ -1,7 +1,7 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { ContentBlock } from '@modelcontextprotocol/sdk/types.js';
3
3
  import type { ServerResult } from '@modelcontextprotocol/sdk/types.js';
4
- import { z } from 'zod';
4
+ import type { z } from 'zod';
5
5
  import type { SharedFetchStage } from '../lib/fetch-pipeline.js';
6
6
  import { type ToolHandlerExtra } from '../lib/progress.js';
7
7
  import type { ProgressReporter } from '../lib/progress.js';
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-url.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,oCAAoC,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAU3D,OAAO,EACL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIL,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAE9B,KAAK,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEzD,UAAU,gBAAgB;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAwI/C,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,YAAY,GACnB,MAAM,GAAG,SAAS,CAUpB;AAED,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,WAAW,CAA0B;gBAG1B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM;IAGlC,WAAW,IAAI,IAAI;IAInB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAO1C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIxC,aAAa,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAIvC,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,QAAQ;CAmCjB;AAuED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAqBD,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;CAC3D;AAqBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,wBAAwB,CAmCzE"}
1
+ {"version":3,"file":"fetch-url.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,oCAAoC,CAAC;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAc7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAU3D,OAAO,EACL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAIL,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAC;AAE9B,KAAK,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEzD,UAAU,gBAAgB;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAwI/C,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,YAAY,GACnB,MAAM,GAAG,SAAS,CAUpB;AAED,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,WAAW,CAA0B;gBAG1B,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM;IAGlC,WAAW,IAAI,IAAI;IAInB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAO1C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIxC,aAAa,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAIvC,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,QAAQ;CAmCjB;AAuED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAqBD,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;CAC3D;AAqBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,wBAAwB,CAsCzE"}
@@ -1,5 +1,4 @@
1
1
  import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
2
- import { z } from 'zod';
3
2
  import { config, logDebug, logError, logWarn } from '../lib/core.js';
4
3
  import { finalizeInlineMarkdown, markdownTransform, parseCachedMarkdownResult, performSharedFetch, serializeMarkdownResult, withSignal, } from '../lib/fetch-pipeline.js';
5
4
  import { handleToolError } from '../lib/mcp-tools.js';
@@ -246,7 +245,7 @@ const TOOL_DEFINITION = {
246
245
  title: 'Fetch URL',
247
246
  description: FETCH_URL_TOOL_DESCRIPTION,
248
247
  inputSchema: fetchUrlInputSchema,
249
- outputSchema: z.toJSONSchema(fetchUrlOutputSchema),
248
+ outputSchema: fetchUrlOutputSchema,
250
249
  handler: fetchUrlToolHandler,
251
250
  annotations: {
252
251
  readOnlyHint: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j0hanz/fetch-url-mcp",
3
- "version": "1.11.1",
3
+ "version": "1.11.3",
4
4
  "mcpName": "io.github.j0hanz/fetch-url-mcp",
5
5
  "description": "A web content fetcher MCP server that converts HTML to clean, AI and human readable markdown.",
6
6
  "type": "module",
@@ -69,11 +69,11 @@
69
69
  "prepublishOnly": "npm run lint && npm run type-check && npm run build"
70
70
  },
71
71
  "dependencies": {
72
- "@modelcontextprotocol/sdk": "^1.27.1",
72
+ "@modelcontextprotocol/sdk": "^1.28",
73
73
  "@mozilla/readability": "^0.6.0",
74
74
  "linkedom": "^0.18.12",
75
75
  "node-html-markdown": "^2.0.0",
76
- "undici": "^7.24.5",
76
+ "undici": "^7.24.6",
77
77
  "zod": "^4.3.6"
78
78
  },
79
79
  "devDependencies": {
@@ -85,7 +85,7 @@
85
85
  "eslint-plugin-de-morgan": "^2.1.1",
86
86
  "eslint-plugin-depend": "^1.5.0",
87
87
  "eslint-plugin-unused-imports": "^4.4.1",
88
- "knip": "^6.0.4",
88
+ "knip": "^6",
89
89
  "prettier": "^3.8.1",
90
90
  "tsx": "^4.21.0",
91
91
  "typescript": "^5.9.3",