@caeliq/llms 1.0.57 → 1.0.59

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 (75) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +82 -685
  3. package/dist/api/routes.d.ts +2 -0
  4. package/dist/cjs/server.cjs +279 -226
  5. package/dist/cjs/server.cjs.map +4 -4
  6. package/dist/cursor-sdk/hooks-template.d.ts +2 -1
  7. package/dist/cursor-sdk/host-env.d.ts +38 -0
  8. package/dist/cursor-sdk/lifecycle-planner.d.ts +69 -0
  9. package/dist/cursor-sdk/prompt.d.ts +33 -3
  10. package/dist/cursor-sdk/runner.d.ts +29 -0
  11. package/dist/cursor-sdk/session.d.ts +55 -1
  12. package/dist/cursor-sdk/shared.d.ts +14 -0
  13. package/dist/cursor-sdk/tool-paths.d.ts +26 -0
  14. package/dist/cursor-sdk/tools.d.ts +12 -1
  15. package/dist/cursor-sdk/turn-identity.d.ts +46 -0
  16. package/dist/cursor-sdk/turn-output.d.ts +77 -0
  17. package/dist/esm/server.mjs +280 -227
  18. package/dist/esm/server.mjs.map +4 -4
  19. package/dist/routing/inbound-pipeline.d.ts +31 -0
  20. package/dist/routing/protocol-adapter.d.ts +37 -0
  21. package/dist/routing/protocol-endpoints.d.ts +77 -0
  22. package/dist/routing/protocol-errors.d.ts +10 -0
  23. package/dist/server.d.ts +3 -1
  24. package/dist/services/provider.d.ts +1 -1
  25. package/dist/tests/anthropic.provider-wire.d.ts +1 -0
  26. package/dist/tests/anthropic.tool-call-id-sanitize.d.ts +1 -0
  27. package/dist/tests/anthropic.turn-intent.d.ts +1 -0
  28. package/dist/tests/claude-auth.identity.d.ts +1 -0
  29. package/dist/tests/client-abort-classification.test.d.ts +1 -0
  30. package/dist/tests/cursor-sdk.host-env.d.ts +1 -0
  31. package/dist/tests/cursor-sdk.interrupt-reentry.d.ts +1 -0
  32. package/dist/tests/cursor-sdk.lifecycle-planner.d.ts +1 -0
  33. package/dist/tests/cursor-sdk.pending-next-rejection.d.ts +1 -0
  34. package/dist/tests/cursor-sdk.scratch-paths.d.ts +1 -0
  35. package/dist/tests/cursor-sdk.scratch-report.d.ts +1 -0
  36. package/dist/tests/cursor-sdk.tool-call-id.d.ts +1 -0
  37. package/dist/tests/cursor-sdk.trailing-turn-fallback.d.ts +1 -0
  38. package/dist/tests/cursor-sdk.turn-coordination.d.ts +1 -0
  39. package/dist/tests/cursor-sdk.turn-identity.d.ts +1 -0
  40. package/dist/tests/inbound-protocol-routes.d.ts +1 -0
  41. package/dist/tests/inbound-routing-pipeline.d.ts +1 -0
  42. package/dist/tests/openai.inbound-chat.d.ts +1 -0
  43. package/dist/tests/openai.inbound-responses.d.ts +1 -0
  44. package/dist/tests/protocol-endpoints.d.ts +1 -0
  45. package/dist/tests/redact.body-for-log.d.ts +1 -0
  46. package/dist/tests/responses.call-id-sanitize.d.ts +1 -0
  47. package/dist/tests/responses.parallel-and-failure.d.ts +1 -0
  48. package/dist/tests/router-scenario-precedence.d.ts +1 -0
  49. package/dist/tests/stream.upstream-terminated.d.ts +1 -0
  50. package/dist/tests/system-instructions-fold.d.ts +1 -0
  51. package/dist/tests/upstream-error-semantics.d.ts +1 -0
  52. package/dist/transformer/anthropic.transformer.d.ts +16 -3
  53. package/dist/transformer/claude-auth.transformer.d.ts +36 -4
  54. package/dist/transformer/cursor-sdk.transformer.d.ts +4 -2
  55. package/dist/transformer/openai.responses.transformer.d.ts +17 -1
  56. package/dist/transformer/openai.transformer.d.ts +26 -32
  57. package/dist/transformer/tooluse.transformer.d.ts +1 -1
  58. package/dist/transformer/vercel.transformer.d.ts +1 -1
  59. package/dist/transformer/vertex-claude.transformer.d.ts +1 -1
  60. package/dist/transformer/vertex-gemini.transformer.d.ts +1 -1
  61. package/dist/types/transformer.d.ts +15 -0
  62. package/dist/types/turn-intent.d.ts +26 -0
  63. package/dist/utils/claude-auth.d.ts +9 -2
  64. package/dist/utils/claude-billing.d.ts +58 -0
  65. package/dist/utils/claude-model-catalog.d.ts +49 -0
  66. package/dist/utils/headers.d.ts +10 -0
  67. package/dist/utils/mistral.util.d.ts +1 -1
  68. package/dist/utils/openai.responses.util.d.ts +53 -0
  69. package/dist/utils/redact.d.ts +18 -0
  70. package/dist/utils/request.d.ts +1 -1
  71. package/dist/utils/retry.d.ts +7 -0
  72. package/dist/utils/router.d.ts +7 -0
  73. package/dist/utils/stream.d.ts +2 -0
  74. package/dist/utils/toolCallId.d.ts +23 -0
  75. package/package.json +25 -21
@@ -0,0 +1,58 @@
1
+ import { TextContent, UnifiedChatRequest, UnifiedMessage } from "../types/llm";
2
+ /** Salt used in Claude Code's `cc_version` suffix hash (`RYn()`). */
3
+ export declare const BILLING_SALT = "59cf53e54c78";
4
+ export declare const CC_VERSION: string;
5
+ export declare const CC_ENTRYPOINT: string;
6
+ export declare const SYSTEM_IDENTITY = "You are Claude Code, Anthropic's official CLI for Claude.";
7
+ export declare function extractFirstUserMessageText(messages: UnifiedMessage[] | undefined): string;
8
+ export declare function computeVersionSuffix(text: string, version: string): string;
9
+ /** 5 lowercase hex chars, cached per process — not a content hash. */
10
+ export declare function sessionCch(): string;
11
+ export declare function __resetClaudeBillingStateForTests(): void;
12
+ export declare function buildClaudeBillingHeaderValue(messages: UnifiedMessage[] | undefined, version?: string, entrypoint?: string): string;
13
+ /**
14
+ * Normalize `request.system` to an array as a complete ordered fold:
15
+ * top-level `request.system` blocks first, then every `role:"system"` /
16
+ * `role:"developer"` message's text blocks in source order. Consumed messages
17
+ * are removed from `request.messages` so no downstream builder can drop or
18
+ * double-emit them. Block-level `cache_control` is preserved.
19
+ */
20
+ export declare function normalizeSystemToArray(request: UnifiedChatRequest): TextContent[];
21
+ /** Drop any existing billing entry (dedupe) and prepend a fresh one at system[0]. */
22
+ export declare function applyClaudeBillingSystemBlock(system: TextContent[], messages: UnifiedMessage[] | undefined): void;
23
+ /**
24
+ * Insert SYSTEM_IDENTITY as its own entry at system[1]. Any remaining
25
+ * caller system content is left in place here — relocateForeignSystemContent
26
+ * (called separately, afterwards) is what moves it out of system[].
27
+ */
28
+ export declare function applyClaudeSystemIdentity(system: TextContent[]): void;
29
+ /**
30
+ * Move everything in `system[]` past the identity block (index 1) into the
31
+ * first user message instead. Anthropic's OAuth billing validator appears to
32
+ * inspect `system[]` content beyond the identity prefix and reject requests
33
+ * whose system array carries a foreign harness prompt with an "out of extra
34
+ * usage" 400 — the same approach used by third-party Claude Code OAuth
35
+ * clients (e.g. opencode-claude-auth). The relocated text still reaches the
36
+ * model, just as part of the first user turn rather than
37
+ * `system[]`.
38
+ *
39
+ * A no-op when there is no user message to attach the content to, so nothing
40
+ * is silently dropped — the caller's system content stays in `system[]`
41
+ * instead.
42
+ */
43
+ export declare function relocateForeignSystemContent(system: TextContent[], messages: UnifiedMessage[] | undefined): void;
44
+ /**
45
+ * Claude Code's OAuth validator expects tool names in the mcp_PascalCase
46
+ * spelling used by the official CLI. Non-Claude-Code clients commonly send
47
+ * ordinary names such as `bash` or `read`, so normalize them before the
48
+ * Anthropic body is built. The prefix check keeps this operation idempotent.
49
+ */
50
+ export declare function prefixClaudeToolName(name: string): string;
51
+ /** Restore a Claude Code tool name to the caller's original spelling. */
52
+ export declare function unprefixClaudeToolName(name: string): string;
53
+ /** Rewrite tool names in a Unified request in place for the OAuth wire path. */
54
+ export declare function prefixClaudeToolNames(request: UnifiedChatRequest, nameMap?: Map<string, string>): void;
55
+ /** Rewrite tool names in a Unified/OpenAI-shaped response in place. */
56
+ export declare function unprefixClaudeToolNames(value: any, nameMap?: Map<string, string>): void;
57
+ /** Rewrite one OpenAI SSE data payload's tool names. */
58
+ export declare function unprefixClaudeToolNamesInSseData(value: any, nameMap?: Map<string, string>): void;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Claude Code's bundled model capability catalog (extracted from v2.1.220).
3
+ *
4
+ * Every model-dependent decision in the claude-auth impersonation path (beta
5
+ * flags, effort support, thinking shape, max_tokens ceiling) is driven by
6
+ * `capabilities` membership here, never by matching on the model name.
7
+ */
8
+ export interface ClaudeModelCatalogEntry {
9
+ /** Context window in tokens, or undefined when the model predates 1M-context routing. */
10
+ window?: number;
11
+ /** Router carries a native (unconditional) 1M-token context window. */
12
+ nativeOneMillion: boolean;
13
+ /** Model can opt into a 1M-token window via the context-1m-2025-08-07 beta. */
14
+ supportsOneMillionBeta: boolean;
15
+ /** Model id accepts an explicit "[1m]" wire suffix. */
16
+ supportsOneMillionSuffix: boolean;
17
+ maxOutputTokens: {
18
+ default: number;
19
+ upper: number;
20
+ };
21
+ defaultEffort?: string;
22
+ capabilities: string[];
23
+ }
24
+ export declare const CLAUDE_MODEL_CATALOG: Record<string, ClaudeModelCatalogEntry>;
25
+ /** Strip the "[1m]" wire marker, reporting whether it was present. */
26
+ export declare function stripOneMillionContextMarker(modelId: string | undefined): {
27
+ modelId: string;
28
+ requestedOneMillion: boolean;
29
+ };
30
+ /**
31
+ * Normalize a routed model id (CCR "provider,model" selector, an optional
32
+ * "[1m]" marker, and Anthropic's dated model-id suffix) down to a catalog
33
+ * key, e.g. "anthropic,claude-opus-5-20260101[1m]" -> "claude-opus-5".
34
+ */
35
+ export declare function normalizeModelIdForCatalog(modelId: string | undefined): string;
36
+ /** Look up a model's catalog entry. Unknown models resolve to undefined (minimal capability set). */
37
+ export declare function lookupClaudeModelCatalogEntry(modelId: string | undefined): ClaudeModelCatalogEntry | undefined;
38
+ export declare function catalogEntryHasCapability(entry: ClaudeModelCatalogEntry | undefined, capability: string): boolean;
39
+ /**
40
+ * Whether extended-thinking betas apply to this model. The catalog has no
41
+ * dedicated "supports_thinking" column, but every entry that predates the
42
+ * Claude 4 thinking generation (claude-3-5-haiku, claude-3-5-sonnet,
43
+ * claude-3-7-sonnet) — plus the not-yet-classified claude-mythos-5 — carries
44
+ * an empty capability set; every thinking-capable model carries at least
45
+ * "context_management". A non-empty capability set is therefore a reliable,
46
+ * self-documenting proxy that also degrades unknown models to "no thinking"
47
+ * rather than guessing.
48
+ */
49
+ export declare function catalogEntrySupportsThinking(entry: ClaudeModelCatalogEntry | undefined): boolean;
@@ -0,0 +1,10 @@
1
+ export type HeaderRecord = Record<string, string | undefined>;
2
+ export declare function mergeHeadersCaseInsensitive(base: HeaderRecord | undefined, update: HeaderRecord | undefined): HeaderRecord;
3
+ /**
4
+ * Carry non-representational upstream response headers (rate-limit/usage
5
+ * metadata, request ids, etc.) onto a reshaped `Response`, so overage
6
+ * observability (`anthropic-ratelimit-unified-*`) survives SSE re-framing.
7
+ */
8
+ export declare function preserveUpstreamResponseHeaders(headers: Headers | undefined): Record<string, string>;
9
+ export declare function selectSafeDownstreamHeaders(headers: Headers | HeaderRecord | undefined): Record<string, string>;
10
+ export declare function canonicalizeOutboundHeaders(headers: HeaderRecord | undefined, fallbackBearer?: string): Record<string, string>;
@@ -2,7 +2,7 @@ import { UnifiedChatRequest } from "../types/llm";
2
2
  /**
3
3
  * Transform incoming request to Mistral-compatible format
4
4
  */
