From 896aaf799d988edf42f9d1e0405d0406ad57b2bf Mon Sep 17 00:00:00 2001 From: Roomote Date: Tue, 27 Oct 2026 03:55:32 +0000 Subject: [PATCH] chore(deps): patch runtime dependency alert bundle --- .docker/app/runtime-deps/api/package.json | 3 +- .docker/app/runtime-deps/api/pnpm-lock.yaml | 27 +- apps/api/package.json | 2 +- apps/api/src/handlers/ado/types.ts | 2 +- .../src/handlers/custom-automations/index.ts | 2 +- apps/api/src/handlers/inference/jevgrep.ts | 1 + apps/api/src/handlers/mcp/bitbucket.ts | 9 +- .../handlers/mcp/http-integrations/broker.ts | 2 +- apps/api/src/handlers/mcp/task-outputs.ts | 4 +- .../tasks/automation-work-items/schema.ts | 14 +- .../tasks/fastSessionCommunication.ts | 2 +- .../api/src/handlers/tasks/getTaskMessages.ts | 2 +- apps/api/src/handlers/tasks/saveTaskMemory.ts | 4 +- .../handlers/tasks/submitTaskSuggestions.ts | 2 +- apps/bullmq/package.json | 2 +- apps/bullmq/src/jobs/snapshot.ts | 2 +- apps/preview-proxy/package.json | 2 +- apps/web/package.json | 2 +- .../[reportId]/submit/page.tsx | 2 +- .../(sandbox)/sessions/[sessionId]/page.tsx | 2 +- .../api/mcp-remote-oauth/authorize/route.ts | 2 +- .../app/api/mcp-remote-oauth/revoke/route.ts | 2 +- .../app/api/mcp-remote-oauth/token/route.ts | 4 +- .../sessions/[sessionId]/attention/route.ts | 6 +- .../[sessionId]/attention/stream/route.ts | 4 +- .../integration-tool-approvals/route.ts | 2 +- .../sessions/[sessionId]/presence/route.ts | 4 +- .../api/sessions/[sessionId]/secrets/route.ts | 2 +- .../api/sessions/[sessionId]/stream/route.ts | 2 +- .../system/primitives/form.stories.tsx | 13 +- .../lib/server/fast-session-reply-stream.ts | 4 +- .../automations/ci-failure-triage-routing.ts | 6 +- .../trpc/commands/fast-sessions/input.test.ts | 22 +- .../src/trpc/commands/fast-sessions/input.ts | 32 +- .../trpc/commands/sandbox-session/index.ts | 3 +- apps/web/src/trpc/commands/sessions/index.ts | 4 +- apps/web/src/trpc/routers/_app.ts | 148 ++++---- apps/web/src/trpc/routers/instance-skills.ts | 4 +- .../src/trpc/routers/vulnerability-watch.ts | 2 +- apps/worker/package.json | 2 +- .../automation-work-items-tool-schema.test.ts | 9 +- .../__tests__/report-platform-issue.test.ts | 15 +- .../__tests__/tool-descriptions.test.ts | 7 +- .../automation-work-items-tool.ts | 2 +- .../src/mcp/roomote-mcp-server/index.ts | 2 +- .../on-demand-integrations.ts | 2 +- .../procedures/answerUserInputRequest.ts | 1 + package.json | 9 +- packages/ado/package.json | 2 +- packages/ado/src/api.ts | 4 +- packages/auth/package.json | 2 +- packages/auth/src/auth-token.ts | 2 +- packages/auth/src/preview-token.ts | 2 +- packages/auth/src/run-token.ts | 2 +- packages/auth/src/session-broker-token.ts | 2 +- packages/bitbucket/package.json | 2 +- packages/cloud-agents/package.json | 3 +- ...slack-question-channel-suggestions.test.ts | 9 +- .../fast-agent-native-tool-schemas.test.ts | 2 +- .../fast-agent-native-tool-bridge.ts | 4 +- .../server/fast-agent/fast-agent-service.ts | 6 +- .../src/server/mcp-nullable-optionals.test.ts | 55 ++- .../src/server/mcp-nullable-optionals.ts | 76 +++-- .../src/server/non-task-provider-usage.ts | 10 +- .../cloud-agents/src/server/task-run-queue.ts | 4 +- packages/communication/package.json | 2 +- .../communication/scripts/run-mock-discord.ts | 2 +- .../scripts/run-mock-telegram.ts | 8 +- .../src/mock-agentmail-config.ts | 4 +- packages/db/package.json | 2 +- packages/db/src/lib/custom-skills.ts | 2 +- packages/env/package.json | 2 +- packages/gitea/package.json | 2 +- packages/gitea/src/api.ts | 2 +- packages/github/package.json | 2 +- packages/gitlab/package.json | 2 +- packages/linear/package.json | 2 +- packages/linear/src/types.ts | 2 +- packages/sdk/package.json | 2 +- .../vulnerability-watch/matching.ts | 2 +- .../server/lib/automation-recommendations.ts | 4 +- .../sdk/src/server/lib/credential-egress.ts | 7 +- .../lib/task-runs/pr-review-notification.ts | 6 +- .../pull-request-mergeability-check.ts | 2 +- .../sdk/src/server/routers/linear-sessions.ts | 2 +- packages/sdk/src/server/routers/llm-usage.ts | 9 +- .../sdk/src/server/routers/mcp-connections.ts | 6 +- packages/sdk/src/server/routers/task-runs.ts | 11 +- .../sdk/src/server/routers/tool-approvals.ts | 4 +- packages/sdk/src/server/trpc.ts | 2 +- packages/slack/package.json | 2 +- packages/types/package.json | 2 +- packages/types/src/auth.ts | 18 +- .../types/src/automation-additional-rules.ts | 4 +- packages/types/src/credential-egress.ts | 2 +- packages/types/src/custom-mcp-servers.ts | 14 +- packages/types/src/environment-config.ts | 25 +- packages/types/src/environment-recipe.ts | 2 +- packages/types/src/fast-agent-capabilities.ts | 2 +- packages/types/src/fast-agent.ts | 2 +- .../types/src/integration-tool-approvals.ts | 2 +- packages/types/src/integration-tool-lookup.ts | 4 +- .../src/manage-custom-automations-tool.ts | 28 +- packages/types/src/manage-tasks-tool.ts | 2 +- packages/types/src/service-credentials.ts | 8 +- packages/types/src/source-control.ts | 2 +- packages/types/src/task-launch-api.ts | 6 +- packages/types/src/task-runs.ts | 22 +- pnpm-lock.yaml | 318 +++++++++--------- 109 files changed, 632 insertions(+), 514 deletions(-) diff --git a/.docker/app/runtime-deps/api/package.json b/.docker/app/runtime-deps/api/package.json index bc184241cf..424e22b222 100644 --- a/.docker/app/runtime-deps/api/package.json +++ b/.docker/app/runtime-deps/api/package.json @@ -7,11 +7,12 @@ "dompurify": "3.4.17", "jsdom": "26.1.0", "snowflake-sdk": "3.3.0", - "zod": "3.25.76" + "zod": "4.6.6" }, "pnpm": { "overrides": { "axios": "1.20.0", + "@azure/msal-node": "7.1.0", "follow-redirects": "1.16.1", "moment": "2.31.0", "toml": "5.0.1" diff --git a/.docker/app/runtime-deps/api/pnpm-lock.yaml b/.docker/app/runtime-deps/api/pnpm-lock.yaml index 52ca4ee213..8199ad562d 100644 --- a/.docker/app/runtime-deps/api/pnpm-lock.yaml +++ b/.docker/app/runtime-deps/api/pnpm-lock.yaml @@ -6,6 +6,7 @@ settings: overrides: axios: 1.20.0 + '@azure/msal-node': 7.1.0 follow-redirects: 1.16.1 moment: 2.31.0 toml: 5.0.1 @@ -24,8 +25,8 @@ importers: specifier: 3.3.0 version: 3.3.0(asn1.js@5.4.1) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 packages: @@ -211,8 +212,12 @@ packages: resolution: {integrity: sha512-hgLgfRdbG2AmhXPygebf1KYJEvse86+ZZLWufdiTKaGRYEUqOzHdlf6AS1IiuUCHWbynkgbHc451jSNkbfhWlg==} engines: {node: '>=0.8.0'} - '@azure/msal-node@5.5.0': - resolution: {integrity: sha512-A/2WIsuH0vsC6JVkkafjS4kHpi2LDR4AzDT0kJ+oIRtXYeYtvGQ2pwN2X88thQPhSek+82ela3MprsKXWQRrhQ==} + '@azure/msal-common@16.14.2': + resolution: {integrity: sha512-HOBR0Gfo39TMrkxNG8k6cfjRkrRjXZc3JQs3ebMWQc9S4cihuknMYra3sgmzbZB752oQBqBN9+WF7c826p2vIQ==} + engines: {node: '>=0.8.0'} + + '@azure/msal-node@7.1.0': + resolution: {integrity: sha512-s1O6hSY/C/dmqykTmmeHY6GhSkDuY8N1gxyhuLyaCwbY7N+UBvU2Wu4flas7+NxZiAPcXNPVpgt3n/HP/5yL+w==} engines: {node: '>=20'} '@azure/storage-blob@12.26.0': @@ -885,8 +890,8 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.6.6: + resolution: {integrity: sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==} snapshots: @@ -1238,7 +1243,7 @@ snapshots: '@azure/core-util': 1.14.0 '@azure/logger': 1.4.0 '@azure/msal-browser': 5.18.0 - '@azure/msal-node': 5.5.0 + '@azure/msal-node': 7.1.0 open: 10.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -1257,9 +1262,11 @@ snapshots: '@azure/msal-common@16.12.0': {} - '@azure/msal-node@5.5.0': + '@azure/msal-common@16.14.2': {} + + '@azure/msal-node@7.1.0': dependencies: - '@azure/msal-common': 16.12.0 + '@azure/msal-common': 16.14.2 jsonwebtoken: 9.0.3 '@azure/storage-blob@12.26.0': @@ -1986,4 +1993,4 @@ snapshots: xmlchars@2.2.0: {} - zod@3.25.76: {} + zod@4.6.6: {} diff --git a/apps/api/package.json b/apps/api/package.json index a7782d9fc5..74c158c08a 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -50,7 +50,7 @@ "snowflake-sdk": "3.3.0", "svix": "^1.99.1", "undici": "^7.29.1", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@ai-sdk/azure": "3.0.93", diff --git a/apps/api/src/handlers/ado/types.ts b/apps/api/src/handlers/ado/types.ts index 1f42a8e6ec..4ee9454130 100644 --- a/apps/api/src/handlers/ado/types.ts +++ b/apps/api/src/handlers/ado/types.ts @@ -167,7 +167,7 @@ const adoWorkItemResourceSchema = z // work-item-update shape with per-field old/new values. revision: z .object({ - fields: z.record(adoWorkItemRevisionFieldSchema).optional(), + fields: z.record(z.string(), adoWorkItemRevisionFieldSchema).optional(), revisedBy: adoIdentitySchema.optional(), }) .passthrough() diff --git a/apps/api/src/handlers/custom-automations/index.ts b/apps/api/src/handlers/custom-automations/index.ts index abdac77a7f..8536a5677d 100644 --- a/apps/api/src/handlers/custom-automations/index.ts +++ b/apps/api/src/handlers/custom-automations/index.ts @@ -63,7 +63,7 @@ const modelSchema = z .regex(/^[^/\s]+\/.+$/u, 'Model must use provider/model format.'); const environmentTargetSchema = z.union([ - z.string().uuid(), + z.guid(), z.literal(ALL_REPOSITORIES), z.literal(FAST_EXECUTION), ]); diff --git a/apps/api/src/handlers/inference/jevgrep.ts b/apps/api/src/handlers/inference/jevgrep.ts index c1722c8d89..33ceb5c6be 100644 --- a/apps/api/src/handlers/inference/jevgrep.ts +++ b/apps/api/src/handlers/inference/jevgrep.ts @@ -9,6 +9,7 @@ const requestSchema = z.object({ state: z.unknown(), questions: z .record( + z.string(), z.object({ type: z.literal('noul'), instructions: z.string().min(1).max(32_768), diff --git a/apps/api/src/handlers/mcp/bitbucket.ts b/apps/api/src/handlers/mcp/bitbucket.ts index 5a1756f795..f286f7e884 100644 --- a/apps/api/src/handlers/mcp/bitbucket.ts +++ b/apps/api/src/handlers/mcp/bitbucket.ts @@ -109,11 +109,12 @@ function createServer(auth: Variables['authContext']) { connected?: Awaited>, ) => Promise, ) { - server.registerTool( + const inputSchema = z.object(shape).strict(); + server.registerTool( name, { description, - inputSchema: z.object(shape).strict(), + inputSchema, annotations: { readOnlyHint: readOnly, destructiveHint: !readOnly, @@ -122,7 +123,9 @@ function createServer(auth: Variables['authContext']) { }, async (input) => { try { - const fullName = repository.parse(input.repositoryFullName); + const fullName = repository.parse( + (input as Record).repositoryFullName, + ); const connected = await authorize(auth, fullName); // Resolve through the existing refresh coordinator on every call, never at discovery. const token = await resolveBitbucketOAuthAccessToken(); diff --git a/apps/api/src/handlers/mcp/http-integrations/broker.ts b/apps/api/src/handlers/mcp/http-integrations/broker.ts index 05a5e927f9..465dc4001c 100644 --- a/apps/api/src/handlers/mcp/http-integrations/broker.ts +++ b/apps/api/src/handlers/mcp/http-integrations/broker.ts @@ -257,7 +257,7 @@ export async function integrationRequest( : undefined; const secretRef = z .string() - .uuid() + .check(z.guid()) .safeParse( typeof rawId === 'string' && rawId.startsWith('session:') ? rawId.slice(8) diff --git a/apps/api/src/handlers/mcp/task-outputs.ts b/apps/api/src/handlers/mcp/task-outputs.ts index 14bbfc371e..02ef5963ae 100644 --- a/apps/api/src/handlers/mcp/task-outputs.ts +++ b/apps/api/src/handlers/mcp/task-outputs.ts @@ -83,7 +83,7 @@ const commandCursorSchema = z .max(100) .refine((value) => Number.isFinite(Date.parse(value))), ts: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER), - id: z.string().uuid(), + id: z.guid(), }) .strict(); @@ -238,7 +238,7 @@ export async function downloadMemberTaskArtifact( const input = z .object({ taskId: z.string().regex(/^[0-9a-z]{13}$/), - artifactId: z.string().uuid(), + artifactId: z.guid(), }) .strict() .safeParse(c.req.query()); diff --git a/apps/api/src/handlers/tasks/automation-work-items/schema.ts b/apps/api/src/handlers/tasks/automation-work-items/schema.ts index 1b3360c422..0280d2c9cd 100644 --- a/apps/api/src/handlers/tasks/automation-work-items/schema.ts +++ b/apps/api/src/handlers/tasks/automation-work-items/schema.ts @@ -12,7 +12,7 @@ const automationWorkItemBaseSchema = z.object({ actionKind: z.string().trim().min(1).max(120), investigationContext: z.string().trim().max(4000).optional(), fingerprint: z.string().trim().max(255).optional(), - targetEnvironmentId: z.string().uuid().optional(), + targetEnvironmentId: z.guid().optional(), workspaceReadiness: workspaceReadinessSchema.optional(), readinessMessage: z.string().trim().min(1).max(500).optional(), }); @@ -28,16 +28,20 @@ export const automationWorkItemSchema = z disposition: z.literal('act'), executionPrompt: z .string({ - required_error: - 'Act automation work items must include executionPrompt.', + error: (issue) => + issue.input === undefined + ? 'Act automation work items must include executionPrompt.' + : undefined, }) .trim() .min(1, 'Act automation work items must include executionPrompt.') .max(6000), targetRepositoryFullName: z .string({ - required_error: - 'Act automation work items must include targetRepositoryFullName.', + error: (issue) => + issue.input === undefined + ? 'Act automation work items must include targetRepositoryFullName.' + : undefined, }) .trim() .min( diff --git a/apps/api/src/handlers/tasks/fastSessionCommunication.ts b/apps/api/src/handlers/tasks/fastSessionCommunication.ts index 343e8a0c8d..753eb12038 100644 --- a/apps/api/src/handlers/tasks/fastSessionCommunication.ts +++ b/apps/api/src/handlers/tasks/fastSessionCommunication.ts @@ -21,7 +21,7 @@ import { } from '@roomote/types'; import { z } from 'zod'; -const canonicalFastSessionIdSchema = z.string().uuid(); +const canonicalFastSessionIdSchema = z.guid(); export async function getFastSessionMessagesForUser(params: { sessionId: string; diff --git a/apps/api/src/handlers/tasks/getTaskMessages.ts b/apps/api/src/handlers/tasks/getTaskMessages.ts index ba1c0c4f93..eb2a814940 100644 --- a/apps/api/src/handlers/tasks/getTaskMessages.ts +++ b/apps/api/src/handlers/tasks/getTaskMessages.ts @@ -85,7 +85,7 @@ export async function getTaskMessages( if (!task) { const userId = c.get('mcpAuth').userId; - if (userId && z.string().uuid().safeParse(taskId).success) { + if (userId && z.guid().safeParse(taskId).success) { const [conversation] = await db .select({ id: fastAgentConversations.id }) .from(fastAgentConversations) diff --git a/apps/api/src/handlers/tasks/saveTaskMemory.ts b/apps/api/src/handlers/tasks/saveTaskMemory.ts index 5706ffab45..39c0fe7400 100644 --- a/apps/api/src/handlers/tasks/saveTaskMemory.ts +++ b/apps/api/src/handlers/tasks/saveTaskMemory.ts @@ -26,7 +26,7 @@ function describeTaskMemoryIssues( const value = issue.path.reduce( (acc, key) => acc && typeof acc === 'object' - ? (acc as Record)[key] + ? (acc as Record)[key] : undefined, input, ); @@ -36,7 +36,7 @@ function describeTaskMemoryIssues( : Array.isArray(value) ? `${value.length} entries` : undefined; - return `${path}: at most ${issue.maximum} ${issue.type === 'array' ? 'entries' : 'characters'}${actual ? ` (got ${actual})` : ''}`; + return `${path}: at most ${issue.maximum} ${issue.origin === 'array' ? 'entries' : 'characters'}${actual ? ` (got ${actual})` : ''}`; } return `${path}: ${issue.message}`; }) diff --git a/apps/api/src/handlers/tasks/submitTaskSuggestions.ts b/apps/api/src/handlers/tasks/submitTaskSuggestions.ts index ebd47b9b7d..ebf468ea77 100644 --- a/apps/api/src/handlers/tasks/submitTaskSuggestions.ts +++ b/apps/api/src/handlers/tasks/submitTaskSuggestions.ts @@ -103,7 +103,7 @@ const taskSuggestionSchema = z.object({ priority: z.enum(['P0', 'P1', 'P2', 'P3']).optional(), investigationContext: z.string().trim().max(4000).optional(), targetRepositoryFullName: z.string().trim().min(1).optional(), - targetEnvironmentId: z.string().uuid().optional(), + targetEnvironmentId: z.guid().optional(), workspaceReadiness: workspaceReadinessSchema.optional(), readinessMessage: z.string().trim().min(1).max(500).optional(), }); diff --git a/apps/bullmq/package.json b/apps/bullmq/package.json index 288af5c1ba..2de159ca08 100644 --- a/apps/bullmq/package.json +++ b/apps/bullmq/package.json @@ -39,7 +39,7 @@ "hono": "4.13.11", "ioredis": "^5.10.1", "jsdom": "26.1.0", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/apps/bullmq/src/jobs/snapshot.ts b/apps/bullmq/src/jobs/snapshot.ts index 64cec7df64..28e06a3a14 100644 --- a/apps/bullmq/src/jobs/snapshot.ts +++ b/apps/bullmq/src/jobs/snapshot.ts @@ -92,7 +92,7 @@ const snapshotFailureMetadataSchema = z .object({ name: z.string().min(1).nullish(), responseHeaders: z - .record(z.unknown()) + .record(z.string(), z.unknown()) .nullish() .transform((headers) => Object.fromEntries( diff --git a/apps/preview-proxy/package.json b/apps/preview-proxy/package.json index c054df5b52..df1b760aa5 100644 --- a/apps/preview-proxy/package.json +++ b/apps/preview-proxy/package.json @@ -30,7 +30,7 @@ "http-proxy": "^1.18.1", "pino": "^9.7.0", "pino-pretty": "^13.1.3", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/apps/web/package.json b/apps/web/package.json index 42a3a6cf66..c866e07454 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -133,7 +133,7 @@ "usehooks-ts": "^3.1.1", "vaul": "^1.1.2", "yaml": "^2.9.0", - "zod": "^3.25.76", + "zod": "^4.6.6", "zustand": "^5.0.10" }, "devDependencies": { diff --git a/apps/web/src/app/(authenticated)/platform-issues/[reportId]/submit/page.tsx b/apps/web/src/app/(authenticated)/platform-issues/[reportId]/submit/page.tsx index ddf5e3eb81..6edcef1061 100644 --- a/apps/web/src/app/(authenticated)/platform-issues/[reportId]/submit/page.tsx +++ b/apps/web/src/app/(authenticated)/platform-issues/[reportId]/submit/page.tsx @@ -6,7 +6,7 @@ import { getPlatformIssueReportCommand } from '@/trpc/commands/platform-issue-re import { PlatformIssueSubmission } from './PlatformIssueSubmission'; -const reportIdSchema = z.string().uuid(); +const reportIdSchema = z.guid(); export default async function Page({ params, diff --git a/apps/web/src/app/(sandbox)/sessions/[sessionId]/page.tsx b/apps/web/src/app/(sandbox)/sessions/[sessionId]/page.tsx index be98129b83..0878819472 100644 --- a/apps/web/src/app/(sandbox)/sessions/[sessionId]/page.tsx +++ b/apps/web/src/app/(sandbox)/sessions/[sessionId]/page.tsx @@ -46,7 +46,7 @@ const getSessionPageData = cache(async (sessionId: string) => { } // Both lookup columns are uuid; a garbage route param would otherwise throw // 22P02 in Postgres instead of 404ing. - if (!z.string().uuid().safeParse(sessionId).success) { + if (!z.guid().safeParse(sessionId).success) { notFound(); } diff --git a/apps/web/src/app/api/mcp-remote-oauth/authorize/route.ts b/apps/web/src/app/api/mcp-remote-oauth/authorize/route.ts index 2aca2600aa..8a1364fe56 100644 --- a/apps/web/src/app/api/mcp-remote-oauth/authorize/route.ts +++ b/apps/web/src/app/api/mcp-remote-oauth/authorize/route.ts @@ -18,7 +18,7 @@ export const dynamic = 'force-dynamic'; const authorizeSchema = z.object({ response_type: z.literal('code'), - client_id: z.string().uuid(), + client_id: z.guid(), redirect_uri: z.string().url(), state: z.string().min(1), code_challenge: z.string().regex(/^[A-Za-z0-9_-]{43}$/), diff --git a/apps/web/src/app/api/mcp-remote-oauth/revoke/route.ts b/apps/web/src/app/api/mcp-remote-oauth/revoke/route.ts index 2e82246db3..fe4a9f8b89 100644 --- a/apps/web/src/app/api/mcp-remote-oauth/revoke/route.ts +++ b/apps/web/src/app/api/mcp-remote-oauth/revoke/route.ts @@ -7,7 +7,7 @@ export const runtime = 'nodejs'; const revocationSchema = z.object({ token: z.string().min(1), - client_id: z.string().uuid(), + client_id: z.guid(), }); export async function POST(request: NextRequest) { diff --git a/apps/web/src/app/api/mcp-remote-oauth/token/route.ts b/apps/web/src/app/api/mcp-remote-oauth/token/route.ts index 3f488fff49..0df5a06280 100644 --- a/apps/web/src/app/api/mcp-remote-oauth/token/route.ts +++ b/apps/web/src/app/api/mcp-remote-oauth/token/route.ts @@ -27,7 +27,7 @@ const tokenSchema = z.discriminatedUnion('grant_type', [ z.object({ grant_type: z.literal('authorization_code'), code: z.string().min(1), - client_id: z.string().uuid(), + client_id: z.guid(), redirect_uri: z.string().url(), code_verifier: z.string().regex(/^[A-Za-z0-9._~-]{43,128}$/), resource: z.string().url().optional(), @@ -35,7 +35,7 @@ const tokenSchema = z.discriminatedUnion('grant_type', [ z.object({ grant_type: z.literal('refresh_token'), refresh_token: z.string().min(1), - client_id: z.string().uuid(), + client_id: z.guid(), resource: z.string().url().optional(), scope: z.string().optional(), }), diff --git a/apps/web/src/app/api/sessions/[sessionId]/attention/route.ts b/apps/web/src/app/api/sessions/[sessionId]/attention/route.ts index 0c2a4eff1b..7f2109d371 100644 --- a/apps/web/src/app/api/sessions/[sessionId]/attention/route.ts +++ b/apps/web/src/app/api/sessions/[sessionId]/attention/route.ts @@ -9,10 +9,10 @@ import { findAccessibleSession } from '@/lib/server/sessions'; export const runtime = 'nodejs'; -const paramsSchema = z.object({ sessionId: z.string().uuid() }); +const paramsSchema = z.object({ sessionId: z.guid() }); const bodySchema = z.object({ - notificationId: z.string().uuid(), - clientId: z.string().uuid(), + notificationId: z.guid(), + clientId: z.guid(), action: z.enum(['accepted', 'failed', 'opened']), }); diff --git a/apps/web/src/app/api/sessions/[sessionId]/attention/stream/route.ts b/apps/web/src/app/api/sessions/[sessionId]/attention/stream/route.ts index 576fd3b2a0..0153992a4a 100644 --- a/apps/web/src/app/api/sessions/[sessionId]/attention/stream/route.ts +++ b/apps/web/src/app/api/sessions/[sessionId]/attention/stream/route.ts @@ -16,9 +16,9 @@ import { findAccessibleSession } from '@/lib/server/sessions'; export const runtime = 'nodejs'; -const paramsSchema = z.object({ sessionId: z.string().uuid() }); +const paramsSchema = z.object({ sessionId: z.guid() }); const querySchema = z.object({ - clientId: z.string().uuid(), + clientId: z.guid(), permission: z.enum(['granted', 'default', 'denied', 'unsupported']), }); const POLL_INTERVAL_MS = 1_000; diff --git a/apps/web/src/app/api/sessions/[sessionId]/integration-tool-approvals/route.ts b/apps/web/src/app/api/sessions/[sessionId]/integration-tool-approvals/route.ts index c4c2672d50..d06419eec8 100644 --- a/apps/web/src/app/api/sessions/[sessionId]/integration-tool-approvals/route.ts +++ b/apps/web/src/app/api/sessions/[sessionId]/integration-tool-approvals/route.ts @@ -30,7 +30,7 @@ async function handle(request: Request, props: Props, method: 'GET' | 'POST') { const auth = await authorize(); if (!auth.success || !auth.userId) return error(401); const params = z - .object({ sessionId: z.string().uuid() }) + .object({ sessionId: z.guid() }) .safeParse(await props.params); if (!params.success) return error(400); const context = { sessionId: params.data.sessionId, userId: auth.userId }; diff --git a/apps/web/src/app/api/sessions/[sessionId]/presence/route.ts b/apps/web/src/app/api/sessions/[sessionId]/presence/route.ts index f1f3d16d59..9b0ff87091 100644 --- a/apps/web/src/app/api/sessions/[sessionId]/presence/route.ts +++ b/apps/web/src/app/api/sessions/[sessionId]/presence/route.ts @@ -18,9 +18,9 @@ import { getUsersById } from '@/lib/server/users'; export const runtime = 'nodejs'; -const paramsSchema = z.object({ sessionId: z.string().uuid() }); +const paramsSchema = z.object({ sessionId: z.guid() }); const bodySchema = z.object({ - clientId: z.string().uuid(), + clientId: z.guid(), channel: z.enum(['view', 'voice']).default('view'), generation: z.number().int().nonnegative().optional(), }); diff --git a/apps/web/src/app/api/sessions/[sessionId]/secrets/route.ts b/apps/web/src/app/api/sessions/[sessionId]/secrets/route.ts index 5b584ef482..3677ebb04c 100644 --- a/apps/web/src/app/api/sessions/[sessionId]/secrets/route.ts +++ b/apps/web/src/app/api/sessions/[sessionId]/secrets/route.ts @@ -41,7 +41,7 @@ async function handle( const auth = await authorize(); if (!auth.success || !auth.userId) return error(401); const params = z - .object({ sessionId: z.string().uuid() }) + .object({ sessionId: z.guid() }) .safeParse(await props.params); if (!params.success) return error(400); const context = { sessionId: params.data.sessionId, userId: auth.userId }; diff --git a/apps/web/src/app/api/sessions/[sessionId]/stream/route.ts b/apps/web/src/app/api/sessions/[sessionId]/stream/route.ts index dff32f19c1..516ee06cc5 100644 --- a/apps/web/src/app/api/sessions/[sessionId]/stream/route.ts +++ b/apps/web/src/app/api/sessions/[sessionId]/stream/route.ts @@ -43,7 +43,7 @@ export async function GET( } const { sessionId } = await props.params; - const parsedSessionId = z.string().uuid().safeParse(sessionId); + const parsedSessionId = z.guid().safeParse(sessionId); if (!parsedSessionId.success) { return NextResponse.json({ error: 'Not Found' }, { status: 404 }); } diff --git a/apps/web/src/components/system/primitives/form.stories.tsx b/apps/web/src/components/system/primitives/form.stories.tsx index 57e30f1d41..79345d1593 100644 --- a/apps/web/src/components/system/primitives/form.stories.tsx +++ b/apps/web/src/components/system/primitives/form.stories.tsx @@ -125,7 +125,10 @@ const profileFormSchema = z.object({ }), email: z .string({ - required_error: 'Please select an email to display.', + error: (issue) => + issue.input === undefined + ? 'Please select an email to display.' + : undefined, }) .email(), bio: z.string().max(160).min(4), @@ -243,11 +246,15 @@ const settingsFormSchema = z.object({ marketingEmails: z.boolean().default(false).optional(), securityEmails: z.boolean(), communicationMethod: z.enum(['email', 'sms', 'push'], { - required_error: 'You need to select a notification method.', + error: (issue) => + issue.input === undefined + ? 'You need to select a notification method.' + : undefined, }), theme: z.enum(['light', 'dark', 'system']), language: z.string({ - required_error: 'Please select a language.', + error: (issue) => + issue.input === undefined ? 'Please select a language.' : undefined, }), }); diff --git a/apps/web/src/lib/server/fast-session-reply-stream.ts b/apps/web/src/lib/server/fast-session-reply-stream.ts index 70c9098bd0..aaefa48686 100644 --- a/apps/web/src/lib/server/fast-session-reply-stream.ts +++ b/apps/web/src/lib/server/fast-session-reply-stream.ts @@ -17,8 +17,8 @@ const replyChunkEventSchema = z.object({ contentBlocks: z.array( z.object({ type: z.literal('text'), text: z.string() }), ), - metadata: z.record(z.unknown()).nullable(), - payload: z.record(z.unknown()), + metadata: z.record(z.string(), z.unknown()).nullable(), + payload: z.record(z.string(), z.unknown()), logicalEventId: z.string().optional(), text: z.string().optional(), }); diff --git a/apps/web/src/trpc/commands/automations/ci-failure-triage-routing.ts b/apps/web/src/trpc/commands/automations/ci-failure-triage-routing.ts index 445a87f482..3f9483144a 100644 --- a/apps/web/src/trpc/commands/automations/ci-failure-triage-routing.ts +++ b/apps/web/src/trpc/commands/automations/ci-failure-triage-routing.ts @@ -32,11 +32,9 @@ import type { UserAuthSuccess } from '@/types'; const resolutionSchema = z .object({ status: z.enum(['resolved', 'ambiguous']), - repositoryIds: z.array(z.string().uuid()).nullable(), + repositoryIds: z.array(z.guid()).nullable(), destinations: z.array( - z - .object({ repositoryId: z.string().uuid(), destinationId: z.string() }) - .strict(), + z.object({ repositoryId: z.guid(), destinationId: z.string() }).strict(), ), instructions: z.string(), clarification: z.string().nullable(), diff --git a/apps/web/src/trpc/commands/fast-sessions/input.test.ts b/apps/web/src/trpc/commands/fast-sessions/input.test.ts index bdef416ab7..b779f1e401 100644 --- a/apps/web/src/trpc/commands/fast-sessions/input.test.ts +++ b/apps/web/src/trpc/commands/fast-sessions/input.test.ts @@ -76,15 +76,21 @@ describe('Session input schemas', () => { }); it('rejects too many extracted attachments', () => { - expect(() => - startFastSessionInputSchema.parse({ - text: 'Implement these plans', - attachmentTexts: Array.from( - { length: 21 }, - (_, index) => `Attachment ${index}`, - ), + const result = startFastSessionInputSchema.safeParse({ + text: 'Implement these plans', + attachmentTexts: Array.from( + { length: 21 }, + (_, index) => `Attachment ${index}`, + ), + }); + expect(result.success).toBe(false); + expect(result.error?.issues).toEqual([ + expect.objectContaining({ + code: 'too_big', + maximum: 20, + path: ['attachmentTexts'], }), - ).toThrow('Array must contain at most 20 element(s)'); + ]); }); it('rejects extracted attachment text over the aggregate limit', () => { diff --git a/apps/web/src/trpc/commands/fast-sessions/input.ts b/apps/web/src/trpc/commands/fast-sessions/input.ts index 18f11298be..436f8d75b8 100644 --- a/apps/web/src/trpc/commands/fast-sessions/input.ts +++ b/apps/web/src/trpc/commands/fast-sessions/input.ts @@ -41,11 +41,11 @@ const fastSessionMessageInputShape = { * prompt opens a blank workspace. */ export const pinnedFastSessionLaunchSchema = z.object({ - launchId: z.string().uuid(), + launchId: z.guid(), repo: z.string().trim().min(1), branch: z.string().trim().min(1).optional(), sha: z.string().trim().min(1).optional(), - environmentId: z.string().uuid().optional(), + environmentId: z.guid().optional(), harness: z.enum(launchCodingHarnesses).optional(), computeProvider: z.enum(computeProviders).optional(), }); @@ -93,7 +93,7 @@ function requireFastSessionContent( export const startFastSessionInputSchema = z .object({ ...fastSessionMessageInputShape, - conversationId: z.string().uuid().optional(), + conversationId: z.guid().optional(), privacy: z.enum(['shared', 'private']).optional(), pinnedLaunch: pinnedFastSessionLaunchSchema.optional(), /** Open the Session for a voice call; any text is the pre-typed message. */ @@ -105,18 +105,18 @@ export const startFastSessionInputSchema = z export const fastSessionAutoToolApprovalsInputSchema = z.object({ /** The unified session; omitted for one that has not started yet. */ - sessionId: z.string().uuid().optional(), + sessionId: z.guid().optional(), }); export const setFastSessionAutoToolApprovalsInputSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), enabled: z.boolean(), }); export const replyToFastSessionInputSchema = z .object({ - sessionId: z.string().uuid(), - clientMessageId: z.string().uuid().optional(), + sessionId: z.guid(), + clientMessageId: z.guid().optional(), /** The message was spoken on a voice call; the reply goes to the voice. */ voiceMode: z.boolean().optional(), ...fastSessionMessageInputShape, @@ -124,29 +124,29 @@ export const replyToFastSessionInputSchema = z .superRefine(requireFastSessionContent); export const deleteFastSessionQueuedMessageInputSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), /** The client id the queued reply was sent with. */ - clientMessageId: z.string().uuid(), + clientMessageId: z.guid(), }); export const steerFastSessionQueuedMessageInputSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), /** The client id of the oldest queued reply to send now. */ - clientMessageId: z.string().uuid(), + clientMessageId: z.guid(), }); export const stopFastSessionInputSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), }); export const fastSessionPrReviewActionInputSchema = z.object({ - sessionId: z.string().uuid(), - deliveryId: z.string().uuid(), + sessionId: z.guid(), + deliveryId: z.guid(), choice: z.enum(['yes', 'auto', 'dismiss']), }); export const fastSessionCapabilityOfferResponseInputSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), offerId: z.string().min(1), capability: fastAgentCapabilityIdSchema, resolution: z.enum(['completed', 'dismissed']), @@ -154,7 +154,7 @@ export const fastSessionCapabilityOfferResponseInputSchema = z.object({ }); export const updateFastSessionModelSelectionInputSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), model: fastSessionMessageInputShape.model, reasoningEffort: fastSessionMessageInputShape.reasoningEffort, }); diff --git a/apps/web/src/trpc/commands/sandbox-session/index.ts b/apps/web/src/trpc/commands/sandbox-session/index.ts index 7a74927a16..eb90f69810 100644 --- a/apps/web/src/trpc/commands/sandbox-session/index.ts +++ b/apps/web/src/trpc/commands/sandbox-session/index.ts @@ -97,6 +97,7 @@ export function shouldPollForAutomaticFailedStartRetry(input: { ); } const requestUserInputAnswersSchema = z.record( + z.string(), z.object({ answers: z.array(z.string()), }), @@ -206,7 +207,7 @@ export const answerSandboxUserInputRequestInputSchema = z.object({ }); export const handlePrReviewNotificationActionInputSchema = z.object({ - deliveryId: z.string().uuid(), + deliveryId: z.guid(), choice: z.enum(['yes', 'auto', 'dismiss']), }); diff --git a/apps/web/src/trpc/commands/sessions/index.ts b/apps/web/src/trpc/commands/sessions/index.ts index 74280af3ac..690ea87958 100644 --- a/apps/web/src/trpc/commands/sessions/index.ts +++ b/apps/web/src/trpc/commands/sessions/index.ts @@ -62,7 +62,7 @@ const ARTIFACT_SIGNATURE_CACHE_WINDOW_SECONDS = 60 * 60; const TASK_STOP_WAIT_MS = 15_000; const TASK_STOP_POLL_MS = 100; -export const sessionIdInputSchema = z.object({ sessionId: z.string().uuid() }); +export const sessionIdInputSchema = z.object({ sessionId: z.guid() }); export const sessionStatusInputSchema = sessionIdInputSchema.extend({ status: z.enum(SESSION_MANUAL_STATUSES), }); @@ -561,7 +561,7 @@ export const sessionsListInputSchema = z.object({ model: z.string().nullish(), period: z.union([z.literal('all'), z.number().int().positive()]).optional(), q: z.string().max(200).nullish(), - ids: z.array(z.string().uuid()).max(20).optional(), + ids: z.array(z.guid()).max(20).optional(), ownedOnly: z.boolean().optional(), before: z.string().nullish(), limit: z.number().int().min(1).max(200).optional(), diff --git a/apps/web/src/trpc/routers/_app.ts b/apps/web/src/trpc/routers/_app.ts index c3ec47de03..619a25f4a9 100644 --- a/apps/web/src/trpc/routers/_app.ts +++ b/apps/web/src/trpc/routers/_app.ts @@ -605,7 +605,7 @@ import { } from '../commands/platform-issue-reports'; import { getStatuspageIncident } from '@roomote/slack'; -const stateRecordSchema = z.record(z.string()); +const stateRecordSchema = z.record(z.string(), z.string()); function assertAdmin(auth: { isAdmin: boolean }) { if (!auth.isAdmin) throw new Error('Unauthorized'); @@ -721,7 +721,7 @@ const automationsRouter = createRouter({ ), reviewerEnabled: z.boolean(), reviewerEnvironmentScope: z.enum(['all', 'specific']), - reviewerEnvironmentIds: z.array(z.string().uuid()), + reviewerEnvironmentIds: z.array(z.guid()), reviewerAuthorReviewMode: z.enum(['all', 'specific', 'none']), reviewerCollaborators: z.array(z.string().trim().min(1).max(255)), reviewerExcludedAuthors: z.string().max(8_000).nullable(), @@ -1033,7 +1033,7 @@ const automationsRouter = createRouter({ ), getCustomAutomationOptions: protectedProcedure - .input(z.object({ automationId: z.string().uuid().optional() }).optional()) + .input(z.object({ automationId: z.guid().optional() }).optional()) .query(({ ctx: { auth }, input }) => getCustomAutomationOptionsCommand(auth, input ?? {}), ), @@ -1069,7 +1069,7 @@ const automationsRouter = createRouter({ .optional(), reasoningEffort: z.enum(REASONING_EFFORT_VALUES).nullable().optional(), environmentId: z.union([ - z.string().uuid(), + z.guid(), z.literal(ALL_REPOSITORIES), z.literal(NO_REPOSITORIES), z.literal(FAST_EXECUTION), @@ -1095,7 +1095,7 @@ const automationsRouter = createRouter({ updateCustomAutomation: protectedProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), name: z.string().trim().min(1).max(100), prompt: z .string() @@ -1124,7 +1124,7 @@ const automationsRouter = createRouter({ .optional(), reasoningEffort: z.enum(REASONING_EFFORT_VALUES).nullable().optional(), environmentId: z.union([ - z.string().uuid(), + z.guid(), z.literal(ALL_REPOSITORIES), z.literal(NO_REPOSITORIES), z.literal(FAST_EXECUTION), @@ -1148,31 +1148,31 @@ const automationsRouter = createRouter({ ), getCustomAutomationWebhook: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .query(({ ctx: { auth }, input }) => getCustomAutomationWebhookCommand(auth, input), ), setCustomAutomationWebhookEnabled: protectedProcedure - .input(z.object({ id: z.string().uuid(), enabled: z.boolean() })) + .input(z.object({ id: z.guid(), enabled: z.boolean() })) .mutation(({ ctx: { auth }, input }) => setCustomAutomationWebhookEnabledCommand(auth, input), ), rotateCustomAutomationWebhook: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => rotateCustomAutomationWebhookCommand(auth, input), ), deleteCustomAutomation: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => deleteCustomAutomationCommand(auth, input), ), triggerCustomAutomation: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => triggerCustomAutomationCommand(auth, input), ), @@ -1266,7 +1266,7 @@ export const appRouter = createRouter({ .object({ createdAt: z.string(), ts: z.number(), - id: z.string().uuid(), + id: z.guid(), }) .optional(), }), @@ -1349,12 +1349,12 @@ export const appRouter = createRouter({ platformIssueReports: createRouter({ byId: protectedProcedure - .input(z.object({ reportId: z.string().uuid() })) + .input(z.object({ reportId: z.guid() })) .query(({ ctx: { auth }, input }) => getPlatformIssueReportCommand(auth, input.reportId), ), submit: protectedProcedure - .input(z.object({ reportId: z.string().uuid() })) + .input(z.object({ reportId: z.guid() })) .mutation(({ ctx: { auth }, input }) => submitPlatformIssueReportCommand(auth, input.reportId), ), @@ -1366,7 +1366,7 @@ export const appRouter = createRouter({ z .object({ taskId: z.string().optional(), - sessionId: z.string().uuid().optional(), + sessionId: z.guid().optional(), path: z.string(), version: z.number().optional(), preview: z.boolean().optional(), @@ -1384,7 +1384,7 @@ export const appRouter = createRouter({ z .object({ taskId: z.string().optional(), - sessionId: z.string().uuid().optional(), + sessionId: z.guid().optional(), path: z.string(), }) .refine( @@ -1613,7 +1613,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: sourceControlProviderSchema, - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -1914,7 +1914,7 @@ export const appRouter = createRouter({ ), listConfigVersions: protectedProcedure - .input(z.object({ environmentId: z.string().uuid() })) + .input(z.object({ environmentId: z.guid() })) .query(({ ctx: { auth }, input }) => listEnvironmentConfigVersionsCommand(auth, input), ), @@ -1922,7 +1922,7 @@ export const appRouter = createRouter({ getConfigVersion: protectedProcedure .input( z.object({ - environmentId: z.string().uuid(), + environmentId: z.guid(), version: z.number().int().min(1), }), ) @@ -1937,7 +1937,7 @@ export const appRouter = createRouter({ activeDefinitionTask: protectedProcedure .input( z.object({ - environmentId: z.string().uuid(), + environmentId: z.guid(), }), ) .query(({ ctx: { auth }, input }) => @@ -1949,7 +1949,7 @@ export const appRouter = createRouter({ z.object({ name: z.string().min(1), description: z.string().optional(), - config: z.record(z.unknown()), + config: z.record(z.string(), z.unknown()), }), ) .mutation(({ ctx: { auth }, input }) => @@ -1966,7 +1966,7 @@ export const appRouter = createRouter({ name: z.string().min(1).optional(), description: z.string().optional(), agentInstructions: z.string().optional(), - config: z.record(z.unknown()).optional(), + config: z.record(z.string(), z.unknown()).optional(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -1979,7 +1979,7 @@ export const appRouter = createRouter({ startDefinitionTask: protectedProcedure .input( z.object({ - repositoryIds: z.array(z.string().uuid()), + repositoryIds: z.array(z.guid()), environmentId: z.string().optional(), changeRequest: z.string().trim().min(1).max(8_000).optional(), selectedModelId: z.string().trim().min(1).optional(), @@ -1996,7 +1996,7 @@ export const appRouter = createRouter({ ), retryVerification: protectedProcedure - .input(z.object({ environmentId: z.string().uuid() })) + .input(z.object({ environmentId: z.guid() })) .mutation(({ ctx: { auth }, input }) => retryEnvironmentVerificationCommand(auth, input), ), @@ -2125,7 +2125,7 @@ export const appRouter = createRouter({ setVisibility: protectedProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), visibility: customMcpServerVisibilitySchema, }), ) @@ -2134,21 +2134,19 @@ export const appRouter = createRouter({ ), update: protectedProcedure - .input( - z.object({ id: z.string().uuid(), server: customMcpServerInputSchema }), - ) + .input(z.object({ id: z.guid(), server: customMcpServerInputSchema })) .mutation(({ ctx: { auth }, input }) => updateCustomMcpServerCommand(auth, input), ), delete: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => deleteCustomMcpServerCommand(auth, input), ), setEnabled: protectedProcedure - .input(z.object({ id: z.string().uuid(), enabled: z.boolean() })) + .input(z.object({ id: z.guid(), enabled: z.boolean() })) .mutation(({ ctx: { auth }, input }) => setCustomMcpServerEnabledCommand(auth, input), ), @@ -2156,7 +2154,7 @@ export const appRouter = createRouter({ setDisabledTools: protectedProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), disabledTools: z.array(z.string().min(1)), }), ) @@ -2165,21 +2163,19 @@ export const appRouter = createRouter({ ), listTools: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .query(({ ctx: { auth }, input }) => listCustomMcpServerToolsCommand(auth, input), ), connect: protectedProcedure - .input( - z.object({ id: z.string().uuid(), redirectTo: z.string().optional() }), - ) + .input(z.object({ id: z.guid(), redirectTo: z.string().optional() })) .mutation(({ ctx: { auth }, input }) => connectCustomMcpServerCommand(auth, input), ), disconnect: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => disconnectCustomMcpServerCommand(auth, input), ), @@ -2427,7 +2423,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: z.enum(COMMS_PROVIDER_IDS), - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -2494,7 +2490,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: z.enum(computeProviders), - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -2661,7 +2657,7 @@ export const appRouter = createRouter({ ), delete: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => deleteUserTaskModelMappingPresetCommand(auth, input), ), @@ -2691,7 +2687,9 @@ export const appRouter = createRouter({ .trim() .refine(isSetupModelProviderId, 'Invalid model provider.'), apiKey: z.string().trim().optional(), - additionalEnvValues: z.record(z.string().trim()).optional(), + additionalEnvValues: z + .record(z.string(), z.string().trim()) + .optional(), connectionName: z.string().trim().optional(), modelId: z.string().trim().optional(), }), @@ -2897,7 +2895,7 @@ export const appRouter = createRouter({ .input( z.object({ enabled: z.boolean(), - roles: z.record( + roles: z.partialRecord( z.enum(TASK_MODEL_ROLES as [TaskModelRole, ...TaskModelRole[]]), z.object({ modelId: z.string().trim().min(1), @@ -3010,7 +3008,7 @@ export const appRouter = createRouter({ .array( z.object({ name: z.string().min(1).max(100), - repositoryIds: z.array(z.string().uuid()), + repositoryIds: z.array(z.guid()), installCommand: z.string().max(500).optional(), testCommand: z.string().max(500).optional(), }), @@ -3042,7 +3040,7 @@ export const appRouter = createRouter({ completeWithStarterTasks: protectedProcedure .input( z.object({ - launchBatchId: z.string().uuid(), + launchBatchId: z.guid(), selectedStarterTaskIds: z .array(z.enum(SETUP_STARTER_TASK_IDS)) .max(SETUP_STARTER_TASK_IDS.length), @@ -3063,7 +3061,7 @@ export const appRouter = createRouter({ ), skipSourceControl: protectedProcedure - .input(z.object({ sessionId: z.string().uuid() })) + .input(z.object({ sessionId: z.guid() })) .mutation(({ ctx: { auth }, input }) => skipSetupSourceControlCommand(auth, input.sessionId), ), @@ -3071,9 +3069,12 @@ export const appRouter = createRouter({ submitSessionUserInput: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), requestId: z.string().min(1), - answers: z.record(z.object({ answers: z.array(z.string()).max(50) })), + answers: z.record( + z.string(), + z.object({ answers: z.array(z.string()).max(50) }), + ), }), ) .mutation(({ ctx: { auth }, input }) => @@ -3114,7 +3115,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: z.enum(SETUP_AUTH_PROVIDER_IDS), - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -3129,7 +3130,9 @@ export const appRouter = createRouter({ .trim() .refine(isSetupModelProviderId, 'Invalid model provider.'), apiKey: z.string().trim().optional(), - additionalEnvValues: z.record(z.string().trim()).optional(), + additionalEnvValues: z + .record(z.string(), z.string().trim()) + .optional(), connectionName: z.string().trim().optional(), modelId: z.string().trim().optional(), }), @@ -3164,7 +3167,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: z.enum(computeProviders), - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), }), ) .mutation(async ({ ctx: { auth }, input }) => { @@ -3192,7 +3195,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: sourceControlProviderSchema, - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -3202,7 +3205,7 @@ export const appRouter = createRouter({ saveQueuedTasks: protectedProcedure .input( z.object({ - selectedSuggestionIds: z.array(z.string().uuid()).max(5), + selectedSuggestionIds: z.array(z.guid()).max(5), customTaskPrompt: z.string().trim().max(4_000).optional(), }), ) @@ -3251,7 +3254,7 @@ export const appRouter = createRouter({ .input( z.object({ provider: z.enum(SETUP_AUTH_PROVIDER_IDS), - values: z.record(z.string().trim()).optional(), + values: z.record(z.string(), z.string().trim()).optional(), setupToken: z.string().optional(), }), ) @@ -3340,7 +3343,7 @@ export const appRouter = createRouter({ dismiss: protectedProcedure .input( z.object({ - suggestionId: z.string().uuid(), + suggestionId: z.guid(), }), ) .mutation(({ ctx: { auth }, input }) => @@ -3355,7 +3358,7 @@ export const appRouter = createRouter({ get: protectedProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), kind: z.enum(['report', 'suggestion']), }), ) @@ -3369,7 +3372,7 @@ export const appRouter = createRouter({ act: protectedProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), kind: z.enum(['report', 'suggestion']), action: z.enum(['accept', 'ignore']), }), @@ -3381,13 +3384,13 @@ export const appRouter = createRouter({ clearOne: protectedProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), kind: z.enum(['report', 'suggestion']), }), ) .mutation(({ ctx: { auth }, input }) => clearResultCommand(auth, input)), acceptSuggestion: protectedProcedure - .input(z.object({ id: z.string().uuid() })) + .input(z.object({ id: z.guid() })) .mutation(({ ctx: { auth }, input }) => acceptSuggestionResultCommand(auth, input), ), @@ -3426,7 +3429,7 @@ export const appRouter = createRouter({ startGoal: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), objective: sessionGoalInputSchema.shape.objective, clientMessageId: z.string().optional(), }), @@ -3460,24 +3463,24 @@ export const appRouter = createRouter({ setFastSessionAutoToolApprovalsCommand(auth, input), ), tasks: protectedProcedure - .input(z.object({ sessionId: z.string().uuid() })) + .input(z.object({ sessionId: z.guid() })) .query(({ ctx: { auth }, input }) => getFastSessionTasksCommand(auth, input.sessionId), ), messages: protectedProcedure - .input(z.object({ sessionId: z.string().uuid() })) + .input(z.object({ sessionId: z.guid() })) .query(({ ctx: { auth }, input }) => getFastSessionMessagesCommand(auth, input.sessionId), ), olderMessages: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), cursor: z.object({ createdAt: z.string().min(1).max(64), ts: z.number().int(), turnSeq: z.number().int(), - id: z.string().uuid(), + id: z.guid(), }), }), ) @@ -3487,9 +3490,12 @@ export const appRouter = createRouter({ submitUserInput: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), requestId: z.string().min(1), - answers: z.record(z.object({ answers: z.array(z.string()).max(50) })), + answers: z.record( + z.string(), + z.object({ answers: z.array(z.string()).max(50) }), + ), resolution: z.enum(['submitted', 'cancelled']).optional(), }), ) @@ -3499,7 +3505,7 @@ export const appRouter = createRouter({ composerSuggestion: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), // Client-side cache keys: bump when the live transcript or the // delegated tasks' state meaningfully change so stale suggestions // are never shown. The server derives its own cache keys from @@ -3540,7 +3546,7 @@ export const appRouter = createRouter({ recordTurn: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), role: z.enum(['user', 'assistant']), text: z.string().trim().min(1).max(20_000), }), @@ -3551,7 +3557,7 @@ export const appRouter = createRouter({ recordCallEvent: protectedProcedure .input( z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), phase: z.enum(['started', 'ended']), durationMs: z.number().int().nonnegative().optional(), }), @@ -3568,7 +3574,7 @@ export const appRouter = createRouter({ getSessionWakeupsCommand(auth, input.sessionId), ), cancelWakeup: protectedProcedure - .input(sessionIdInputSchema.extend({ wakeupId: z.string().uuid() })) + .input(sessionIdInputSchema.extend({ wakeupId: z.guid() })) .mutation(({ ctx: { auth }, input }) => cancelSessionWakeupCommand(auth, input), ), @@ -3710,7 +3716,7 @@ export const appRouter = createRouter({ revokeInvite: protectedProcedure .input( z.object({ - inviteId: z.string().uuid(), + inviteId: z.guid(), }), ) .mutation(({ ctx: { auth }, input }) => revokeInviteCommand(auth, input)), @@ -3777,7 +3783,7 @@ export const appRouter = createRouter({ .input( z.object({ skillId: z.string().min(3), - environmentIds: z.array(z.string().uuid()).min(1), + environmentIds: z.array(z.guid()).min(1), }), ) .mutation(({ ctx: { auth }, input }) => @@ -3790,7 +3796,7 @@ export const appRouter = createRouter({ name: z.string().min(1), description: z.string().min(1), content: z.string().min(1), - environmentIds: z.array(z.string().uuid()).min(1), + environmentIds: z.array(z.guid()).min(1), previousSkillId: z.string().min(3).optional(), }), ) diff --git a/apps/web/src/trpc/routers/instance-skills.ts b/apps/web/src/trpc/routers/instance-skills.ts index 017146848f..40d2d6ff14 100644 --- a/apps/web/src/trpc/routers/instance-skills.ts +++ b/apps/web/src/trpc/routers/instance-skills.ts @@ -12,7 +12,7 @@ import { updateInstanceSkillCommand, } from '../commands/instance-skills'; -const skillIdSchema = z.object({ skillId: z.string().uuid() }).strict(); +const skillIdSchema = z.object({ skillId: z.guid() }).strict(); export const instanceSkillsRouter = createRouter({ list: protectedProcedure.query(({ ctx: { auth } }) => @@ -31,7 +31,7 @@ export const instanceSkillsRouter = createRouter({ customSkillDefinitionSchema .extend({ expectedVersion: z.number().int().positive(), - skillId: z.string().uuid(), + skillId: z.guid(), }) .strict(), ) diff --git a/apps/web/src/trpc/routers/vulnerability-watch.ts b/apps/web/src/trpc/routers/vulnerability-watch.ts index 0b661f28ae..3455e17711 100644 --- a/apps/web/src/trpc/routers/vulnerability-watch.ts +++ b/apps/web/src/trpc/routers/vulnerability-watch.ts @@ -45,7 +45,7 @@ export const vulnerabilityWatchRouter = createRouter({ z .object({ enabled: z.boolean(), - excludedRepositoryIds: z.array(z.string().uuid()).max(1000), + excludedRepositoryIds: z.array(z.guid()).max(1000), }) .strict(), ) diff --git a/apps/worker/package.json b/apps/worker/package.json index a1329e919c..c1d6f396dc 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -46,7 +46,7 @@ "superjson": "^2.2.6", "ws": "^8.20.1", "yaml": "^2.9.0", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-eslint": "workspace:^", diff --git a/apps/worker/src/mcp/roomote-mcp-server/__tests__/automation-work-items-tool-schema.test.ts b/apps/worker/src/mcp/roomote-mcp-server/__tests__/automation-work-items-tool-schema.test.ts index d638104a1e..a8e4a1fee7 100644 --- a/apps/worker/src/mcp/roomote-mcp-server/__tests__/automation-work-items-tool-schema.test.ts +++ b/apps/worker/src/mcp/roomote-mcp-server/__tests__/automation-work-items-tool-schema.test.ts @@ -34,14 +34,11 @@ describe('automationWorkItemInputSchema', () => { )) { let schema: z.ZodTypeAny = fieldSchema; - while ( - schema instanceof z.ZodOptional || - schema instanceof z.ZodEffects - ) { + while (schema instanceof z.ZodOptional || schema instanceof z.ZodPipe) { schema = schema instanceof z.ZodOptional - ? schema.unwrap() - : schema.innerType(); + ? (schema.unwrap() as z.ZodType) + : (schema.in as z.ZodType); } expect( diff --git a/apps/worker/src/mcp/roomote-mcp-server/__tests__/report-platform-issue.test.ts b/apps/worker/src/mcp/roomote-mcp-server/__tests__/report-platform-issue.test.ts index 81f17423e4..0a3def7280 100644 --- a/apps/worker/src/mcp/roomote-mcp-server/__tests__/report-platform-issue.test.ts +++ b/apps/worker/src/mcp/roomote-mcp-server/__tests__/report-platform-issue.test.ts @@ -34,6 +34,19 @@ describe('handleReportPlatformIssue', () => { const parsed = JSON.parse(text); expect(parsed.success).toBe(false); - expect(parsed.error).toContain('String must contain at least 1 character'); + expect(JSON.parse(parsed.error)).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + code: 'too_small', + minimum: 1, + path: ['title'], + }), + expect.objectContaining({ + code: 'too_small', + minimum: 1, + path: ['summary'], + }), + ]), + ); }); }); diff --git a/apps/worker/src/mcp/roomote-mcp-server/__tests__/tool-descriptions.test.ts b/apps/worker/src/mcp/roomote-mcp-server/__tests__/tool-descriptions.test.ts index 42b781991b..fea06c5eaf 100644 --- a/apps/worker/src/mcp/roomote-mcp-server/__tests__/tool-descriptions.test.ts +++ b/apps/worker/src/mcp/roomote-mcp-server/__tests__/tool-descriptions.test.ts @@ -136,10 +136,11 @@ function unwrapSchema(schema: z.ZodTypeAny): z.ZodTypeAny { while ( current instanceof z.ZodOptional || current instanceof z.ZodNullable || - current instanceof z.ZodEffects + current instanceof z.ZodPipe ) { - current = - current instanceof z.ZodEffects ? current.innerType() : current.unwrap(); + current = ( + current instanceof z.ZodPipe ? current.in : current.unwrap() + ) as z.ZodType; } return current; diff --git a/apps/worker/src/mcp/roomote-mcp-server/automation-work-items-tool.ts b/apps/worker/src/mcp/roomote-mcp-server/automation-work-items-tool.ts index 9949c624a5..acfab52b83 100644 --- a/apps/worker/src/mcp/roomote-mcp-server/automation-work-items-tool.ts +++ b/apps/worker/src/mcp/roomote-mcp-server/automation-work-items-tool.ts @@ -21,7 +21,7 @@ const nonEmptyTrimmedStringSchema = z }); const uuidStringSchema = z .string() - .refine((value) => z.string().uuid().safeParse(value).success, { + .refine((value) => z.guid().safeParse(value).success, { message: 'Value must be a UUID.', }); diff --git a/apps/worker/src/mcp/roomote-mcp-server/index.ts b/apps/worker/src/mcp/roomote-mcp-server/index.ts index 762b97d134..4333b4a7b4 100644 --- a/apps/worker/src/mcp/roomote-mcp-server/index.ts +++ b/apps/worker/src/mcp/roomote-mcp-server/index.ts @@ -178,7 +178,7 @@ const boundedNonEmptyStringSchema = (maximumLength: number) => }); const uuidStringSchema = z .string() - .refine((value) => z.string().uuid().safeParse(value).success, { + .refine((value) => z.guid().safeParse(value).success, { message: 'Value must be a UUID.', }); diff --git a/apps/worker/src/mcp/roomote-mcp-server/on-demand-integrations.ts b/apps/worker/src/mcp/roomote-mcp-server/on-demand-integrations.ts index a22c0c4547..1fe60e8f67 100644 --- a/apps/worker/src/mcp/roomote-mcp-server/on-demand-integrations.ts +++ b/apps/worker/src/mcp/roomote-mcp-server/on-demand-integrations.ts @@ -33,7 +33,7 @@ const onDemandMcpServerSchema = z.object({ displayName: z.string().min(1), description: z.string().optional(), url: z.string().url(), - headers: z.record(z.string()).optional(), + headers: z.record(z.string(), z.string()).optional(), }); const onDemandMcpCatalogSchema = z.object({ diff --git a/apps/worker/src/sandbox-server/procedures/answerUserInputRequest.ts b/apps/worker/src/sandbox-server/procedures/answerUserInputRequest.ts index b00b15654a..10a70fa0b4 100644 --- a/apps/worker/src/sandbox-server/procedures/answerUserInputRequest.ts +++ b/apps/worker/src/sandbox-server/procedures/answerUserInputRequest.ts @@ -15,6 +15,7 @@ import { } from './slackQuoteTracking'; const requestUserInputAnswersSchema = z.record( + z.string(), z.object({ answers: z.array(z.string()), }), diff --git a/package.json b/package.json index 0b95c0ff0e..e9254008e0 100644 --- a/package.json +++ b/package.json @@ -122,9 +122,7 @@ "socket.io>socket.io-adapter": "2.5.8", "socket.io-adapter>ws": "8.21.0", "tar": "7.5.21", - "zod": "^3.25.76", - "astro>zod": "^4.3.6", - "knip>zod": "^4.1.11", + "zod": "4.6.6", "@streamdown/mermaid>mermaid": "11.16.1", "nanoid@<4": "5.1.16", "dagre-d3-es>lodash-es": "4.18.1", @@ -132,7 +130,8 @@ "jayson>uuid": "11.1.1", "preact": ">=10.26.10", "smol-toml": "1.9.0", - "undici": "^7.29.1", + "undici": "7.30.1", + "@azure/msal-node": "7.1.0", "diff": ">=5.2.2", "flatted": "^3.4.2", "@protobufjs/utf8": "1.1.1", @@ -148,7 +147,7 @@ "brace-expansion@<1.1.21": "1.1.21", "brace-expansion@>=2.0.0 <2.1.7": "2.1.7", "brace-expansion@>=3.0.0 <5.0.12": "5.0.12", - "fast-uri": "3.1.8", + "fast-uri": "3.1.9", "ip-address": "10.7.4", "immutable": "5.1.8", "moment": "2.31.0", diff --git a/packages/ado/package.json b/packages/ado/package.json index 10b4b03238..a29f73afe1 100644 --- a/packages/ado/package.json +++ b/packages/ado/package.json @@ -15,7 +15,7 @@ "dependencies": { "@roomote/db": "workspace:^", "@roomote/types": "workspace:^", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/ado/src/api.ts b/packages/ado/src/api.ts index b88cd037e6..9fe34221c9 100644 --- a/packages/ado/src/api.ts +++ b/packages/ado/src/api.ts @@ -138,8 +138,8 @@ const adoServiceHookSubscriptionSchema = z resourceVersion: z.string().optional(), consumerId: z.string().optional(), consumerActionId: z.string().optional(), - publisherInputs: z.record(z.string()).optional(), - consumerInputs: z.record(z.string()).optional(), + publisherInputs: z.record(z.string(), z.string()).optional(), + consumerInputs: z.record(z.string(), z.string()).optional(), }) .passthrough(); const adoServiceHookSubscriptionListResponseSchema = z.object({ diff --git a/packages/auth/package.json b/packages/auth/package.json index 3b746d75d4..85b4642923 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -41,7 +41,7 @@ "@roomote/env": "workspace:^", "@roomote/types": "workspace:^", "jsonwebtoken": "^9.0.3", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/auth/src/auth-token.ts b/packages/auth/src/auth-token.ts index 06bc14fa1f..25f9a8e013 100644 --- a/packages/auth/src/auth-token.ts +++ b/packages/auth/src/auth-token.ts @@ -106,7 +106,7 @@ export async function validateAuthToken( const parseResult = authTokenPayloadSchema.safeParse(rawPayload); if (!parseResult.success) { - const validationErrors = parseResult.error.errors + const validationErrors = parseResult.error.issues .map((err) => `${err.path.join('.')}: ${err.message}`) .join(', '); diff --git a/packages/auth/src/preview-token.ts b/packages/auth/src/preview-token.ts index 945c283c5d..a50e24c713 100644 --- a/packages/auth/src/preview-token.ts +++ b/packages/auth/src/preview-token.ts @@ -86,7 +86,7 @@ export async function validatePreviewToken( const parseResult = previewTokenPayloadSchema.safeParse(rawPayload); if (!parseResult.success) { - const validationErrors = parseResult.error.errors + const validationErrors = parseResult.error.issues .map((err) => `${err.path.join('.')}: ${err.message}`) .join(', '); diff --git a/packages/auth/src/run-token.ts b/packages/auth/src/run-token.ts index 2d3ed8d9bf..abb03a1843 100644 --- a/packages/auth/src/run-token.ts +++ b/packages/auth/src/run-token.ts @@ -102,7 +102,7 @@ export async function validateRunToken( const parseResult = compatibleRunTokenPayloadSchema.safeParse(rawPayload); if (!parseResult.success) { - const validationErrors = parseResult.error.errors + const validationErrors = parseResult.error.issues .map((err) => `${err.path.join('.')}: ${err.message}`) .join(', '); diff --git a/packages/auth/src/session-broker-token.ts b/packages/auth/src/session-broker-token.ts index d68cd9ce84..b26d9e4d44 100644 --- a/packages/auth/src/session-broker-token.ts +++ b/packages/auth/src/session-broker-token.ts @@ -11,7 +11,7 @@ const claims = z.object({ sub: z.string().min(1), aud: z.literal('roomote-session-broker'), exp: z.number().int(), - r: z.object({ t: z.literal('session-broker'), c: z.string().uuid() }), + r: z.object({ t: z.literal('session-broker'), c: z.guid() }), }); export interface SessionBrokerContext { diff --git a/packages/bitbucket/package.json b/packages/bitbucket/package.json index 2c0952e198..1109573ead 100644 --- a/packages/bitbucket/package.json +++ b/packages/bitbucket/package.json @@ -19,7 +19,7 @@ "@roomote/db": "workspace:^", "@roomote/source-control-oauth": "workspace:^", "@roomote/types": "workspace:^", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/cloud-agents/package.json b/packages/cloud-agents/package.json index 2a04569fc0..703bac16ce 100644 --- a/packages/cloud-agents/package.json +++ b/packages/cloud-agents/package.json @@ -123,8 +123,7 @@ "mammoth": "^1.11.0", "pdfjs-dist": "^6.2.108", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz", - "zod": "^3.25.76", - "zod-to-json-schema": "3.25.1" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/cloud-agents/src/server/__tests__/slack-question-channel-suggestions.test.ts b/packages/cloud-agents/src/server/__tests__/slack-question-channel-suggestions.test.ts index 0999fa617a..3e8f40aaeb 100644 --- a/packages/cloud-agents/src/server/__tests__/slack-question-channel-suggestions.test.ts +++ b/packages/cloud-agents/src/server/__tests__/slack-question-channel-suggestions.test.ts @@ -1,4 +1,4 @@ -import zodToJsonSchema from 'zod-to-json-schema'; +import { z } from 'zod'; const { mockGenerateTrackedNonTaskObject } = vi.hoisted(() => ({ mockGenerateTrackedNonTaskObject: vi.fn(), @@ -107,9 +107,10 @@ describe('suggestSlackQuestionChannels', () => { false, ); - const wireSchema = zodToJsonSchema(schema, { - $refStrategy: 'none', - target: 'jsonSchema7', + const wireSchema = z.toJSONSchema(schema, { + reused: 'inline', + target: 'draft-7', + io: 'input', }); expect(JSON.stringify(wireSchema)).not.toMatch( /"(?:minItems|maxItems|minLength|maxLength|minimum|maximum|exclusiveMinimum|exclusiveMaximum)"/, diff --git a/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-native-tool-schemas.test.ts b/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-native-tool-schemas.test.ts index d7f648cbdf..04b94ce775 100644 --- a/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-native-tool-schemas.test.ts +++ b/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-native-tool-schemas.test.ts @@ -221,7 +221,7 @@ function toOpenCodeJsonSchema(zod: ZodV4, args: unknown) { describe('Fast native tool schemas as OpenAI receives them', () => { const validator = new Ajv2020({ strict: false }).addFormat( 'uuid', - (value: string) => z.string().uuid().safeParse(value).success, + (value: string) => z.guid().safeParse(value).success, ); let workDir: string; let zod: ZodV4; diff --git a/packages/cloud-agents/src/server/fast-agent/fast-agent-native-tool-bridge.ts b/packages/cloud-agents/src/server/fast-agent/fast-agent-native-tool-bridge.ts index 47da3d58df..8018bf844a 100644 --- a/packages/cloud-agents/src/server/fast-agent/fast-agent-native-tool-bridge.ts +++ b/packages/cloud-agents/src/server/fast-agent/fast-agent-native-tool-bridge.ts @@ -264,7 +264,7 @@ const bridgeRequestSchema = z.object({ ...FastAgentNativeToolName[], ], ), - args: z.record(z.unknown()), + args: z.record(z.string(), z.unknown()), agent: z.string().min(1).optional(), }); @@ -690,7 +690,7 @@ export default { description: "Add or reconnect one remote MCP integration from its HTTPS streamable-HTTP endpoint. Any member may call this. Use it for a service's official hosted remote MCP endpoint or a URL the human supplied; never invent a URL, and a local stdio project is not a hosted MCP. It is shared with everyone in the deployment by default, like an integration key; pass visibility 'owner' only when the human asked to keep it private to them, and say which it is when you report it. The server verifies the endpoint before saving it, reuses an existing matching integration, and returns either connected tools, a secure OAuth authorization link, or a settingsUrl for static headers/manual OAuth client setup: the Integrations page for a shared server, or Personal settings for a private one. Roomote registers this deployment with the provider before returning an authorization link, so a returned link can succeed. A client-registration-required or needs-static-headers result means this human cannot connect it now: relay the result's reason (the provider's own words) when present, share settingsUrl as the alternative, and continue with the integration-key route. A pending-owner result means a shared server someone else added is still waiting on them or an administrator: say so, share no link, and continue with the integration-key route or a private server of their own if they ask. Server-backed results include integrationId, the actual Fast catalog ID: use that exact integrationId with find_integration_tools and call_integration_tool, never a server UUID, but do not narrate IDs or catalog checks to the human. Share authorizeUrl and settingsUrl exactly unchanged, labeled 'Authorize ' and 'Integration settings' respectively; never rewrite either target. The conversation resumes automatically after the human authorizes, so never ask them to send a follow-up. In user-visible progress say at most that you are checking. Never ask for or accept secrets in chat or tool arguments.", args: { name: z.string().trim().min(1).max(80).describe("Short integration name; Roomote normalizes it to a lowercase slug"), - url: z.string().url().startsWith("https://").max(2048).describe("HTTPS streamable-HTTP MCP endpoint"), + url: z.string().regex(/^https:\/\/.*/).url().max(2048).describe("HTTPS streamable-HTTP MCP endpoint"), visibility: z.enum(["owner", "deployment"]).optional().describe("deployment (default) shares it with everyone; owner keeps it private to the requesting human"), }, execute: (args, context) => invoke("add_remote_mcp", args, context), diff --git a/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts b/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts index a67c40b8fe..7ddc8caf33 100644 --- a/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts +++ b/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts @@ -1961,7 +1961,11 @@ function isSuccessfulChatReactionResult( const addRemoteMcpArgsSchema = z .object({ name: z.string().trim().min(1).max(80), - url: z.string().url().startsWith('https://').max(2_048), + url: z + .string() + .regex(/^https:\/\/.*/) + .url() + .max(2_048), visibility: customMcpServerVisibilitySchema.optional(), }) .strict(); diff --git a/packages/cloud-agents/src/server/mcp-nullable-optionals.test.ts b/packages/cloud-agents/src/server/mcp-nullable-optionals.test.ts index f2006d5b36..978bb2468e 100644 --- a/packages/cloud-agents/src/server/mcp-nullable-optionals.test.ts +++ b/packages/cloud-agents/src/server/mcp-nullable-optionals.test.ts @@ -137,6 +137,59 @@ describe('withNullableOptionals', () => { it('passes through undefined unchanged', () => { expect(withNullableOptionals(undefined)).toBeUndefined(); }); + + it('preserves object and array checks and descriptions while adapting nested fields', () => { + const original = z + .object({ + entries: z + .array(z.object({ name: z.string().optional() })) + .max(2) + .describe('bounded entries'), + }) + .refine((value) => value.entries.length > 0, 'At least one entry') + .describe('checked object'); + const adapted = withNullableOptionals(original); + expect(adapted.description).toBe('checked object'); + expect(adapted.shape.entries.description).toBe('bounded entries'); + expect(adapted.parse({ entries: [{ name: null }] })).toEqual({ + entries: [{ name: undefined }], + }); + expect(adapted.safeParse({ entries: [] }).success).toBe(false); + expect(adapted.safeParse({ entries: [{}, {}, {}] }).success).toBe(false); + }); + + it('adapts nested discriminated unions and transformed objects', () => { + const original = z + .discriminatedUnion('kind', [ + z.object({ kind: z.literal('text'), note: z.string().optional() }), + z.object({ + kind: z.literal('count'), + count: z.number().int().optional(), + }), + ]) + .transform((value) => ({ ...value, parsed: true })); + const adapted = withNullableOptionals(original); + expect(adapted.parse({ kind: 'text', note: null })).toEqual({ + kind: 'text', + note: undefined, + parsed: true, + }); + expect(adapted.parse({ kind: 'count', count: '2' })).toEqual({ + kind: 'count', + count: 2, + parsed: true, + }); + expect(adapted.safeParse({ kind: 'other' }).success).toBe(false); + }); + + it('evaluates a default factory for each null input', () => { + let next = 0; + const adapted = withNullableOptionals( + z.object({ value: z.number().default(() => ++next) }), + ); + expect(adapted.parse({ value: null }).value).toBe(1); + expect(adapted.parse({ value: null }).value).toBe(2); + }); }); describe('NullableOptionalsMcpServer', () => { @@ -255,7 +308,7 @@ describe('NullableOptionalsMcpServer', () => { >; expect(properties.prNumber).toMatchObject({ type: 'integer' }); expect(properties.resolved).toMatchObject({ - anyOf: [{ type: 'boolean' }, { type: 'null' }], + type: ['boolean', 'null'], }); await client.callTool({ diff --git a/packages/cloud-agents/src/server/mcp-nullable-optionals.ts b/packages/cloud-agents/src/server/mcp-nullable-optionals.ts index 56e34d900a..6630fd4d83 100644 --- a/packages/cloud-agents/src/server/mcp-nullable-optionals.ts +++ b/packages/cloud-agents/src/server/mcp-nullable-optionals.ts @@ -83,7 +83,7 @@ function deserializeTransportPrimitive(schema: ZodTypeAny): ZodTypeAny { function allowNullDeep(schema: ZodTypeAny): ZodTypeAny { if (schema instanceof z.ZodOptional) { - const inner = allowNullDeep(schema.unwrap()); + const inner = allowNullDeep(schema.unwrap() as ZodTypeAny); const nullable = inner instanceof z.ZodNullable ? inner @@ -91,50 +91,66 @@ function allowNullDeep(schema: ZodTypeAny): ZodTypeAny { return keepDescription(nullable.optional(), schema.description); } if (schema instanceof z.ZodDefault) { - const defaultValue = schema._def.defaultValue; - const inner = allowNullDeep(schema.removeDefault()) + const defaultValue = () => schema.def.defaultValue; + const inner = allowNullDeep(schema.removeDefault() as ZodTypeAny) .nullable() .transform((value) => value ?? defaultValue()); return keepDescription(inner.default(defaultValue), schema.description); } if (schema instanceof z.ZodNullable) { - return new z.ZodNullable({ - ...schema._def, - innerType: allowNullDeep(schema.unwrap()), - }); + return keepDescription( + new z.ZodNullable({ + ...schema.def, + innerType: allowNullDeep(schema.unwrap() as ZodTypeAny), + }), + schema.description, + ); } - if (schema instanceof z.ZodEffects) { - return new z.ZodEffects({ - ...schema._def, - schema: allowNullDeep(schema.innerType()), - }); + if (schema instanceof z.ZodPipe) { + return keepDescription( + new z.ZodPipe({ + ...schema.def, + in: allowNullDeep(schema.in as ZodTypeAny), + out: allowNullDeep(schema.out as ZodTypeAny), + }), + schema.description, + ); } if (schema instanceof z.ZodObject) { const shape = withNullableOptionals(schema.shape as z.ZodRawShape); - return new z.ZodObject({ ...schema._def, shape: () => shape }); + return keepDescription( + new z.ZodObject({ ...schema.def, shape }), + schema.description, + ); } if (schema instanceof z.ZodArray) { - return new z.ZodArray({ - ...schema._def, - type: allowNullDeep(schema.element), - }); - } - if (schema instanceof z.ZodUnion) { - const options = (schema.options as ZodTypeAny[]).map(allowNullDeep); - return new z.ZodUnion({ - ...schema._def, - options: options as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]], - }); + return keepDescription( + new z.ZodArray({ + ...schema.def, + element: allowNullDeep(schema.element as ZodTypeAny), + }), + schema.description, + ); } if (schema instanceof z.ZodDiscriminatedUnion) { - const options = (schema.options as z.AnyZodObject[]).map( - (option) => allowNullDeep(option) as z.AnyZodObject, + return keepDescription( + new z.ZodDiscriminatedUnion({ + ...schema.def, + discriminator: schema.def.discriminator, + options: schema.options.map((option) => + allowNullDeep(option as ZodTypeAny), + ), + }), + schema.description, ); + } + if (schema instanceof z.ZodUnion) { + const options = (schema.options as ZodTypeAny[]).map(allowNullDeep); return keepDescription( - z.discriminatedUnion( - schema.discriminator, - options as [z.AnyZodObject, z.AnyZodObject, ...z.AnyZodObject[]], - ), + new z.ZodUnion({ + ...schema.def, + options: options as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]], + }), schema.description, ); } diff --git a/packages/cloud-agents/src/server/non-task-provider-usage.ts b/packages/cloud-agents/src/server/non-task-provider-usage.ts index 2fb40a7220..74cd7848a5 100644 --- a/packages/cloud-agents/src/server/non-task-provider-usage.ts +++ b/packages/cloud-agents/src/server/non-task-provider-usage.ts @@ -32,8 +32,7 @@ import { TASK_MODEL_ROLE_DESCRIPTORS, } from '@roomote/types'; import { captureInstanceEvent } from '@roomote/telemetry/server'; -import type { z } from 'zod'; -import zodToJsonSchema from 'zod-to-json-schema'; +import { z } from 'zod'; import { decodeInferenceErrorEnvelope } from './inference-error-envelope'; import { streamOpenCodeEventsAcrossDisposal } from './opencode-event-stream'; @@ -2730,9 +2729,10 @@ async function generateTrackedNonTaskObjectWithSdk< export function buildNonTaskStructuredOutputJsonSchema( schema: z.ZodTypeAny, ): Record { - return zodToJsonSchema(schema, { - $refStrategy: 'none', - target: 'jsonSchema7', + return z.toJSONSchema(schema, { + reused: 'inline', + target: 'draft-7', + io: 'input', }) as Record; } diff --git a/packages/cloud-agents/src/server/task-run-queue.ts b/packages/cloud-agents/src/server/task-run-queue.ts index b8b1ac56e8..10c51e495b 100644 --- a/packages/cloud-agents/src/server/task-run-queue.ts +++ b/packages/cloud-agents/src/server/task-run-queue.ts @@ -2791,7 +2791,7 @@ function inheritSnapshotResumeSourceControlStamps( if (usesSourceProvider && payload.repositoryProviders === undefined) { const repositoryProviders = z - .record(sourceControlProviderSchema) + .record(z.string(), sourceControlProviderSchema) .safeParse(source.repositoryProviders); if (repositoryProviders.success) { @@ -2838,7 +2838,7 @@ function inheritSnapshotResumeFastAgentSession( ): void { const fastAgentSessionId = z .string() - .uuid() + .check(z.guid()) .safeParse( sourcePayload && typeof sourcePayload === 'object' ? (sourcePayload as Record).fastAgentSessionId diff --git a/packages/communication/package.json b/packages/communication/package.json index 777cb30de5..00e018c21a 100644 --- a/packages/communication/package.json +++ b/packages/communication/package.json @@ -50,7 +50,7 @@ "@roomote/env": "workspace:^", "@roomote/redis": "workspace:^", "@roomote/types": "workspace:^", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/communication/scripts/run-mock-discord.ts b/packages/communication/scripts/run-mock-discord.ts index 40629d162a..dcbf2ff55b 100644 --- a/packages/communication/scripts/run-mock-discord.ts +++ b/packages/communication/scripts/run-mock-discord.ts @@ -52,7 +52,7 @@ const configSchema = z.object({ .array( z.object({ kind: z.enum(['message', 'interaction']), - payload: z.record(z.unknown()), + payload: z.record(z.string(), z.unknown()), eventId: z.string().min(1).optional(), }), ) diff --git a/packages/communication/scripts/run-mock-telegram.ts b/packages/communication/scripts/run-mock-telegram.ts index 4f5eaee050..7af57febaa 100644 --- a/packages/communication/scripts/run-mock-telegram.ts +++ b/packages/communication/scripts/run-mock-telegram.ts @@ -25,7 +25,7 @@ const inboundMessageSchema = z message_id: z.number().int().optional(), message_thread_id: z.number().int().optional(), date: z.number().int().optional(), - entities: z.array(z.record(z.unknown())).optional(), + entities: z.array(z.record(z.string(), z.unknown())).optional(), }) .passthrough(); @@ -70,7 +70,7 @@ const configSchema = z.object({ }) .passthrough(), ), - messages: z.array(z.record(z.unknown())).optional(), + messages: z.array(z.record(z.string(), z.unknown())).optional(), behavior: z .object({ rejectHtmlParseMode: z.boolean().optional(), @@ -99,13 +99,13 @@ const configSchema = z.object({ id: z.string().min(1), from: z.object({ id: z.number() }).passthrough(), data: z.string().optional(), - message: z.record(z.unknown()).optional(), + message: z.record(z.string(), z.unknown()).optional(), }) .passthrough(), }), z.object({ kind: z.literal('update'), - update: z.record(z.unknown()), + update: z.record(z.string(), z.unknown()), }), ]), ) diff --git a/packages/communication/src/mock-agentmail-config.ts b/packages/communication/src/mock-agentmail-config.ts index 0d595035a1..fdc27632ac 100644 --- a/packages/communication/src/mock-agentmail-config.ts +++ b/packages/communication/src/mock-agentmail-config.ts @@ -85,7 +85,7 @@ const configSchema = z.object({ .passthrough(), ) .optional(), - messages: z.array(z.record(z.unknown())).optional(), + messages: z.array(z.record(z.string(), z.unknown())).optional(), // Seeded events make `kind: "redeliver"` usable from a scenario file: // the redelivery reuses the stored svix id and resends the payload. events: z @@ -98,7 +98,7 @@ const configSchema = z.object({ inbox_id: z.string().min(1), message_id: z.string().min(1), payload: z.string().min(1), - deliveries: z.array(z.record(z.unknown())).optional(), + deliveries: z.array(z.record(z.string(), z.unknown())).optional(), }) .passthrough(), ) diff --git a/packages/db/package.json b/packages/db/package.json index 5fbe286da7..9cc2c1aa00 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -60,6 +60,6 @@ "drizzle-kit": "^0.31.9", "fishery": "^2.4.0", "vitest": "^4.1.1", - "zod": "^3.25.76" + "zod": "^4.6.6" } } diff --git a/packages/db/src/lib/custom-skills.ts b/packages/db/src/lib/custom-skills.ts index 75ef5ce827..0015b5d0d6 100644 --- a/packages/db/src/lib/custom-skills.ts +++ b/packages/db/src/lib/custom-skills.ts @@ -34,7 +34,7 @@ async function requireMember(tx: Transaction, actorUserId: string) { } async function readSkill(tx: Transaction, skillId: string) { - if (!z.string().uuid().safeParse(skillId).success) + if (!z.guid().safeParse(skillId).success) throw new CreateCustomSkillError('Skill not found', 404); const [skill] = await tx .select() diff --git a/packages/env/package.json b/packages/env/package.json index 09cc85e75a..74fce3a2bf 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -16,7 +16,7 @@ "dependencies": { "@roomote/types": "workspace:^", "@t3-oss/env-nextjs": "^0.13.10", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/gitea/package.json b/packages/gitea/package.json index 531bba0b69..8d503a106f 100644 --- a/packages/gitea/package.json +++ b/packages/gitea/package.json @@ -16,7 +16,7 @@ "@roomote/db": "workspace:^", "@roomote/source-control-oauth": "workspace:^", "@roomote/types": "workspace:^", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/gitea/src/api.ts b/packages/gitea/src/api.ts index ded2dc0363..e5a64b151e 100644 --- a/packages/gitea/src/api.ts +++ b/packages/gitea/src/api.ts @@ -60,7 +60,7 @@ const giteaHookSchema = z .object({ id: z.number(), type: z.string().optional(), - config: z.record(z.string()).optional(), + config: z.record(z.string(), z.string()).optional(), }) .passthrough(); const giteaHookListSchema = z.array(giteaHookSchema); diff --git a/packages/github/package.json b/packages/github/package.json index ec81421fc2..7c5ff8ac7f 100644 --- a/packages/github/package.json +++ b/packages/github/package.json @@ -21,7 +21,7 @@ "execa": "9.6.1", "jsonwebtoken": "^9.0.3", "p-map": "^7.0.4", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/gitlab/package.json b/packages/gitlab/package.json index 06986697c9..c66a01ebad 100644 --- a/packages/gitlab/package.json +++ b/packages/gitlab/package.json @@ -16,7 +16,7 @@ "@roomote/db": "workspace:^", "@roomote/source-control-oauth": "workspace:^", "@roomote/types": "workspace:^", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/linear/package.json b/packages/linear/package.json index 08ad7a4378..29c235f78c 100644 --- a/packages/linear/package.json +++ b/packages/linear/package.json @@ -22,7 +22,7 @@ "@roomote/redis": "workspace:^", "@roomote/telemetry": "workspace:^", "@roomote/types": "workspace:^", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/linear/src/types.ts b/packages/linear/src/types.ts index e241d469f4..66c7d51d3a 100644 --- a/packages/linear/src/types.ts +++ b/packages/linear/src/types.ts @@ -153,7 +153,7 @@ const webhookAgentActivitySchema = z.object({ userId: z.string().optional(), content: webhookAgentActivityContentSchema, signal: humanToAgentSignalSchema.nullish(), - signalMetadata: z.record(z.unknown()).nullish(), + signalMetadata: z.record(z.string(), z.unknown()).nullish(), ephemeral: z.boolean().optional(), }); diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 2a22786653..f7bba4d093 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -151,7 +151,7 @@ "undici": "^7.29.1", "unzipper": "^0.12.5", "yaml": "^2.9.0", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/sdk/src/server/automations/vulnerability-watch/matching.ts b/packages/sdk/src/server/automations/vulnerability-watch/matching.ts index 41a05b4a26..49171d715e 100644 --- a/packages/sdk/src/server/automations/vulnerability-watch/matching.ts +++ b/packages/sdk/src/server/automations/vulnerability-watch/matching.ts @@ -119,7 +119,7 @@ export function matchCve( if (m.other?.type === 'kev') return true; if (m.other?.type !== 'ssvc') return false; const ssvc = z - .object({ options: z.array(z.record(z.unknown())) }) + .object({ options: z.array(z.record(z.string(), z.unknown())) }) .safeParse(m.other.content); return ( ssvc.success && diff --git a/packages/sdk/src/server/lib/automation-recommendations.ts b/packages/sdk/src/server/lib/automation-recommendations.ts index 43039e925d..66e79f7ee6 100644 --- a/packages/sdk/src/server/lib/automation-recommendations.ts +++ b/packages/sdk/src/server/lib/automation-recommendations.ts @@ -86,14 +86,14 @@ type GitHubOctokitCache = Map>; export const automationRecommendationJobSchema = z.object({ fingerprint: z.string().min(1), - repositoryIds: z.array(z.string().uuid()), + repositoryIds: z.array(z.guid()), }); export type AutomationRecommendationJob = z.infer< typeof automationRecommendationJobSchema >; export const automationSignalPrefetchJobSchema = z.object({ - repositoryId: z.string().uuid(), + repositoryId: z.guid(), signalsVersion: z.number().int().positive(), }); export type AutomationSignalPrefetchJob = z.infer< diff --git a/packages/sdk/src/server/lib/credential-egress.ts b/packages/sdk/src/server/lib/credential-egress.ts index 66a5e884ae..4ee97bcf96 100644 --- a/packages/sdk/src/server/lib/credential-egress.ts +++ b/packages/sdk/src/server/lib/credential-egress.ts @@ -77,16 +77,13 @@ export class CredentialEgressRequestError extends Error { } } -function parse( - schema: z.ZodType, - input: unknown, -): T { +function parse(schema: z.ZodType, input: unknown): T { const parsed = schema.safeParse(input); if (!parsed.success) throw new CredentialEgressRequestError(400, 'malformed'); return parsed.data; } -const workloadIdSchema = z.string().uuid(); +const workloadIdSchema = z.guid(); export async function registerWorkload( input: unknown, diff --git a/packages/sdk/src/server/lib/task-runs/pr-review-notification.ts b/packages/sdk/src/server/lib/task-runs/pr-review-notification.ts index ac93aed462..9426193b23 100644 --- a/packages/sdk/src/server/lib/task-runs/pr-review-notification.ts +++ b/packages/sdk/src/server/lib/task-runs/pr-review-notification.ts @@ -173,13 +173,13 @@ export const prReviewNotificationRequestSchema = z.object({ batchId: z.string().optional(), sourceControlProvider: sourceControlProviderSchema.optional(), host: z.string().nullable().optional(), - repositoryId: z.string().uuid().nullable().optional(), + repositoryId: z.guid().nullable().optional(), deliveryIds: z.array(z.string()).optional(), leaseToken: z.string().optional(), events: z.array(prReviewActivityEventSchema).optional(), ownershipVersion: z.enum(['legacy', 'canonical']).optional(), - deliveryId: z.string().uuid().optional(), - notificationUnitId: z.string().uuid().optional(), + deliveryId: z.guid().optional(), + notificationUnitId: z.guid().optional(), destinationKey: z.string().optional(), deliveryState: z .enum([ diff --git a/packages/sdk/src/server/lib/task-runs/pull-request-mergeability-check.ts b/packages/sdk/src/server/lib/task-runs/pull-request-mergeability-check.ts index 86bb4ab6b4..ce702d1a9f 100644 --- a/packages/sdk/src/server/lib/task-runs/pull-request-mergeability-check.ts +++ b/packages/sdk/src/server/lib/task-runs/pull-request-mergeability-check.ts @@ -23,7 +23,7 @@ export const pullRequestMergeabilityCheckRequestSchema = z // still picked up. baseRef: z.string().min(1).optional(), prNumber: z.number().int().positive().optional(), - taskPullRequestIds: z.array(z.string().uuid()).min(1).optional(), + taskPullRequestIds: z.array(z.guid()).min(1).optional(), deduplicationKey: z.string().min(1), retryAttempt: z.union([z.literal(0), z.literal(1)]), allowNotifiedConflictCheck: z.boolean().default(false), diff --git a/packages/sdk/src/server/routers/linear-sessions.ts b/packages/sdk/src/server/routers/linear-sessions.ts index 392ad58405..1ea11bb658 100644 --- a/packages/sdk/src/server/routers/linear-sessions.ts +++ b/packages/sdk/src/server/routers/linear-sessions.ts @@ -126,7 +126,7 @@ export const linearSessionsRouter = router({ sessionId: z.string(), content: z.string(), signal: z.enum(['select']).optional(), - signalMetadata: z.record(z.unknown()).optional(), + signalMetadata: z.record(z.string(), z.unknown()).optional(), }), ) .mutation(async ({ input }) => { diff --git a/packages/sdk/src/server/routers/llm-usage.ts b/packages/sdk/src/server/routers/llm-usage.ts index 9b069e27d2..eb2b26f74b 100644 --- a/packages/sdk/src/server/routers/llm-usage.ts +++ b/packages/sdk/src/server/routers/llm-usage.ts @@ -19,7 +19,7 @@ export const llmUsageRouter = router({ eventKey: z.string().min(1).nullable().optional(), taskId: z.string().nullable().optional(), runId: z.number().int().nullable().optional(), - environmentId: z.string().uuid().nullable().optional(), + environmentId: z.guid().nullable().optional(), harnessSessionId: z.string().nullable().optional(), messageId: z.string().nullable().optional(), providerId: z.string().nullable().optional(), @@ -36,8 +36,11 @@ export const llmUsageRouter = router({ costSource: z.enum(LLM_USAGE_COST_SOURCES).nullable().optional(), messageCreatedAt: z.date().nullable().optional(), messageCompletedAt: z.date().nullable().optional(), - pricingMetadata: z.record(z.unknown()).nullable().optional(), - details: z.record(z.unknown()).nullable().optional(), + pricingMetadata: z + .record(z.string(), z.unknown()) + .nullable() + .optional(), + details: z.record(z.string(), z.unknown()).nullable().optional(), }), ) .mutation(async ({ ctx, input }) => { diff --git a/packages/sdk/src/server/routers/mcp-connections.ts b/packages/sdk/src/server/routers/mcp-connections.ts index c746f2ad77..b84c5af195 100644 --- a/packages/sdk/src/server/routers/mcp-connections.ts +++ b/packages/sdk/src/server/routers/mcp-connections.ts @@ -271,7 +271,7 @@ export const mcpConnectionsRouter = router({ hasValidTokens: userOnlyProcedure .input( z.object({ - id: z.string().uuid(), + id: z.guid(), }), ) .query(async ({ ctx, input }) => { @@ -353,7 +353,7 @@ export const mcpConnectionsRouter = router({ * not be able to read directly. */ markCredentialEgressBootstrapReady: authenticatedProcedure - .input(z.object({ nonce: z.string().uuid() }).strict()) + .input(z.object({ nonce: z.guid() }).strict()) .mutation(async ({ ctx, input }) => { try { await markCredentialEgressBootstrapReady(ctx.auth, input.nonce); @@ -367,7 +367,7 @@ export const mcpConnectionsRouter = router({ }), getCredentialEgressDelivery: authenticatedProcedure - .input(z.object({ nonce: z.string().uuid() }).strict()) + .input(z.object({ nonce: z.guid() }).strict()) .query(async ({ ctx, input }) => { try { return { diff --git a/packages/sdk/src/server/routers/task-runs.ts b/packages/sdk/src/server/routers/task-runs.ts index 3883954807..dde4915b83 100644 --- a/packages/sdk/src/server/routers/task-runs.ts +++ b/packages/sdk/src/server/routers/task-runs.ts @@ -170,6 +170,7 @@ const acpRequestUserInputQuestionSchema = z.object({ }); const acpRequestUserInputAnswersSchema = z.record( + z.string(), z.object({ answers: z.array(z.string()), }), @@ -252,7 +253,7 @@ function runTokenOnlyScoped( const targetId = typeof extractRunId === 'function' - ? extractRunId(input) + ? extractRunId(input as z.output) : (input as Record)[extractRunId as string]; if (targetId !== ctx.auth.runId) { @@ -317,7 +318,7 @@ export const taskRunsRouter = router({ // apps/api sendMessageToTask and the webhook queue sites), which write // task_runs directly. Both fields sent by a run-token caller are // stripped by this schema. - result: z.record(z.unknown()).optional(), + result: z.record(z.string(), z.unknown()).optional(), }), 'id', ).mutation(({ input: { id, ...values } }) => updateTaskRun(id, values)), @@ -412,7 +413,7 @@ export const taskRunsRouter = router({ source: z.enum(runEventSources), eventType: z.enum(runEventTypes), message: z.string().optional(), - details: z.record(z.unknown()).optional(), + details: z.record(z.string(), z.unknown()).optional(), }), 'runId', ).mutation(({ input }) => recordTaskRunEvent(input)), @@ -540,7 +541,7 @@ export const taskRunsRouter = router({ costSource: z.enum(LLM_USAGE_COST_SOURCES).nullable().optional(), messageCreatedAt: z.date().nullable().optional(), messageCompletedAt: z.date().nullable().optional(), - details: z.record(z.unknown()).nullable().optional(), + details: z.record(z.string(), z.unknown()).nullable().optional(), }), 'runId', ).mutation(({ input }) => recordTaskInferenceUsage(input)), @@ -604,7 +605,7 @@ export const taskRunsRouter = router({ .nonnegative() .nullable() .optional(), - details: z.record(z.unknown()).nullable().optional(), + details: z.record(z.string(), z.unknown()).nullable().optional(), }), 'runId', ).mutation(({ input }) => recordComputeProviderUsage(input)), diff --git a/packages/sdk/src/server/routers/tool-approvals.ts b/packages/sdk/src/server/routers/tool-approvals.ts index da1dadb248..73911b1e7f 100644 --- a/packages/sdk/src/server/routers/tool-approvals.ts +++ b/packages/sdk/src/server/routers/tool-approvals.ts @@ -63,7 +63,7 @@ export const toolApprovalsRouter = router({ integrationId: z.string().min(1).max(200), toolName: z.string().min(1).max(200), nativeRequestId: z.string().min(1).max(200), - args: z.unknown(), + args: z.unknown().optional(), userRequest: z .string() .max(INTEGRATION_TOOL_USER_REQUEST_MAX_CHARS) @@ -83,7 +83,7 @@ export const toolApprovalsRouter = router({ /** Poll one of this task's approvals while the Session owner decides. */ status: taskRunProcedure - .input(z.object({ approvalId: z.string().uuid() }).strict()) + .input(z.object({ approvalId: z.guid() }).strict()) .query(async ({ ctx, input }) => ({ status: await getTaskToolApprovalStatus({ runId: ctx.runId, diff --git a/packages/sdk/src/server/trpc.ts b/packages/sdk/src/server/trpc.ts index d7b9e3bb3e..f8c18d3f81 100644 --- a/packages/sdk/src/server/trpc.ts +++ b/packages/sdk/src/server/trpc.ts @@ -87,7 +87,7 @@ export function runScoped( .use(async ({ ctx, input, next }) => { const targetId = ( typeof extractRunId === 'function' - ? extractRunId(input) + ? extractRunId(input as z.output) : (input as Record)[extractRunId as string] ) as number; diff --git a/packages/slack/package.json b/packages/slack/package.json index 1789320c0a..af5202119d 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -26,7 +26,7 @@ "@roomote/redis": "workspace:^", "@roomote/types": "workspace:^", "@slack/web-api": "^7.19.0", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/types/package.json b/packages/types/package.json index 31b3954330..5e6112ab6c 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "yaml": "^2.9.0", - "zod": "^3.25.76" + "zod": "^4.6.6" }, "devDependencies": { "@roomote/config-typescript": "workspace:^", diff --git a/packages/types/src/auth.ts b/packages/types/src/auth.ts index 5dca242cef..03bbc37d36 100644 --- a/packages/types/src/auth.ts +++ b/packages/types/src/auth.ts @@ -10,13 +10,13 @@ export const runTokenPayloadSchema = z.object({ exp: z.number().int().positive('Expiration (exp) must be a positive integer'), iat: z.number().int().positive('Issued at (iat) must be a positive integer'), nbf: z.number().int().positive('Not before (nbf) must be a positive integer'), - v: z.literal(1, { errorMap: () => ({ message: 'Version must be 1' }) }), + v: z.literal(1, { error: () => ({ message: 'Version must be 1' }) }), r: z.object({ // Absent user claim means the run runs as the deployment service // principal (automation-initiated work with no human driver). u: z.string().min(1, 'User ID must be non-empty when present').optional(), t: z.literal('run', { - errorMap: () => ({ message: 'Token type must be "run"' }), + error: () => ({ message: 'Token type must be "run"' }), }), }), }); @@ -51,11 +51,11 @@ export const authTokenPayloadSchema = z.object({ exp: z.number().int().positive('Expiration (exp) must be a positive integer'), iat: z.number().int().positive('Issued at (iat) must be a positive integer'), nbf: z.number().int().positive('Not before (nbf) must be a positive integer'), - v: z.literal(1, { errorMap: () => ({ message: 'Version must be 1' }) }), + v: z.literal(1, { error: () => ({ message: 'Version must be 1' }) }), r: z.object({ u: z.string().min(1, 'User ID is required'), t: z.literal('auth', { - errorMap: () => ({ message: 'Token type must be "auth"' }), + error: () => ({ message: 'Token type must be "auth"' }), }), }), }); @@ -91,11 +91,11 @@ export const mcpAccessTokenPayloadSchema = z.object({ exp: z.number().int().positive('Expiration (exp) must be a positive integer'), iat: z.number().int().positive('Issued at (iat) must be a positive integer'), nbf: z.number().int().positive('Not before (nbf) must be a positive integer'), - v: z.literal(1, { errorMap: () => ({ message: 'Version must be 1' }) }), + v: z.literal(1, { error: () => ({ message: 'Version must be 1' }) }), r: z.object({ u: z.string().min(1, 'User ID is required'), t: z.literal('mcp', { - errorMap: () => ({ message: 'Token type must be "mcp"' }), + error: () => ({ message: 'Token type must be "mcp"' }), }), s: z.array(z.string().min(1)).min(1, 'At least one scope is required'), }), @@ -121,16 +121,16 @@ export interface McpAccessTokenContext { export const previewTokenPayloadSchema = z.object({ iss: z.string().min(1, 'Issuer (iss) is required'), sub: z.literal('preview', { - errorMap: () => ({ message: 'Subject must be "preview"' }), + error: () => ({ message: 'Subject must be "preview"' }), }), exp: z.number().int().positive('Expiration (exp) must be a positive integer'), iat: z.number().int().positive('Issued at (iat) must be a positive integer'), nbf: z.number().int().positive('Not before (nbf) must be a positive integer'), - v: z.literal(1, { errorMap: () => ({ message: 'Version must be 1' }) }), + v: z.literal(1, { error: () => ({ message: 'Version must be 1' }) }), r: z.object({ u: z.string().min(1, 'User ID is required'), t: z.literal('pt', { - errorMap: () => ({ message: 'Token type must be "pt"' }), + error: () => ({ message: 'Token type must be "pt"' }), }), }), }); diff --git a/packages/types/src/automation-additional-rules.ts b/packages/types/src/automation-additional-rules.ts index 76faba9d61..36cb35d0f3 100644 --- a/packages/types/src/automation-additional-rules.ts +++ b/packages/types/src/automation-additional-rules.ts @@ -3,11 +3,11 @@ import { z } from 'zod'; export const automationAdditionalRulesSchema = z .object({ text: z.string().min(1).max(8000), - repositoryIds: z.array(z.string().uuid()).nullable(), + repositoryIds: z.array(z.guid()).nullable(), destinations: z.array( z .object({ - repositoryId: z.string().uuid(), + repositoryId: z.guid(), target: z .object({ provider: z.enum(['slack', 'discord', 'teams', 'telegram']), diff --git a/packages/types/src/credential-egress.ts b/packages/types/src/credential-egress.ts index fc03fa4a74..50e10438d0 100644 --- a/packages/types/src/credential-egress.ts +++ b/packages/types/src/credential-egress.ts @@ -214,7 +214,7 @@ export const credentialEgressProxyAuthorizeSchema = z method: credentialEgressMethodSchema, path: requestPathSchema, phase: z.enum(CREDENTIAL_EGRESS_PHASES).default('request'), - authorizationId: z.string().uuid().optional(), + authorizationId: z.guid().optional(), }) .strict(); diff --git a/packages/types/src/custom-mcp-servers.ts b/packages/types/src/custom-mcp-servers.ts index d5476a93ad..a3f84d1136 100644 --- a/packages/types/src/custom-mcp-servers.ts +++ b/packages/types/src/custom-mcp-servers.ts @@ -200,12 +200,14 @@ export const customMcpServerNameSchema = z CUSTOM_MCP_SERVER_NAME_PATTERN, 'Server name must be a lowercase slug (letters, digits, "-", "_"), at most 64 characters.', ) - .refine( - (name) => !RESERVED_CUSTOM_MCP_SERVER_NAMES.has(name), - (name) => ({ - message: `'${name}' is reserved by a built-in ${PRODUCT_NAME} integration.`, - }), - ); + .superRefine((name, ctx) => { + if (RESERVED_CUSTOM_MCP_SERVER_NAMES.has(name)) { + ctx.addIssue({ + code: 'custom', + message: `'${name}' is reserved by a built-in ${PRODUCT_NAME} integration.`, + }); + } + }); export const customMcpServerHeadersSchema = z .record(z.string(), z.string().max(MAX_CUSTOM_MCP_HEADER_VALUE_LENGTH)) diff --git a/packages/types/src/environment-config.ts b/packages/types/src/environment-config.ts index 26008c5ec0..fe2eccaa90 100644 --- a/packages/types/src/environment-config.ts +++ b/packages/types/src/environment-config.ts @@ -7,15 +7,17 @@ import { gitBranchNameSchema } from './git-ref'; import { collectReservedEnvReferences } from './reserved-mcp-env-vars'; import { SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME } from './sandbox-preview-inference'; -const environmentEnvMapSchema = z.record(z.string()).superRefine((env, ctx) => { - if (SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME in env) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - path: [SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME], - message: `${SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME} is a deployment-level preview key and cannot be stored in an environment definition`, - }); - } -}); +const environmentEnvMapSchema = z + .record(z.string(), z.string()) + .superRefine((env, ctx) => { + if (SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME in env) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: [SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME], + message: `${SANDBOX_OPENROUTER_API_KEY_ENV_VAR_NAME} is a deployment-level preview key and cannot be stored in an environment definition`, + }); + } + }); /** * Command @@ -410,7 +412,7 @@ export function slugToPortKey(slug: string): string { */ const environmentMcpServerStreamableHttpInputSchema = z.object({ url: z.string().min(1), - headers: z.record(z.string()).optional(), + headers: z.record(z.string(), z.string()).optional(), command: z.undefined().optional(), args: z.undefined().optional(), env: z.undefined().optional(), @@ -717,7 +719,8 @@ export const environmentConfigSchema = z services: z .array(serviceConfigSchema) .optional() - .transform(filterLegacyServices), + .transform(filterLegacyServices) + .optional(), /** * Customer-owned Docker Compose projects or Dockerfiles to start after * their repositories have been prepared. diff --git a/packages/types/src/environment-recipe.ts b/packages/types/src/environment-recipe.ts index aa50f6124b..8a941833b8 100644 --- a/packages/types/src/environment-recipe.ts +++ b/packages/types/src/environment-recipe.ts @@ -44,7 +44,7 @@ const rBioconductorRecipeSchema = z r_version: z.string().min(1), bioconductor_version: z.string().min(1), packages: z.array(rResolvedPackageSchema).min(1), - renv_lock: z.record(z.unknown()), + renv_lock: z.record(z.string(), z.unknown()), resolution_fingerprint: recipeFingerprintSchema, }) .optional(), diff --git a/packages/types/src/fast-agent-capabilities.ts b/packages/types/src/fast-agent-capabilities.ts index 001e0d7504..5bd6154f39 100644 --- a/packages/types/src/fast-agent-capabilities.ts +++ b/packages/types/src/fast-agent-capabilities.ts @@ -96,7 +96,7 @@ const fastAgentCapabilitySnapshotSchema = z.object({ >, ), initialMilestones: z - .record( + .partialRecord( fastAgentCapabilityIdSchema, z.enum(['offered', 'completed', 'declined', 'deferred']), ) diff --git a/packages/types/src/fast-agent.ts b/packages/types/src/fast-agent.ts index d64fad7358..c91bd7b14b 100644 --- a/packages/types/src/fast-agent.ts +++ b/packages/types/src/fast-agent.ts @@ -177,7 +177,7 @@ export function isFastAgentCommunicationConversation( } export const fastAgentParentSchema = z.object({ - sessionId: z.string().uuid(), + sessionId: z.guid(), conversation: fastAgentConversationSchema, }); diff --git a/packages/types/src/integration-tool-approvals.ts b/packages/types/src/integration-tool-approvals.ts index 3e8b60cba5..91619ff63e 100644 --- a/packages/types/src/integration-tool-approvals.ts +++ b/packages/types/src/integration-tool-approvals.ts @@ -183,7 +183,7 @@ export interface IntegrationToolApprovals { } export const integrationToolApprovalDecisionSchema = z.object({ - approvalId: z.string().uuid(), + approvalId: z.guid(), /** `approved_for_session` approves this call and stops asking for the tool. */ decision: z.enum(['approved', 'approved_for_session', 'rejected']), }); diff --git a/packages/types/src/integration-tool-lookup.ts b/packages/types/src/integration-tool-lookup.ts index 965a6155da..abc5d7b9b9 100644 --- a/packages/types/src/integration-tool-lookup.ts +++ b/packages/types/src/integration-tool-lookup.ts @@ -116,7 +116,7 @@ const integrationToolArgumentValueSchema = z.union([ z.boolean(), z.null(), z.array(z.unknown()), - z.record(z.unknown()), + z.record(z.string(), z.unknown()), ]); /** @@ -187,7 +187,7 @@ export const CALL_INTEGRATION_TOOL_TOOL = { // models take the null branch for a property-less object even when the // integration tool needs arguments. args: z - .record(integrationToolArgumentValueSchema) + .record(z.string(), integrationToolArgumentValueSchema) .describe(CALL_INTEGRATION_TOOL_ARG_DESCRIPTIONS.args), }, annotations: { diff --git a/packages/types/src/manage-custom-automations-tool.ts b/packages/types/src/manage-custom-automations-tool.ts index 83c68aaca0..6a06b96e5d 100644 --- a/packages/types/src/manage-custom-automations-tool.ts +++ b/packages/types/src/manage-custom-automations-tool.ts @@ -66,8 +66,8 @@ export const manageCustomAutomationsFieldSchemas = { enabled: z.boolean().optional(), resultPriority: z .enum(AUTOMATION_RESULT_PRIORITIES) - .describe('Result inbox priority. Defaults to normal when creating.') - .optional(), + .optional() + .describe('Result inbox priority. Defaults to normal when creating.'), schedule: z .string() .optional() @@ -77,42 +77,42 @@ export const manageCustomAutomationsFieldSchemas = { model: z .string() .nullable() + .optional() .describe( 'Optional provider/model launch override. Call list_models first and pass an exact returned model ID. The ID prefix selects the configured inference route; openai/... includes connected ChatGPT subscription routing. Omit to keep the deployment default; pass null on update to clear an existing override.', - ) - .optional(), + ), reasoningEffort: z .enum(REASONING_EFFORT_VALUES) .nullable() + .optional() .describe( 'Optional reasoning effort for the selected model. Omit to keep the model default; pass null on update to clear an existing override.', - ) - .optional(), + ), environmentId: z .string() + .optional() .describe( `Environment UUID, "${ALL_REPOSITORIES}", "${NO_REPOSITORIES}" for a Blank slate sandbox without repositories, or "${FAST_EXECUTION}" for Fast mode without an initial sandbox task.`, - ) - .optional(), + ), targetProvider: z .enum(['slack', 'discord', 'teams', 'telegram', 'email']) .nullable() + .optional() .describe( 'Destination provider. Pass null on update to clear the report destination.', - ) - .optional(), + ), targetMode: z .enum(['channel', 'direct_message']) + .optional() .describe( 'Destination mode. Use direct_message to send reports privately to the automation owner through the selected connected provider. Email only supports direct_message.', - ) - .optional(), + ), targetChannelId: z .string() + .optional() .describe( 'Channel identifier for channel destinations, or the opaque account identity id returned by list_destinations for Email. Never pass a raw email address. Account verification is required for inbound email commands and replies, not for receiving automation reports; replying to a Roomote email from the account address verifies it implicitly.', - ) - .optional(), + ), } satisfies z.ZodRawShape; export const manageCustomAutomationsInputSchema = z.object( diff --git a/packages/types/src/manage-tasks-tool.ts b/packages/types/src/manage-tasks-tool.ts index 0ba9eb9647..bdb843c1c0 100644 --- a/packages/types/src/manage-tasks-tool.ts +++ b/packages/types/src/manage-tasks-tool.ts @@ -130,7 +130,7 @@ export const roomoteManagementFieldSchemas = { ), sessionId: z .string() - .uuid() + .check(z.guid()) .optional() .describe( 'Roomote session UUID from a /sessions/:id URL for get_summary, get_messages, get_updates, or send_message when taskId is omitted; responses return the canonical session ID', diff --git a/packages/types/src/service-credentials.ts b/packages/types/src/service-credentials.ts index 7937d3af51..11a3cc57fb 100644 --- a/packages/types/src/service-credentials.ts +++ b/packages/types/src/service-credentials.ts @@ -68,7 +68,7 @@ export const serviceCredentialPrepareToolSchema = z export const serviceCredentialCreateSchema = z .object({ - pendingRef: z.string().uuid(), + pendingRef: z.guid(), secret: z.string().min(8).max(4096), /** * Required, and required to match the prepared policy exactly, whenever @@ -82,13 +82,13 @@ export const serviceCredentialCreateSchema = z export const serviceCredentialRevokeSchema = z .object({ - secretRef: z.string().uuid(), + secretRef: z.guid(), }) .strict(); export const serviceCredentialVisibilityUpdateSchema = z .object({ - secretRef: z.string().uuid(), + secretRef: z.guid(), visibility: serviceCredentialVisibilitySchema, }) .strict(); @@ -113,7 +113,7 @@ export const SERVICE_CREDENTIAL_REQUEST_BODY_MAX_BYTES = 65_536; export const serviceCredentialRequestSchema = z .object({ - secretRef: z.string().uuid(), + secretRef: z.guid(), /** Any method; the broker enforces the grant's approved methods. */ method: credentialEgressMethodSchema, path: z.string().min(1).max(2048), diff --git a/packages/types/src/source-control.ts b/packages/types/src/source-control.ts index 9b25d994aa..b37beba00b 100644 --- a/packages/types/src/source-control.ts +++ b/packages/types/src/source-control.ts @@ -186,7 +186,7 @@ export function resolveRepositoryProvidersFromPayload(payload: { repositoryProviders?: unknown; }): Record | undefined { const parsed = z - .record(sourceControlProviderSchema) + .record(z.string(), sourceControlProviderSchema) .safeParse(payload.repositoryProviders); return parsed.success && Object.keys(parsed.data).length > 0 diff --git a/packages/types/src/task-launch-api.ts b/packages/types/src/task-launch-api.ts index 1dc91ec14a..1a8d80f1a6 100644 --- a/packages/types/src/task-launch-api.ts +++ b/packages/types/src/task-launch-api.ts @@ -110,12 +110,12 @@ export const taskLaunchRequestSchema = z.object({ .trim() .regex(/^[0-9a-f]{7,40}$/i, 'sha must be a git commit SHA') .optional(), - environmentId: z.string().uuid().optional(), + environmentId: z.guid().optional(), /** * Idempotency key for standard launches. Retrying with the same id returns * the task the first request created instead of starting another one. */ - launchId: z.string().uuid().optional(), + launchId: z.guid().optional(), type: launchTaskTypeSchema.optional(), repositoryFullNames: z.array(z.string().trim().min(1)).min(1).optional(), selectedRepositories: z.array(z.string().trim().min(1)).min(1).optional(), @@ -140,7 +140,7 @@ export const taskLaunchRequestSchema = z.object({ * Fast conversation whose Session should own the launched task. `pr-review` * launches attach the review to this Session and announce its outcome there. */ - fastConversationId: z.string().uuid().optional(), + fastConversationId: z.guid().optional(), }); export type TaskLaunchRequest = z.infer; diff --git a/packages/types/src/task-runs.ts b/packages/types/src/task-runs.ts index 16da42862f..390e0c49b2 100644 --- a/packages/types/src/task-runs.ts +++ b/packages/types/src/task-runs.ts @@ -1013,7 +1013,9 @@ const sharedTaskPayloadSchema = z.object({ * span multiple providers. Aggregate selections also include this map when * homogeneous so downstream attribution can verify complete coverage. */ - repositoryProviders: z.record(sourceControlProviderSchema).optional(), + repositoryProviders: z + .record(z.string(), sourceControlProviderSchema) + .optional(), /** * Source-control instance host for repository resolution (for example @@ -1076,13 +1078,13 @@ const sharedTaskPayloadSchema = z.object({ * When specified, additional repositories defined in the environment * will be cloned alongside the primary repository. */ - environmentId: z.string().uuid().optional(), + environmentId: z.guid().optional(), /** * Optional environment definition ID for setup/update tasks that should be * associated with an environment record without changing workspace selection. */ - environmentDefinitionId: z.string().uuid().optional(), + environmentDefinitionId: z.guid().optional(), /** Marks a repository-free environment-definition task that needs nested Docker. */ preparesEnvironment: z.boolean().optional(), @@ -1094,7 +1096,7 @@ const sharedTaskPayloadSchema = z.object({ * this marker may record a verification result for that environment through * the `record_verification` MCP action. */ - verifiesEnvironmentId: z.string().uuid().optional(), + verifiesEnvironmentId: z.guid().optional(), /** * Optional validated repository subset to prepare when `repo` is the @@ -1168,7 +1170,7 @@ const sharedTaskPayloadSchema = z.object({ * the task. */ liveTaskStream: z.boolean().optional(), /** Runless Fast conversation that delegated this task on any chat provider. */ - fastAgentSessionId: z.string().uuid().optional(), + fastAgentSessionId: z.guid().optional(), /** A Session explicitly requested this review, so its result reaches that * Session through the pull-request feedback relay even though review runs * otherwise stay quiet there. Settle still announces only failures. */ @@ -1545,7 +1547,7 @@ const suggestedTasksPayloadSchema = delegatedTaskPayloadSchema.extend({ .min(1) .max(4000) .optional(), - selectedRepositoryIds: z.array(z.string().uuid()).min(1).optional(), + selectedRepositoryIds: z.array(z.guid()).min(1).optional(), }); export const suggestedTasksTaskSchema = sharedTaskSchema.extend({ @@ -1605,18 +1607,18 @@ export const snapshotEnvironmentAttachmentSchema = z.preprocess( z.discriminatedUnion('source', [ z.object({ source: z.literal('active_snapshot_row'), - environmentSnapshotId: z.string().uuid(), + environmentSnapshotId: z.guid(), sourceSnapshotId: z.string().nullable(), sourceSnapshotCreatedAt: z.string().datetime().nullable(), }), z.object({ source: z.literal('pending_snapshot_row'), - environmentSnapshotId: z.string().uuid(), + environmentSnapshotId: z.guid(), claimedAt: z.string().datetime(), }), z.object({ source: z.literal('legacy_active_snapshot_row'), - environmentSnapshotId: z.string().uuid(), + environmentSnapshotId: z.guid(), }), z.object({ source: z.literal('legacy_sandbox_row'), @@ -1645,7 +1647,7 @@ export const snapshotEnvironmentSchema = sharedTaskSchema.extend({ * The environment config defines which repositories, services, * and setup commands to include in the snapshot. */ - environmentId: z.string().uuid(), + environmentId: z.guid(), environmentSnapshotAttachment: snapshotEnvironmentAttachmentSchema.optional(), }), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b910373358..de24891047 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,9 +38,7 @@ overrides: socket.io>socket.io-adapter: 2.5.8 socket.io-adapter>ws: 8.21.0 tar: 7.5.21 - zod: ^3.25.76 - astro>zod: ^4.3.6 - knip>zod: ^4.1.11 + zod: 4.6.6 '@streamdown/mermaid>mermaid': 11.16.1 nanoid@<4: 5.1.16 dagre-d3-es>lodash-es: 4.18.1 @@ -48,7 +46,8 @@ overrides: jayson>uuid: 11.1.1 preact: '>=10.26.10' smol-toml: 1.9.0 - undici: ^7.29.1 + undici: 7.30.1 + '@azure/msal-node': 7.1.0 diff: '>=5.2.2' flatted: ^3.4.2 '@protobufjs/utf8': 1.1.1 @@ -64,7 +63,7 @@ overrides: brace-expansion@<1.1.21: 1.1.21 brace-expansion@>=2.0.0 <2.1.7: 2.1.7 brace-expansion@>=3.0.0 <5.0.12: 5.0.12 - fast-uri: 3.1.8 + fast-uri: 3.1.9 ip-address: 10.7.4 immutable: 5.1.8 moment: 2.31.0 @@ -165,7 +164,7 @@ importers: version: 0.4.2(@trpc/server@11.15.0(typescript@5.9.3))(hono@4.13.11) '@modelcontextprotocol/sdk': specifier: 1.32.0 - version: 1.32.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.32.0(@cfworker/json-schema@4.1.1)(zod@4.6.6) '@octokit/openapi-webhooks-types': specifier: ^12.1.0 version: 12.1.0 @@ -254,15 +253,15 @@ importers: specifier: ^1.99.1 version: 1.99.1 undici: - specifier: ^7.29.1 - version: 7.29.1 + specifier: 7.30.1 + version: 7.30.1 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@ai-sdk/azure': specifier: 3.0.93 - version: 3.0.93(zod@3.25.76) + version: 3.0.93(zod@4.6.6) '@roomote/config-typescript': specifier: workspace:^ version: link:../../packages/config-typescript @@ -274,7 +273,7 @@ importers: version: 8.5.1(jiti@2.7.0)(postcss@8.5.23)(tsx@4.20.4)(typescript@5.9.3)(yaml@2.9.0) vitest: specifier: 4.1.12 - version: 4.1.12(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(jsdom@26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(vite@7.3.7(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.20.4)(yaml@2.9.0)) + version: 4.1.12(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@24.12.4)(jsdom@26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(vite@7.3.7(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.20.4)(yaml@2.9.0)) apps/bullmq: dependencies: @@ -345,8 +344,8 @@ importers: specifier: 26.1.0 version: 26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -359,7 +358,7 @@ importers: version: 8.5.1(jiti@2.7.0)(postcss@8.5.23)(tsx@4.20.4)(typescript@5.9.3)(yaml@2.9.0) vitest: specifier: 4.1.12 - version: 4.1.12(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.0)(@types/node@24.12.4)(jsdom@26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(vite@7.3.7(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.20.4)(yaml@2.9.0)) + version: 4.1.12(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(jsdom@26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(vite@7.3.7(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.20.4)(yaml@2.9.0)) apps/controller: dependencies: @@ -520,8 +519,8 @@ importers: specifier: ^13.1.3 version: 13.1.3 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -555,7 +554,7 @@ importers: version: 3.1000.0 '@better-auth/drizzle-adapter': specifier: ^1.6.22 - version: 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8)) + version: 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8)) '@codemirror/lang-yaml': specifier: ^6.0.0 version: 6.1.3 @@ -741,7 +740,7 @@ importers: version: 4.1.2 ai: specifier: ^6.0.116 - version: 6.0.116(zod@3.25.76) + version: 6.0.116(zod@4.6.6) ansi-to-react: specifier: ^6.2.6 version: 6.2.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -869,8 +868,8 @@ importers: specifier: ^2.9.0 version: 2.9.0 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 zustand: specifier: ^5.0.10 version: 5.0.10(@types/react@19.2.10)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.5.0(react@19.2.4)) @@ -958,7 +957,7 @@ importers: version: 2.0.10(hono@4.13.11) '@modelcontextprotocol/sdk': specifier: 1.32.0 - version: 1.32.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.32.0(@cfworker/json-schema@4.1.1)(zod@4.6.6) '@roo-code/judgement': specifier: 0.4.1 version: 0.4.1 @@ -1038,8 +1037,8 @@ importers: specifier: ^2.9.0 version: 2.9.0 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-eslint': specifier: workspace:^ @@ -1078,8 +1077,8 @@ importers: specifier: workspace:^ version: link:../types zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1109,8 +1108,8 @@ importers: specifier: ^9.0.3 version: 9.0.3 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1137,8 +1136,8 @@ importers: specifier: workspace:^ version: link:../types zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1154,13 +1153,13 @@ importers: dependencies: '@ai-sdk/mcp': specifier: ^1.0.25 - version: 1.0.25(zod@3.25.76) + version: 1.0.25(zod@4.6.6) '@aws-sdk/client-s3': specifier: 3.1000.0 version: 3.1000.0 '@modelcontextprotocol/sdk': specifier: 1.32.0 - version: 1.32.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + version: 1.32.0(@cfworker/json-schema@4.1.1)(zod@4.6.6) '@opencode-ai/sdk': specifier: 1.18.30 version: 1.18.30 @@ -1208,7 +1207,7 @@ importers: version: link:../types ai: specifier: ^6.0.116 - version: 6.0.116(zod@3.25.76) + version: 6.0.116(zod@4.6.6) bullmq: specifier: ^5.78.0 version: 5.78.0 @@ -1234,11 +1233,8 @@ importers: specifier: https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz version: https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz zod: - specifier: ^3.25.76 - version: 3.25.76 - zod-to-json-schema: - specifier: 3.25.1 - version: 3.25.1(zod@3.25.76) + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1277,8 +1273,8 @@ importers: specifier: workspace:^ version: link:../types zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1423,8 +1419,8 @@ importers: specifier: 4.1.12 version: 4.1.12(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(jsdom@26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(vite@7.3.7(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.20.4)(yaml@2.9.0)) zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 packages/env: dependencies: @@ -1433,10 +1429,10 @@ importers: version: link:../types '@t3-oss/env-nextjs': specifier: ^0.13.10 - version: 0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@4.6.6) zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1472,8 +1468,8 @@ importers: specifier: workspace:^ version: link:../types zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1512,8 +1508,8 @@ importers: specifier: ^7.0.4 version: 7.0.4 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1540,8 +1536,8 @@ importers: specifier: workspace:^ version: link:../types zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1574,8 +1570,8 @@ importers: specifier: workspace:^ version: link:../types zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1687,8 +1683,8 @@ importers: specifier: 7.2.0 version: 7.2.0 undici: - specifier: ^7.29.1 - version: 7.29.1 + specifier: 7.30.1 + version: 7.30.1 unzipper: specifier: ^0.12.5 version: 0.12.5 @@ -1696,8 +1692,8 @@ importers: specifier: ^2.9.0 version: 2.9.0 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1745,8 +1741,8 @@ importers: specifier: ^7.19.0 version: 7.19.0 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1798,8 +1794,8 @@ importers: specifier: ^2.9.0 version: 2.9.0 zod: - specifier: ^3.25.76 - version: 3.25.76 + specifier: 4.6.6 + version: 4.6.6 devDependencies: '@roomote/config-typescript': specifier: workspace:^ @@ -1820,37 +1816,37 @@ packages: resolution: {integrity: sha512-9nKNmRtopjE3+L+286/4sLBDfDvmdsL7fiQXG0TE38NywxkDDLUhdr0KSllkRQ+m1/8bO7x4rIVhHSjQQiqmnQ==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 '@ai-sdk/deepseek@2.0.50': resolution: {integrity: sha512-pnl22aGBIdpK0sXSJN4zDykIXTdyO9m3gFhno3SBPpdwT4Tq041Uy0i/EDWSxIiFa9JEokFGiCt4NNzcE5ntRA==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 '@ai-sdk/gateway@3.0.66': resolution: {integrity: sha512-SIQ0YY0iMuv+07HLsZ+bB990zUJ6S4ujORAh+Jv1V2KGNn73qQKnGO0JBk+w+Res8YqOFSycwDoWcFlQrVxS4A==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 '@ai-sdk/mcp@1.0.25': resolution: {integrity: sha512-vMlXUPGHGDE2vzLcPR8sw7Dhz2OBjtPU5lB+lIuC1hNQo4REuUC08P0e96/hzBKf4oQYJ8Zo6uP8AG2qThyFbg==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 '@ai-sdk/openai@3.0.88': resolution: {integrity: sha512-6M4+bxK/UMijDYK2ia1hCKYma1iajFYxHDlhbinFUdhH2WbFsjoZRMpSjEMlTOBptqmh2J1JclKnprGulF8WwQ==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 '@ai-sdk/provider-utils@4.0.33': resolution: {integrity: sha512-nJ0bAfegMAIJtrzMJtbzer1cS3nb7c7DsyU1S4nrPm7ZU0Mn6SBBZv5IGZZGTbpWTJwqKTSPeZJTXalbAxt1BA==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 '@ai-sdk/provider@3.0.12': resolution: {integrity: sha512-sj9DWTJ2Ze0WR9qsiOPqoqzNx3OxL6iMxHImbhvoe9qOspekbzxNDMiJ4TIGfYHYh9w4OmBjz3prvqhzTi96+Q==} @@ -2119,12 +2115,16 @@ packages: resolution: {integrity: sha512-eNf2aqx1C6I0yT1GEu5ukblFrmaBXGfe1bivpmlfqvK7giPZvoXLa404C8EfeHVsy6EIryfQuPRzuW1fPxWlHg==} engines: {node: '>=0.8.0'} + '@azure/msal-common@16.14.2': + resolution: {integrity: sha512-HOBR0Gfo39TMrkxNG8k6cfjRkrRjXZc3JQs3ebMWQc9S4cihuknMYra3sgmzbZB752oQBqBN9+WF7c826p2vIQ==} + engines: {node: '>=0.8.0'} + '@azure/msal-common@16.7.0': resolution: {integrity: sha512-Jb8Y7pX6KM42SIT7KWP6YbY3+vLbwB5b5m+tpiiOzMU1QeyelQzs9lO8jv1e7/Uj9r7tg7VjPvW4T0KB1jF3UQ==} engines: {node: '>=0.8.0'} - '@azure/msal-node@5.2.3': - resolution: {integrity: sha512-YYX4TchEVddVBiybKvKhV9QO/q22jgewP+BVxKG7Uh115voPcviGlypbKERDsqQdAiSTJrwi80gcWFjYKdo8+Q==} + '@azure/msal-node@7.1.0': + resolution: {integrity: sha512-s1O6hSY/C/dmqykTmmeHY6GhSkDuY8N1gxyhuLyaCwbY7N+UBvU2Wu4flas7+NxZiAPcXNPVpgt3n/HP/5yL+w==} engines: {node: '>=20'} '@azure/storage-blob@12.26.0': @@ -3208,7 +3208,7 @@ packages: engines: {node: '>=18'} peerDependencies: '@cfworker/json-schema': ^4.1.1 - zod: ^3.25.76 + zod: 4.6.6 peerDependenciesMeta: '@cfworker/json-schema': optional: true @@ -6046,7 +6046,7 @@ packages: arktype: ^2.1.0 typescript: '>=5.0.0' valibot: ^1.0.0-beta.7 || ^1.0.0 - zod: ^3.25.76 + zod: 4.6.6 peerDependenciesMeta: arktype: optional: true @@ -6063,7 +6063,7 @@ packages: arktype: ^2.1.0 typescript: '>=5.0.0' valibot: ^1.0.0-beta.7 || ^1.0.0 - zod: ^3.25.76 + zod: 4.6.6 peerDependenciesMeta: arktype: optional: true @@ -6882,7 +6882,7 @@ packages: resolution: {integrity: sha512-7yM+cTmyRLeNIXwt4Vj+mrrJgVQ9RMIW5WO0ydoLoYkewIvsMcvUmqS4j2RJTUXaF1HphwmSKUMQ/HypNRGOmA==} engines: {node: '>=18'} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} @@ -7209,7 +7209,7 @@ packages: better-call@1.3.7: resolution: {integrity: sha512-Al51/hjp2SSp6CRTa3F2ptcx4yQVS1xWKoY6jcVXqNYOap6mHFP2jUBn5EwIL4iIed1/Sq4hlQ+Umm6EflZG+w==} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 peerDependenciesMeta: zod: optional: true @@ -8497,8 +8497,8 @@ packages: fast-sha256@1.3.0: resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} - fast-uri@3.1.8: - resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + fast-uri@3.1.9: + resolution: {integrity: sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==} fast-xml-builder@1.2.0: resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} @@ -11861,8 +11861,8 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - undici@7.29.1: - resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==} + undici@7.30.1: + resolution: {integrity: sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==} engines: {node: '>=20.18.1'} unicorn-magic@0.2.0: @@ -12344,16 +12344,10 @@ packages: zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: - zod: ^3.25.76 + zod: 4.6.6 - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zod@4.6.6: + resolution: {integrity: sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==} zustand@5.0.10: resolution: {integrity: sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg==} @@ -12380,46 +12374,46 @@ snapshots: '@adobe/css-tools@4.4.3': {} - '@ai-sdk/azure@3.0.93(zod@3.25.76)': + '@ai-sdk/azure@3.0.93(zod@4.6.6)': dependencies: - '@ai-sdk/deepseek': 2.0.50(zod@3.25.76) - '@ai-sdk/openai': 3.0.88(zod@3.25.76) + '@ai-sdk/deepseek': 2.0.50(zod@4.6.6) + '@ai-sdk/openai': 3.0.88(zod@4.6.6) '@ai-sdk/provider': 3.0.14 - '@ai-sdk/provider-utils': 4.0.33(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider-utils': 4.0.33(zod@4.6.6) + zod: 4.6.6 - '@ai-sdk/deepseek@2.0.50(zod@3.25.76)': + '@ai-sdk/deepseek@2.0.50(zod@4.6.6)': dependencies: '@ai-sdk/provider': 3.0.14 - '@ai-sdk/provider-utils': 4.0.33(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider-utils': 4.0.33(zod@4.6.6) + zod: 4.6.6 - '@ai-sdk/gateway@3.0.66(zod@3.25.76)': + '@ai-sdk/gateway@3.0.66(zod@4.6.6)': dependencies: '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.33(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.33(zod@4.6.6) '@vercel/oidc': 3.1.0 - zod: 3.25.76 + zod: 4.6.6 - '@ai-sdk/mcp@1.0.25(zod@3.25.76)': + '@ai-sdk/mcp@1.0.25(zod@4.6.6)': dependencies: '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.33(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.33(zod@4.6.6) pkce-challenge: 5.0.1 - zod: 3.25.76 + zod: 4.6.6 - '@ai-sdk/openai@3.0.88(zod@3.25.76)': + '@ai-sdk/openai@3.0.88(zod@4.6.6)': dependencies: '@ai-sdk/provider': 3.0.14 - '@ai-sdk/provider-utils': 4.0.33(zod@3.25.76) - zod: 3.25.76 + '@ai-sdk/provider-utils': 4.0.33(zod@4.6.6) + zod: 4.6.6 - '@ai-sdk/provider-utils@4.0.33(zod@3.25.76)': + '@ai-sdk/provider-utils@4.0.33(zod@4.6.6)': dependencies: '@ai-sdk/provider': 3.0.12 '@standard-schema/spec': 1.1.0 eventsource-parser: 3.1.1 - zod: 3.25.76 + zod: 4.6.6 '@ai-sdk/provider@3.0.12': dependencies: @@ -12943,7 +12937,7 @@ snapshots: '@azure/core-util': 1.13.1 '@azure/logger': 1.3.0 '@azure/msal-browser': 5.12.0 - '@azure/msal-node': 5.2.3 + '@azure/msal-node': 7.1.0 open: 10.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -12960,11 +12954,13 @@ snapshots: dependencies: '@azure/msal-common': 16.7.0 + '@azure/msal-common@16.14.2': {} + '@azure/msal-common@16.7.0': {} - '@azure/msal-node@5.2.3': + '@azure/msal-node@7.1.0': dependencies: - '@azure/msal-common': 16.7.0 + '@azure/msal-common': 16.14.2 jsonwebtoken: 9.0.3 '@azure/storage-blob@12.26.0': @@ -13101,52 +13097,52 @@ snapshots: '@balena/dockerignore@1.0.2': {} - '@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1)': + '@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1)': dependencies: '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 '@opentelemetry/semantic-conventions': 1.43.0 '@standard-schema/spec': 1.1.0 - better-call: 1.3.7(zod@4.4.3) + better-call: 1.3.7(zod@4.6.6) jose: 6.2.4 kysely: 0.29.4 nanostores: 1.4.1 - zod: 4.4.3 + zod: 4.6.6 optionalDependencies: '@opentelemetry/api': 1.9.1 - '@better-auth/drizzle-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8))': + '@better-auth/drizzle-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8))': dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) '@better-auth/utils': 0.4.2 optionalDependencies: drizzle-orm: 0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8) - '@better-auth/kysely-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(kysely@0.29.4)': + '@better-auth/kysely-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(kysely@0.29.4)': dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) '@better-auth/utils': 0.4.2 optionalDependencies: kysely: 0.29.4 - '@better-auth/memory-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)': + '@better-auth/memory-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)': dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) '@better-auth/utils': 0.4.2 - '@better-auth/mongo-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)': + '@better-auth/mongo-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)': dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) '@better-auth/utils': 0.4.2 - '@better-auth/prisma-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)': + '@better-auth/prisma-adapter@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)': dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) '@better-auth/utils': 0.4.2 - '@better-auth/telemetry@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)': + '@better-auth/telemetry@1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)': dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 @@ -13159,7 +13155,7 @@ snapshots: '@blaxel/core@0.3.0(@cfworker/json-schema@4.1.1)(@hey-api/openapi-ts@0.99.0(typescript@5.9.3))(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@hey-api/client-fetch': 0.10.2(@hey-api/openapi-ts@0.99.0(typescript@5.9.3)) - '@modelcontextprotocol/sdk': 1.32.0(@cfworker/json-schema@4.1.1)(zod@3.25.76) + '@modelcontextprotocol/sdk': 1.32.0(@cfworker/json-schema@4.1.1)(zod@4.6.6) archiver: 7.0.1 axios: 1.20.0 dockerfile-ast: 0.7.1 @@ -13170,7 +13166,7 @@ snapshots: uuid: 11.1.1 ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) yaml: 2.9.0 - zod: 3.25.76 + zod: 4.6.6 transitivePeerDependencies: - '@cfworker/json-schema' - '@hey-api/openapi-ts' @@ -13541,7 +13537,7 @@ snapshots: discord-api-types: 0.38.49 magic-bytes.js: 1.13.0 tslib: 2.8.1 - undici: 7.29.1 + undici: 7.30.1 '@discordjs/util@1.2.0': dependencies: @@ -14224,7 +14220,7 @@ snapshots: '@mixmark-io/domino@2.2.0': {} - '@modelcontextprotocol/sdk@1.32.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)': + '@modelcontextprotocol/sdk@1.32.0(@cfworker/json-schema@4.1.1)(zod@4.6.6)': dependencies: '@hono/node-server': 2.0.10(hono@4.13.11) ajv: 8.20.0 @@ -14241,8 +14237,8 @@ snapshots: json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 raw-body: 3.0.2 - zod: 3.25.76 - zod-to-json-schema: 3.25.1(zod@3.25.76) + zod: 4.6.6 + zod-to-json-schema: 3.25.1(zod@4.6.6) optionalDependencies: '@cfworker/json-schema': 4.1.1 transitivePeerDependencies: @@ -16923,19 +16919,19 @@ snapshots: dependencies: tslib: 2.8.1 - '@t3-oss/env-core@0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@3.25.76)': + '@t3-oss/env-core@0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@4.6.6)': optionalDependencies: arktype: 2.1.27 typescript: 5.9.3 - zod: 3.25.76 + zod: 4.6.6 - '@t3-oss/env-nextjs@0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@3.25.76)': + '@t3-oss/env-nextjs@0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@4.6.6)': dependencies: - '@t3-oss/env-core': 0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@3.25.76) + '@t3-oss/env-core': 0.13.10(arktype@2.1.27)(typescript@5.9.3)(zod@4.6.6) optionalDependencies: arktype: 2.1.27 typescript: 5.9.3 - zod: 3.25.76 + zod: 4.6.6 '@tailwindcss/node@4.3.1': dependencies: @@ -17850,13 +17846,13 @@ snapshots: agent-base@7.1.4: {} - ai@6.0.116(zod@3.25.76): + ai@6.0.116(zod@4.6.6): dependencies: - '@ai-sdk/gateway': 3.0.66(zod@3.25.76) + '@ai-sdk/gateway': 3.0.66(zod@4.6.6) '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.33(zod@3.25.76) + '@ai-sdk/provider-utils': 4.0.33(zod@4.6.6) '@opentelemetry/api': 1.9.0 - zod: 3.25.76 + zod: 4.6.6 ajv-formats@2.1.1(ajv@8.20.0): optionalDependencies: @@ -17881,7 +17877,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.8 + fast-uri: 3.1.9 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -18139,23 +18135,23 @@ snapshots: better-auth@1.6.22(@opentelemetry/api@1.9.1)(better-sqlite3@11.10.0)(drizzle-kit@0.31.9)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8))(next@16.4.1(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pg@8.15.6)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.1.12(@edge-runtime/vm@3.2.0)(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(jsdom@26.1.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(vite@7.3.7(@types/node@24.12.4)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(tsx@4.20.4)(yaml@2.9.0))): dependencies: - '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) - '@better-auth/drizzle-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8)) - '@better-auth/kysely-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(kysely@0.29.4) - '@better-auth/memory-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2) - '@better-auth/mongo-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2) - '@better-auth/prisma-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2) - '@better-auth/telemetry': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@3.25.76))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1) + '@better-auth/core': 1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1) + '@better-auth/drizzle-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.0)(@libsql/client-wasm@0.15.5)(@opentelemetry/api@1.9.1)(@types/pg@8.16.0)(better-sqlite3@11.10.0)(kysely@0.29.4)(pg@8.15.6)(postgres@3.4.8)) + '@better-auth/kysely-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(kysely@0.29.4) + '@better-auth/memory-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2) + '@better-auth/mongo-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2) + '@better-auth/prisma-adapter': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2) + '@better-auth/telemetry': 1.6.22(@better-auth/core@1.6.22(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.3.7(zod@4.6.6))(jose@6.2.4)(kysely@0.29.4)(nanostores@1.4.1))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1) '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 '@noble/ciphers': 2.2.0 '@noble/hashes': 2.2.0 - better-call: 1.3.7(zod@4.4.3) + better-call: 1.3.7(zod@4.6.6) defu: 6.1.7 jose: 6.2.4 kysely: 0.29.4 nanostores: 1.4.1 - zod: 4.4.3 + zod: 4.6.6 optionalDependencies: better-sqlite3: 11.10.0 drizzle-kit: 0.31.9 @@ -18169,14 +18165,14 @@ snapshots: - '@cloudflare/workers-types' - '@opentelemetry/api' - better-call@1.3.7(zod@4.4.3): + better-call@1.3.7(zod@4.6.6): dependencies: '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 rou3: 0.7.12 set-cookie-parser: 3.1.2 optionalDependencies: - zod: 4.4.3 + zod: 4.6.6 better-path-resolve@1.0.0: dependencies: @@ -18928,7 +18924,7 @@ snapshots: lodash.snakecase: 4.1.1 magic-bytes.js: 1.13.0 tslib: 2.8.1 - undici: 7.29.1 + undici: 7.30.1 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -19046,7 +19042,7 @@ snapshots: openapi-fetch: 0.14.1 platform: 1.3.6 tar: 7.5.21 - undici: 7.29.1 + undici: 7.30.1 ecdsa-sig-formatter@1.0.11: dependencies: @@ -19575,7 +19571,7 @@ snapshots: fast-sha256@1.3.0: {} - fast-uri@3.1.8: {} + fast-uri@3.1.9: {} fast-xml-builder@1.2.0: dependencies: @@ -20609,7 +20605,7 @@ snapshots: smol-toml: 1.9.0 strip-json-comments: 5.0.3 typescript: 5.9.3 - zod: 4.3.6 + zod: 4.6.6 kolorist@1.8.0: {} @@ -23713,7 +23709,7 @@ snapshots: undici-types@7.18.2: {} - undici@7.29.1: {} + undici@7.30.1: {} unicorn-magic@0.2.0: {} @@ -24288,15 +24284,11 @@ snapshots: compress-commons: 6.0.2 readable-stream: 4.7.0 - zod-to-json-schema@3.25.1(zod@3.25.76): + zod-to-json-schema@3.25.1(zod@4.6.6): dependencies: - zod: 3.25.76 - - zod@3.25.76: {} - - zod@4.3.6: {} + zod: 4.6.6 - zod@4.4.3: {} + zod@4.6.6: {} zustand@5.0.10(@types/react@19.2.10)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.5.0(react@19.2.4)): optionalDependencies: