Migrate workspace schemas to zod 4

This commit is contained in:
Mohamed Boudra
2026-06-08 13:59:44 +07:00
parent 99876d37f3
commit ed8a6fefad
60 changed files with 378 additions and 342 deletions
+1 -2
View File
@@ -91,8 +91,7 @@
"which": "^5.0.0",
"ws": "^8.14.2",
"zod": "^4.1.8",
"zod-to-json-schema": "^3.25.1",
"zod3": "npm:zod@^3.25.76"
"zod-to-json-schema": "^3.25.1"
},
"devDependencies": {
"@playwright/test": "^1.56.1",
@@ -1,6 +1,6 @@
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { z } from "zod3";
import { z } from "zod";
async function main() {
const transport = new StdioClientTransport({
@@ -7,7 +7,7 @@ import {
} from "@getpaseo/protocol/agent-lifecycle";
import { isDelegatedAgent, PARENT_AGENT_ID_LABEL } from "@getpaseo/protocol/agent-labels";
import type { Logger } from "pino";
import { z } from "zod3";
import { z } from "zod";
import type { TerminalManager } from "../../terminal/terminal-manager.js";
import {
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { Logger } from "pino";
import type { AgentManager } from "./agent-manager.js";
@@ -4,7 +4,7 @@ import { mkdtempSync, rmSync } from "fs";
import { tmpdir } from "os";
import path from "path";
import { randomUUID } from "crypto";
import { z } from "zod3";
import { z } from "zod";
import express from "express";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
@@ -1,5 +1,5 @@
import { describe, it, expect } from "vitest";
import { z } from "zod3";
import { z } from "zod";
import {
getStructuredAgentResponse,
generateStructuredAgentResponseWithFallback,
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
import Ajv, { type ErrorObject, type Options as AjvOptions } from "ajv";
import type { AgentProvider, AgentSessionConfig } from "./agent-sdk-types.js";
@@ -1,6 +1,6 @@
import { promises as fs } from "node:fs";
import path from "node:path";
import { z } from "zod3";
import { z } from "zod";
import type { Logger } from "pino";
import { writeJsonFileAtomic } from "../atomic-file.js";
@@ -14,10 +14,10 @@ const SERIALIZABLE_CONFIG_SCHEMA = z
modeId: z.string().nullable().optional(),
model: z.string().nullable().optional(),
thinkingOptionId: z.string().nullable().optional(),
featureValues: z.record(z.unknown()).nullable().optional(),
extra: z.record(z.any()).nullable().optional(),
featureValues: z.record(z.string(), z.unknown()).nullable().optional(),
extra: z.record(z.string(), z.any()).nullable().optional(),
systemPrompt: z.string().nullable().optional(),
mcpServers: z.record(z.any()).nullable().optional(),
mcpServers: z.record(z.string(), z.any()).nullable().optional(),
})
.nullable()
.optional();
@@ -27,7 +27,7 @@ const PERSISTENCE_HANDLE_SCHEMA = z
provider: z.string(),
sessionId: z.string(),
nativeHandle: z.any().optional(),
metadata: z.record(z.any()).optional(),
metadata: z.record(z.string(), z.any()).optional(),
})
.nullable()
.optional();
@@ -41,7 +41,7 @@ const STORED_AGENT_SCHEMA = z.object({
lastActivityAt: z.string().optional(),
lastUserMessageAt: z.string().nullable().optional(),
title: z.string().nullable().optional(),
labels: z.record(z.string()).default({}),
labels: z.record(z.string(), z.string()).default({}),
lastStatus: AgentStatusSchema.default("closed"),
lastModeId: z.string().nullable().optional(),
config: SERIALIZABLE_CONFIG_SCHEMA,
@@ -52,7 +52,7 @@ const STORED_AGENT_SCHEMA = z.object({
model: z.string().nullable().optional(),
thinkingOptionId: z.string().nullable().optional(),
modeId: z.string().nullable().optional(),
extra: z.record(z.unknown()).optional(),
extra: z.record(z.string(), z.unknown()).optional(),
})
.optional(),
features: z.array(AgentFeatureSchema).optional(),
@@ -1,4 +1,4 @@
import type { z } from "zod3";
import type { z } from "zod";
import type { Logger } from "pino";
import type { ProviderSnapshotManager } from "./provider-snapshot-manager.js";
import type { AgentManager, ManagedAgent } from "./agent-manager.js";
@@ -5,7 +5,7 @@ import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import { experimental_createMCPClient } from "ai";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { z } from "zod3";
import { z } from "zod";
import { AGENT_WAIT_TIMEOUT_MS } from "./mcp-shared.js";
import { createTestPaseoDaemon, type TestPaseoDaemon } from "../test-utils/paseo-daemon.js";
@@ -31,7 +31,7 @@ function str(val: unknown): string {
}
function recordArr(val: unknown): StructuredContent[] {
return z.array(z.record(z.unknown())).parse(val);
return z.array(z.record(z.string(), z.unknown())).parse(val);
}
function expectAgentFeatureValue(snapshot: StructuredContent, featureId: string, value: unknown) {
@@ -355,7 +355,7 @@ describe("Suite A: Core Fixes", () => {
expect(internalSnapshot?.config.featureValues).toEqual({ test_feature: true });
const status = await callToolStructured(topLevelClient, "get_agent_status", { agentId });
const snapshot = z.record(z.unknown()).parse(status.snapshot);
const snapshot = z.record(z.string(), z.unknown()).parse(status.snapshot);
expectAgentFeatureValue(snapshot, "test_feature", true);
} finally {
await archiveAgentIfPresent(agentId);
@@ -373,7 +373,7 @@ describe("Suite A: Core Fixes", () => {
expect(internalSnapshot?.config.featureValues).toEqual({ test_feature: true });
const status = await callToolStructured(topLevelClient, "get_agent_status", { agentId });
const snapshot = z.record(z.unknown()).parse(status.snapshot);
const snapshot = z.record(z.string(), z.unknown()).parse(status.snapshot);
expectAgentFeatureValue(snapshot, "test_feature", true);
} finally {
await archiveAgentIfPresent(agentId);
@@ -393,7 +393,7 @@ describe("Suite A: Core Fixes", () => {
expect(internalSnapshot?.config.featureValues).toEqual({ test_feature: true });
const status = await callToolStructured(topLevelClient, "get_agent_status", { agentId });
const snapshot = z.record(z.unknown()).parse(status.snapshot);
const snapshot = z.record(z.string(), z.unknown()).parse(status.snapshot);
expectAgentFeatureValue(snapshot, "test_feature", true);
} finally {
await archiveAgentIfPresent(agentId);
@@ -5,7 +5,7 @@ import { access, mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
import { join, resolve as resolvePath } from "node:path";
import { tmpdir } from "node:os";
import Ajv from "ajv";
import { z } from "zod3";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
import { createTestLogger } from "../../test-utils/test-logger.js";
@@ -121,7 +121,7 @@ function expectOutputSchemaAccepts(tool: RegisteredMcpTool, data: unknown): void
function agentsOf(response: {
structuredContent: LooseStructuredContent;
}): Array<Record<string, unknown>> {
return z.array(z.record(z.unknown())).parse(response.structuredContent.agents);
return z.array(z.record(z.string(), z.unknown())).parse(response.structuredContent.agents);
}
type AgentManagerSpies = ReturnType<typeof buildAgentManagerSpies>;
@@ -3205,7 +3205,7 @@ describe("agent snapshot MCP serialization", () => {
const tool = registeredTool(server, "list_agents");
const response = await tool.handler({});
const structured = z
.object({ agents: z.array(z.record(z.unknown())) })
.object({ agents: z.array(z.record(z.string(), z.unknown())) })
.parse(response.structuredContent);
expect(structured).toEqual({
@@ -3317,7 +3317,7 @@ describe("agent snapshot MCP serialization", () => {
});
const tool = registeredTool(server, "get_agent_status");
const response = await tool.handler({ agentId: "full-detail-agent" });
const snapshot = z.record(z.unknown()).parse(response.structuredContent.snapshot);
const snapshot = z.record(z.string(), z.unknown()).parse(response.structuredContent.snapshot);
const parsed = AgentSnapshotPayloadSchema.safeParse(snapshot);
if (!parsed.success) {
@@ -1,5 +1,5 @@
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod3";
import { z } from "zod";
import { ensureValidJson } from "../json-utils.js";
import type { Logger } from "pino";
import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
@@ -690,7 +690,7 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom
modeId: z.string().optional().describe("Session mode to configure before the first run."),
thinkingOptionId: z.string().optional().describe("Thinking option ID."),
features: z
.record(z.unknown())
.record(z.string(), z.unknown())
.optional()
.describe("Provider-specific feature values, for example { fast_mode: true } for Codex."),
})
@@ -705,7 +705,7 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom
.optional()
.describe("Thinking option ID. Pass null to clear."),
features: z
.record(z.unknown())
.record(z.string(), z.unknown())
.optional()
.describe("Provider-specific feature values, for example { fast_mode: true } for Codex."),
})
@@ -715,7 +715,10 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom
modeId: z.string().optional().describe("Draft session mode ID."),
model: z.string().optional().describe("Draft model ID."),
thinkingOptionId: z.string().optional().describe("Draft thinking option ID."),
features: z.record(z.unknown()).optional().describe("Draft provider feature values."),
features: z
.record(z.string(), z.unknown())
.optional()
.describe("Draft provider feature values."),
})
.strict();
const agentToAgentInputSchema = {
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { Logger } from "pino";
import type { AgentPermissionRequest } from "./agent-sdk-types.js";
@@ -66,8 +66,8 @@ const cases: ParityCase[] = [
},
{
label: "non-existent path (canonicalize fallback)",
// realpath will throw; canonicalize falls back to NFC of input. SDK does
// the same, so paths should still match.
// realpath will throw; canonicalize falls back to the input path. SDK does
// the same, including platform-specific normalization, so paths should match.
build: async () => join(workspaceRoot, "this-path-was-never-created-" + randomUUID()),
},
];
@@ -6,8 +6,8 @@ import { join } from "node:path";
// Verbatim port of the Claude Agent SDK's project-directory encoding so
// paseo computes the same `~/.claude/projects/<dir>` path the SDK does.
// The SDK ships only as a precompiled bundle; grep the JS source at
// node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs for `function f1`,
// `function i4`, `function tB`, `S0=200`.
// node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs for `function Ar`,
// `function wo`, `function kn`, `function Lq`, `Ai=200`.
const PROJECT_DIR_LENGTH_CAP = 200;
@@ -32,20 +32,24 @@ export function claudeProjectDirSync(cwd: string, options?: ClaudeProjectDirOpti
async function canonicalize(input: string): Promise<string> {
try {
return (await realpath(input)).normalize("NFC");
return normalizeLikeSdk(await realpath(input));
} catch {
return input.normalize("NFC");
return normalizeLikeSdk(input);
}
}
function canonicalizeSync(input: string): string {
try {
return realpathSync.native(input).normalize("NFC");
return normalizeLikeSdk(realpathSync.native(input));
} catch {
return input.normalize("NFC");
return normalizeLikeSdk(input);
}
}
function normalizeLikeSdk(path: string): string {
return process.platform === "darwin" ? path.normalize("NFC") : path;
}
function encode(input: string): string {
const replaced = input.replace(/[^a-zA-Z0-9]/g, "-");
if (replaced.length <= PROJECT_DIR_LENGTH_CAP) {
@@ -1,5 +1,5 @@
import { createHash } from "node:crypto";
import { z } from "zod3";
import { z } from "zod";
import type { AgentTimelineItem } from "../../agent-sdk-types.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallDetail } from "../../agent-sdk-types.js";
import {
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallTimelineItem } from "../../agent-sdk-types.js";
import { isSpeakToolName } from "@getpaseo/protocol/tool-name-normalization";
@@ -39,7 +39,7 @@ import * as fsSync from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { z } from "zod3";
import { z } from "zod";
import { renderPromptAttachmentAsText } from "../prompt-attachments.js";
import { composeSystemPromptParts } from "../system-prompt.js";
import { curateAgentActivity } from "../activity-curator.js";
@@ -1,7 +1,7 @@
import type { ChildProcessWithoutNullStreams } from "node:child_process";
import readline from "node:readline";
import type { Logger } from "pino";
import { z } from "zod3";
import { z } from "zod";
import { terminateWithTreeKill } from "../../../../utils/tree-kill.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallDetail } from "../../agent-sdk-types.js";
import { stripCwdPrefix } from "@getpaseo/protocol/path-utils";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallTimelineItem } from "../../agent-sdk-types.js";
import {
@@ -13,7 +13,7 @@ import {
import { createPathEquivalenceMatcher } from "../../../utils/path.js";
import pLimit from "p-limit";
import type { Logger } from "pino";
import { z } from "zod3";
import { z } from "zod";
import {
getAgentStreamEventTurnId,
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallDetail } from "../../agent-sdk-types.js";
import { nonEmptyString, truncateDiffText } from "../tool-call-mapper-utils.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallTimelineItem } from "../../agent-sdk-types.js";
import { normalizeToolCallStatus } from "../tool-call-mapper-utils.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallDetail } from "../../agent-sdk-types.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { ToolCallDetail } from "../agent-sdk-types.js";
import {
@@ -424,11 +424,12 @@ interface ToolReadOutputValue {
content?: string;
}
export const ToolReadOutputSchema: z.ZodType<ToolReadOutputValue, z.ZodTypeDef, unknown> =
ToolReadOutputContentSchema;
export const ToolReadOutputSchema: z.ZodType<ToolReadOutputValue> = ToolReadOutputContentSchema;
export const ToolReadOutputWithPathSchema: z.ZodType<ToolReadOutputValue, z.ZodTypeDef, unknown> =
z.union([ToolReadOutputContentSchema, ToolReadOutputPathSchema]);
export const ToolReadOutputWithPathSchema: z.ZodType<ToolReadOutputValue> = z.union([
ToolReadOutputContentSchema,
ToolReadOutputPathSchema,
]);
export const ToolWriteContentSchema = z
.object({
@@ -934,8 +935,12 @@ export function toolDetailBranchByName<
input: inputSchema.nullable(),
output: outputSchema.nullable(),
});
return schema.transform((value: z.infer<typeof schema>) => {
return mapper(value.input, value.output);
return schema.transform((value) => {
const parsed = value as unknown as {
input: z.infer<InputSchema> | null;
output: z.infer<OutputSchema> | null;
};
return mapper(parsed.input, parsed.output);
});
}
@@ -957,8 +962,12 @@ export function toolDetailBranchByToolName<
input: inputSchema.nullable(),
output: outputSchema.nullable(),
});
return schema.transform((value: z.infer<typeof schema>) => {
return mapper(value.input, value.output);
return schema.transform((value) => {
const parsed = value as unknown as {
input: z.infer<InputSchema> | null;
output: z.infer<OutputSchema> | null;
};
return mapper(parsed.input, parsed.output);
});
}
@@ -982,7 +991,12 @@ export function toolDetailBranchByNameWithCwd<
output: outputSchema.nullable(),
cwd: z.string().optional().nullable(),
});
return schema.transform((value: z.infer<typeof schema>) => {
return mapper(value.input, value.output, value.cwd ?? null);
return schema.transform((value) => {
const parsed = value as unknown as {
input: z.infer<InputSchema> | null;
output: z.infer<OutputSchema> | null;
cwd?: string | null;
};
return mapper(parsed.input, parsed.output, parsed.cwd ?? null);
});
}
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
import { promises as fs } from "node:fs";
import path from "node:path";
import type pino from "pino";
import { z } from "zod3";
import { z } from "zod";
import { writeJsonFileAtomic } from "../atomic-file.js";
import {
ChatMessageSchema,
+1 -1
View File
@@ -1,6 +1,6 @@
import path from "node:path";
import { resolvePaseoNodeEnv } from "./paseo-env.js";
import { z } from "zod3";
import { z } from "zod";
import { expandTilde } from "../utils/path.js";
import type { PaseoDaemonConfig } from "./bootstrap.js";
@@ -3,7 +3,7 @@ import { execSync } from "child_process";
import { existsSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "fs";
import { tmpdir } from "os";
import path from "path";
import { z } from "zod3";
import { z } from "zod";
import {
createDaemonTestContext,
+1 -1
View File
@@ -1,6 +1,6 @@
import { existsSync, readFileSync } from "node:fs";
import path from "node:path";
import { z } from "zod3";
import { z } from "zod";
import type pino from "pino";
import {
+1 -1
View File
@@ -1,7 +1,7 @@
import { randomUUID } from "node:crypto";
import { promises as fs } from "node:fs";
import path from "node:path";
import { z } from "zod3";
import { z } from "zod";
import type { Logger } from "pino";
import { writeJsonFileAtomic } from "./atomic-file.js";
import { curateAgentActivity } from "./agent/activity-curator.js";
@@ -1,7 +1,7 @@
import { existsSync, readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { z } from "zod3";
import { z } from "zod";
interface ResolvePackageVersionParams {
moduleUrl?: string;
@@ -1,6 +1,6 @@
import { existsSync, readFileSync } from "node:fs";
import path from "node:path";
import { z } from "zod3";
import { z } from "zod";
import {
AgentProviderRuntimeSettingsMapSchema,
+1 -1
View File
@@ -2,7 +2,7 @@ import { open, readFile, unlink, mkdir } from "node:fs/promises";
import { existsSync } from "node:fs";
import { join } from "node:path";
import { hostname } from "node:os";
import { z } from "zod3";
import { z } from "zod";
export const pidLockInfoSchema = z.object({
pid: z.number(),
+1 -1
View File
@@ -4,7 +4,7 @@ import { realpathSync } from "node:fs";
import type { FSWatcher } from "node:fs";
import { basename, resolve, sep } from "path";
import { homedir } from "node:os";
import { z } from "zod3";
import { z } from "zod";
import type { ToolSet } from "ai";
import { CLIENT_CAPS, type ClientCapability } from "@getpaseo/protocol/client-capabilities";
import {
@@ -3,7 +3,7 @@ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "nod
import { homedir, tmpdir } from "node:os";
import path from "node:path";
import { expect, test, vi } from "vitest";
import { z } from "zod3";
import { z } from "zod";
import { Session } from "./session.js";
import type { AgentSnapshotPayload, SessionOutboundMessage } from "@getpaseo/protocol/messages";
import { AgentManager } from "./agent/agent-manager.js";
@@ -1,6 +1,6 @@
import path from "node:path";
import { z } from "zod3";
import { z } from "zod";
import type { PersistedConfig } from "../../../persisted-config.js";
import type { RequestedSpeechProviders } from "../../speech-types.js";
@@ -45,9 +45,13 @@ export interface LocalSpeechSttLanguageConfig {
const NumberLikeSchema = z.union([z.number(), z.string().trim().min(1)]);
const LanguageSchema = z.string().trim().min(1).default(DEFAULT_STT_LANGUAGE);
const OptionalFiniteNumberSchema = NumberLikeSchema.pipe(z.coerce.number().finite()).optional();
const OptionalFiniteNumberSchema = NumberLikeSchema.pipe(
z.coerce.number<string | number>().finite(),
).optional();
const OptionalIntegerSchema = NumberLikeSchema.pipe(z.coerce.number().int()).optional();
const OptionalIntegerSchema = NumberLikeSchema.pipe(
z.coerce.number<string | number>().int(),
).optional();
const LocalSpeechResolutionSchema = z.object({
includeProviderConfig: z.boolean(),
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
export type SherpaOnnxModelKind = "stt-offline" | "tts";
@@ -85,9 +85,7 @@ function resolveDefaultModelId(role: DefaultModelRole): SherpaOnnxModelId {
export const DEFAULT_LOCAL_STT_MODEL = resolveDefaultModelId("stt");
export const DEFAULT_LOCAL_TTS_MODEL = resolveDefaultModelId("tts");
function createModelIdSchema<T extends string>(
modelIds: readonly T[],
): z.ZodType<T, z.ZodTypeDef, string> {
function createModelIdSchema<T extends string>(modelIds: readonly T[]): z.ZodType<T, string> {
const validIds = new Set<string>(modelIds);
return z
.string()
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { PersistedConfig } from "../../../persisted-config.js";
import type { RequestedSpeechProviders } from "../../speech-types.js";
@@ -21,7 +21,9 @@ const OpenAiTtsModelSchema = z.enum(["tts-1", "tts-1-hd"]);
const NumberLikeSchema = z.union([z.number(), z.string().trim().min(1)]);
const OptionalFiniteNumberSchema = NumberLikeSchema.pipe(z.coerce.number().finite()).optional();
const OptionalFiniteNumberSchema = NumberLikeSchema.pipe(
z.coerce.number<string | number>().finite(),
).optional();
const OptionalTrimmedStringSchema = z
.string()
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { PersistedConfig } from "../persisted-config.js";
import type { PaseoOpenAIConfig, PaseoSpeechConfig } from "../bootstrap.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
export const SpeechProviderIdSchema = z.enum(["openai", "local"]);
export type SpeechProviderId = z.infer<typeof SpeechProviderIdSchema>;
@@ -98,7 +98,7 @@ vi.mock("./push/push-service.js", () => ({
},
}));
import { z } from "zod3";
import { z } from "zod";
import { VoiceAssistantWebSocketServer } from "./websocket-server";
import { parseServerInfoStatusPayload } from "./messages.js";
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js";
@@ -1048,7 +1048,7 @@ export class VoiceAssistantWebSocketServer {
serverId: this.serverId,
hostname: getHostname(),
version: this.daemonVersion,
...(this.serverCapabilities ? { capabilities: this.serverCapabilities } : {}),
capabilities: this.serverCapabilities,
features: {
// COMPAT(providersSnapshot): keep optional until all clients rely on snapshot flow.
providersSnapshot: true,
@@ -1,5 +1,5 @@
import pino from "pino";
import { z } from "zod3";
import { z } from "zod";
import { describe, expect, test } from "vitest";
import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
@@ -1,7 +1,7 @@
import { promises as fs } from "node:fs";
import type { Logger } from "pino";
import { z } from "zod3";
import { z } from "zod";
import { writeJsonFileAtomic } from "./atomic-file.js";
import type { PersistedProjectKind, PersistedWorkspaceKind } from "./workspace-registry-model.js";
@@ -62,7 +62,7 @@ type RegistryRecord = PersistedProjectRecord | PersistedWorkspaceRecord;
class FileBackedRegistry<TRecord extends RegistryRecord> {
private readonly filePath: string;
private readonly logger: Logger;
private readonly schema: z.ZodType<TRecord, z.ZodTypeDef, unknown>;
private readonly schema: z.ZodType<TRecord, unknown>;
private readonly getId: (record: TRecord) => string;
private loaded = false;
private readonly cache = new Map<string, TRecord>();
@@ -71,7 +71,7 @@ class FileBackedRegistry<TRecord extends RegistryRecord> {
constructor(options: {
filePath: string;
logger: Logger;
schema: z.ZodType<TRecord, z.ZodTypeDef, unknown>;
schema: z.ZodType<TRecord, unknown>;
getId: (record: TRecord) => string;
component: string;
}) {
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { FirstAgentContext } from "@getpaseo/protocol/messages";
import type { AgentManager } from "./agent/agent-manager.js";
import {
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import type { GitHubSearchKind } from "@getpaseo/protocol/messages";
import { findExecutable } from "../utils/executable.js";
import { resolveGitHubRemote } from "../utils/github-remote.js";
@@ -1,4 +1,4 @@
import { z } from "zod3";
import { z } from "zod";
import { stripCwdPrefix } from "@getpaseo/protocol/path-utils";
const SHELL_WRAPPER_PREFIX_PATTERN = /^\/bin\/(?:zsh|bash|sh)\s+(?:-[a-zA-Z]+\s+)?/;
@@ -1,6 +1,6 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
import { isAbsolute, join, resolve } from "path";
import { z } from "zod3";
import { z } from "zod";
const PaseoWorktreeMetadataV1Schema = z.object({
version: z.literal(1),