5
- export declare function buildRequestBody(request: UnifiedChatRequest, context?: any, provider?: any): Record<string, any>;
5
+ export declare function buildRequestBody(request: UnifiedChatRequest, context?: any, _provider?: any): Record<string, any>;
6
6
  /**
7
7
  * Transform a Mistral provider request back into a UnifiedChatRequest
8
8
  */
@@ -0,0 +1,53 @@
1
+ import { UnifiedChatRequest } from "../types/llm";
2
+ export interface ResponsesCallIdMap {
3
+ /** Original client call_id → sanitized id (and reverse). */
4
+ forward: Map<string, string>;
5
+ reverse: Map<string, string>;
6
+ }
7
+ export declare function createCallIdMap(): ResponsesCallIdMap;
8
+ /** Sanitize and remember a stable per-turn mapping for function call correlation. */
9
+ export declare function mapCallId(map: ResponsesCallIdMap, id: unknown, direction?: "client_to_unified" | "unified_to_client"): string | undefined;
10
+ /**
11
+ * Client Responses wire → Unified (Chat Completions shape).
12
+ * Supports the Responses MVP subset; rejects CCR-unsupported stateful fields.
13
+ */
14
+ export declare function responsesRequestToUnified(body: any, callIdMap?: ResponsesCallIdMap): UnifiedChatRequest;
15
+ /** Unified Chat JSON → Responses API non-stream response. */
16
+ export declare function unifiedResponseToResponses(chat: any, options?: {
17
+ originalModel?: string;
18
+ callIdMap?: ResponsesCallIdMap;
19
+ }): any;
20
+ export interface ResponsesStreamState {
21
+ responseId: string;
22
+ model?: string;
23
+ textItemId: string;
24
+ textStarted: boolean;
25
+ textOutputIndex?: number;
26
+ textContent: string;
27
+ toolCalls: Map<number, {
28
+ id: string;
29
+ name: string;
30
+ arguments: string;
31
+ added: boolean;
32
+ outputIndex: number;
33
+ emittedArgumentsLength: number;
34
+ }>;
35
+ nextOutputIndex: number;
36
+ finished: boolean;
37
+ created: boolean;
38
+ sequenceNumber: number;
39
+ finishReasonSeen: boolean;
40
+ usage?: any;
41
+ callIdMap: ResponsesCallIdMap;
42
+ }
43
+ export declare function createResponsesStreamState(options?: {
44
+ model?: string;
45
+ callIdMap?: ResponsesCallIdMap;
46
+ }): ResponsesStreamState;
47
+ /**
48
+ * Convert one Unified Chat Completions chunk into zero or more Responses
49
+ * stream events, including the mandatory content_part lifecycle for Codex.
50
+ */
51
+ export declare function unifiedChunkToResponsesEvents(chunk: any, state: ResponsesStreamState): any[];
52
+ export declare function finalizeResponsesStream(state: ResponsesStreamState, usage?: any): any[];
53
+ export declare function responsesFailedEvent(message: string, state?: ResponsesStreamState): any;
@@ -3,6 +3,24 @@
3
3
  * Keep enough diagnostic signal (status, error type) without leaking secrets.
