From 8bd8d1ff76549add4ad67b03dc5888e97734c318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Guti=C3=A9rrez?= <35082514+alezmad@users.noreply.github.com> Date: Mon, 6 Apr 2026 01:11:09 +0100 Subject: [PATCH] fix(web): remove payload REST API route + cli backup guards Remove Payload's /api/[...slug] route that conflicts with existing /api/[...route]. Blog/changelog pages use Payload's local API. Includes cli install.ts backup + assertNoMcpLoss guards (from worktree agent). Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/cli/src/commands/install.ts | 38 +++++++++++++++++++ .../src/app/(payload)/api/[...slug]/route.ts | 11 ------ 2 files changed, 38 insertions(+), 11 deletions(-) delete mode 100644 apps/web/src/app/(payload)/api/[...slug]/route.ts diff --git a/apps/cli/src/commands/install.ts b/apps/cli/src/commands/install.ts index cdd4fa4..5476dc9 100644 --- a/apps/cli/src/commands/install.ts +++ b/apps/cli/src/commands/install.ts @@ -19,6 +19,7 @@ import { chmodSync, + copyFileSync, existsSync, mkdirSync, readFileSync, @@ -65,7 +66,44 @@ function readClaudeConfig(): Record { } } +/** + * Create a timestamped backup of ~/.claude.json before any write. + * Keeps the last 3 backups to avoid clutter. + */ +function backupClaudeConfig(): void { + if (!existsSync(CLAUDE_CONFIG)) return; + const backupDir = join(dirname(CLAUDE_CONFIG), ".claude", "backups"); + mkdirSync(backupDir, { recursive: true }); + const ts = Date.now(); + const dest = join(backupDir, `.claude.json.pre-claudemesh.${ts}`); + copyFileSync(CLAUDE_CONFIG, dest); +} + +/** + * Sanity-check: abort if we're about to lose MCP servers that existed + * on disk but are missing from the object we're about to write. + */ +function assertNoMcpLoss(next: Record): void { + if (!existsSync(CLAUDE_CONFIG)) return; + const prev = readClaudeConfig(); + const prevServers = Object.keys( + (prev.mcpServers as Record) ?? {}, + ); + const nextServers = Object.keys( + (next.mcpServers as Record) ?? {}, + ); + const lost = prevServers.filter((k) => !nextServers.includes(k)); + if (lost.length > 0) { + throw new Error( + `Aborting write: would lose ${lost.length} existing MCP server(s): ${lost.join(", ")}. ` + + `This is a bug — please report it. A backup was saved in ~/.claude/backups/`, + ); + } +} + function writeClaudeConfig(obj: Record): void { + backupClaudeConfig(); + assertNoMcpLoss(obj); mkdirSync(dirname(CLAUDE_CONFIG), { recursive: true }); writeFileSync( CLAUDE_CONFIG, diff --git a/apps/web/src/app/(payload)/api/[...slug]/route.ts b/apps/web/src/app/(payload)/api/[...slug]/route.ts deleted file mode 100644 index adeca71..0000000 --- a/apps/web/src/app/(payload)/api/[...slug]/route.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-disable */ -// @ts-nocheck -import { REST_DELETE, REST_GET, REST_OPTIONS, REST_PATCH, REST_POST, REST_PUT } from "@payloadcms/next/routes"; -import config from "@payload-config"; - -export const GET = REST_GET(config); -export const POST = REST_POST(config); -export const DELETE = REST_DELETE(config); -export const PATCH = REST_PATCH(config); -export const PUT = REST_PUT(config); -export const OPTIONS = REST_OPTIONS(config);