fix: make worktreeRoot backward-compatible for old clients/daemons

worktreeRoot was added as a required field in 9154f8fc, which breaks
old clients parsing new daemon responses and new clients parsing old
daemon responses. Made it .optional() with .transform() fallbacks.

Also added a critical rule to CLAUDE.md: schema changes must always
be backward-compatible in both directions.
This commit is contained in:
Mohamed Boudra
2026-04-04 20:29:44 +07:00
parent 018ebd5f29
commit 1e9b7f1157
3 changed files with 115 additions and 27 deletions
@@ -50,4 +50,71 @@ describe("workspace message schemas", () => {
expect(result.success).toBe(false);
});
test("parses legacy fetch_agents_response checkout payloads without worktreeRoot", () => {
const result = SessionOutboundMessageSchema.safeParse({
type: "fetch_agents_response",
payload: {
requestId: "req-1",
entries: [
{
agent: {
id: "agent-1",
provider: "codex",
cwd: "C:\\repo",
model: null,
features: [],
thinkingOptionId: null,
effectiveThinkingOptionId: null,
createdAt: "2026-04-04T00:00:00.000Z",
updatedAt: "2026-04-04T00:00:00.000Z",
lastUserMessageAt: null,
status: "running",
capabilities: {
supportsStreaming: true,
supportsSessionPersistence: true,
supportsDynamicModes: true,
supportsMcpServers: true,
supportsReasoningStream: true,
supportsToolInvocations: true,
},
currentModeId: null,
availableModes: [],
pendingPermissions: [],
persistence: null,
title: "Agent 1",
labels: {},
requiresAttention: false,
attentionReason: null,
},
project: {
projectKey: "remote:github.com/acme/repo",
projectName: "acme/repo",
checkout: {
cwd: "C:\\repo",
isGit: true,
currentBranch: "main",
remoteUrl: "https://github.com/acme/repo.git",
isPaseoOwnedWorktree: false,
mainRepoRoot: null,
},
},
},
],
pageInfo: {
nextCursor: null,
prevCursor: null,
hasMore: false,
},
},
});
expect(result.success).toBe(true);
if (!result.success) {
return;
}
const checkout = result.data.payload.entries[0]?.project.checkout;
expect(checkout?.worktreeRoot).toBe("C:\\repo");
});
});