4
4
  */
5
5
  export declare function sanitizeUpstreamErrorText(value: string): string;
6
+ /**
7
+ * Deep-sanitize a parsed upstream error body before it is logged or
8
+ * serialized to a client: secret-bearing keys are redacted outright and
9
+ * every string value passes through sanitizeUpstreamErrorText. Depth and
10
+ * array length are bounded so an adversarial body cannot balloon.
11
+ */
12
+ export declare function sanitizeUpstreamErrorBody(value: unknown, depth?: number): unknown;
13
+ /** Default cap for a single logged request body. */
14
+ export declare const DEFAULT_LOG_BODY_MAX_BYTES = 32768;
15
+ /**
16
+ * Redact secrets from a request body that is about to be logged verbatim.
17
+ *
18
+ * Unlike sanitizeUpstreamErrorText this preserves whitespace, newlines and
19
+ * full string values: the point of body capture is to read prompts and
20
+ * message content back, so per-string truncation would defeat it. Only
21
+ * secret-bearing patterns are rewritten, then the whole payload is capped.
22
+ */
23
+ export declare function sanitizeBodyForLog(value: string, maxBytes?: number): string;
6
24
  export declare function sanitizeErrorForLog(error: unknown): {
7
25
  message: string;
8
26
  code?: string;
@@ -1,4 +1,4 @@
1
1
  import { UnifiedChatRequest } from "../types/llm";
2
2
  /** Loopback and NO_PROXY/no_proxy hosts should not go through HTTPS_PROXY. */
3
3
  export declare function shouldBypassProxy(target: URL | string): boolean;
4
- export declare function sendUnifiedRequest(url: URL | string, request: UnifiedChatRequest, config: any, context: any, logger?: any): Promise<Response>;
4
+ export declare function sendUnifiedRequest(url: URL | string, request: UnifiedChatRequest, config: any, _context: any, _logger?: any): Promise<Response>;
@@ -24,4 +24,11 @@ export declare function toClientAbortError(reason?: unknown): Error;
24
24
  export declare function isClientAbortError(error: unknown): boolean;
25
25
  export declare function isResponseSocketGone(reply: FastifyReply): boolean;
26
26
  export declare function isProviderNetworkError(error: unknown): boolean;
27
+ /**
28
+ * HTTP statuses worth trying another model for: transient throttling,
29
+ * contention, and server-side failures. Ordinary 4xx responses (validation,
30
+ * authentication, permissions, model-not-found) are terminal — resending the
31
+ * identical request to a fallback model would fail the same way.
32
+ */
33
+ export declare function isFallbackEligibleStatus(status: number | undefined): boolean;
27
34
  export declare function isFallbackEligibleError(error: unknown): boolean;
@@ -13,8 +13,10 @@ interface MessageParam {
13
13
  role: string;
14
14
  content: string | ContentBlockParam[];
15
15
  }
16
+ export declare const CLAUDE_CODE_BILLING_SYSTEM_HEADER_PREFIX = "x-anthropic-billing-header";
16
17
  /** Normalize `provider/model` or `provider,model` into our `provider,model` form. */
17
18
  export declare function normalizeModelSelector(value: string | undefined | null): string | undefined;
19
+ export declare function claudeCodeBillingMetadataIsSubagent(text: string): boolean;
18
20
  /**
19
21
  * Strip Claude Code's billing helper system block.
20
22
  * Returns true when that block marks the request as a subagent.
@@ -22,6 +24,11 @@ export declare function normalizeModelSelector(value: string | undefined | null)
22
24
  export declare function removeClaudeCodeBillingSystemHeader(body: any): boolean;
23
25
  /** Prefer system tag, then early user-message tag; strip whichever matched. */
24
26
  export declare function extractAndRemoveClaudeCodeSubagentModelTag(body: any): string | undefined;
27
+ /** Read Claude Code's billing/subagent marker without mutating the source body. */
28
+ export declare function inspectClaudeCodeBillingSystemHeader(body: any): {
29
+ present: boolean;
30
+ isSubagent: boolean;
31
+ };
25
32
  export declare const calculateTokenCount: (messages: MessageParam[], system: any, tools: Tool[]) => number;
26
33
  export interface RouterContext {
27
34
  configService: ConfigService;
@@ -5,6 +5,8 @@ export interface StreamContext {
5
5
  export declare function createSSEStreamReader(response: Response, processLine: (line: string, context: StreamContext) => void, options?: {
6
6
  bufferSize?: number;
7
7
  onComplete?: (context: StreamContext) => void;
8
+ /** Return true when the protocol adapter emitted its own terminal error. */
9
+ onError?: (error: unknown, context: StreamContext) => boolean | void;
8
10
  logger?: any;
9
11
  }): Response;
10
12
  export declare function encodeSSEData(data: string, encoder: TextEncoder): Uint8Array;
@@ -0,0 +1,23 @@
1
+ export declare function isValidAnthropicToolCallId(id: unknown): id is string;
2
+ /**
3
+ * Coerce an id into Anthropic's allowed alphabet.
4
+ *
5
+ * Runs of invalid characters collapse to a single `_` rather than being
6
+ * deleted: deletion can merge two distinct ids into one (`a\nb` and `ab` both
7
+ * become `ab`), and a duplicate `tool_use.id` is a worse failure than a long
8
+ * one — it silently mispairs tool results.
9
+ *
10
+ * Must be deterministic and idempotent. The same id arrives from two
11
+ * independent directions — emitted on the response and echoed back by the
12
+ * client on the next request — and both must map to the same value or the
13
+ * `tool_use` / `tool_result` pair stops matching.
14
+ */
15
+ export declare function sanitizeToolCallId(id: unknown): string | undefined;
16
+ /**
17
+ * Bound a Responses API call id without losing tool-call/result pairing.
18
+ *
19
+ * Invalid or overlong ids use a readable prefix plus a deterministic hash of
20
+ * the original value. Hashing avoids collisions from either normalization or
21
+ * plain truncation, while the conforming fast path makes this idempotent.
22
+ */
23
+ export declare function sanitizeResponsesCallId(id: unknown): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caeliq/llms",
3
- "version": "1.0.57",
3
+ "version": "1.0.59",
4
4
  "description": "A universal LLM API transformation server",
5
5
  "main": "dist/cjs/server.cjs",
6
6
  "module": "dist/esm/server.mjs",
@@ -29,30 +29,34 @@
29
29
  "LICENSE"
30
30
  ],
31
31
  "dependencies": {
32
- "@anthropic-ai/sdk": "^0.54.0",
33
- "@caeliq/ccr-shared": "^2.0.3",
34
- "@cursor/sdk": "^1.0.23",
35
- "@fastify/cors": "^11.0.1",
36
- "@google/genai": "^2.13.0",
37
- "@huggingface/tokenizers": "^0.0.6",
38
- "dotenv": "^16.5.0",
39
- "fastify": "^5.4.0",
40
- "fastify-plugin": "^5.1.0",
41
- "google-auth-library": "^10.1.0",
32
+ "@anthropic-ai/sdk": "^0.115.0",
33
+ "@caeliq/ccr-shared": "^2.1.1",
34
+ "@cursor/sdk": "^1.0.26",
35
+ "@fastify/cors": "^11.3.0",
36
+ "@fastify/rate-limit": "^10.3.0",
37
+ "@google/genai": "^2.15.0",
38
+ "@huggingface/tokenizers": "^0.1.3",
39
+ "dotenv": "^17.4.2",
40
+ "fastify": "^5.11.2",
41
+ "fastify-plugin": "^6.0.0",
42
+ "google-auth-library": "^11.0.0",
42
43
  "json5": "^2.2.3",
43
- "jsonrepair": "^3.13.0",
44
+ "jsonrepair": "^3.15.0",
44
45
  "latex-to-unicode": "^0.1.0",
45
- "lru-cache": "^11.2.2",
46
- "openai": "^5.6.0",
47
- "tiktoken": "^1.0.21",
48
- "undici": "^7.10.0",
49
- "uuid": "^11.1.0"
46
+ "lru-cache": "^11.5.2",
47
+ "openai": "^7.2.0",
48
+ "tiktoken": "^1.0.22",
49
+ "undici": "^8.9.0",
50
+ "uuid": "^14.0.1"
50
51
  },
51
52
  "devDependencies": {
52
- "@types/node": "^24.0.15",
53
- "esbuild": "^0.25.1",
54
- "tsx": "^4.20.3",
55
- "typescript": "^5.8.2"
53
+ "@types/node": "^26.1.2",
54
+ "esbuild": "^0.28.1",
55
+ "tsx": "^4.23.1",
56
+ "typescript": "^6.0.3"
57
+ },
58
+ "engines": {
59
+ "node": ">=22.19.0"
56
60
  },
57
61
  "repository": {
58
62
  "type": "git",