fix: remove the hide cursor on windows logic

This commit is contained in:
Haileyesus
2026-05-28 20:50:46 +03:00
parent 374e9de719
commit dd6614bca3
6 changed files with 12 additions and 98 deletions

View File

@@ -1,18 +1,7 @@
import os from 'node:os';
import { providerRegistry } from '@/modules/providers/provider.registry.js';
import type { LLMProvider, McpScope, ProviderMcpServer, UpsertProviderMcpServerInput } from '@/shared/types.js';
import { AppError } from '@/shared/utils.js';
/** Cursor MCP is not supported on Windows hosts (no Cursor CLI integration). */
function includeProviderInGlobalMcp(providerId: LLMProvider): boolean {
if (providerId === 'cursor' && os.platform() === 'win32') {
return false;
}
return true;
}
export const providerMcpService = {
/**
@@ -75,7 +64,7 @@ export const providerMcpService = {
const scope = input.scope ?? 'project';
const results: Array<{ provider: LLMProvider; created: boolean; error?: string }> = [];
const providers = providerRegistry.listProviders().filter((p) => includeProviderInGlobalMcp(p.id));
const providers = providerRegistry.listProviders();
for (const provider of providers) {
try {
await provider.mcp.upsertServer({ ...input, scope });

View File

@@ -341,8 +341,7 @@ test('providerMcpService global adder writes to all providers and rejects unsupp
workspacePath,
});
const expectCursorGlobal = process.platform !== 'win32';
assert.equal(globalResult.length, expectCursorGlobal ? 5 : 4);
assert.equal(globalResult.length, 5);
assert.ok(globalResult.every((entry) => entry.created === true));
const claudeProject = await readJson(path.join(workspacePath, '.mcp.json'));
@@ -357,10 +356,8 @@ test('providerMcpService global adder writes to all providers and rejects unsupp
const opencodeProject = await readJson(path.join(workspacePath, 'opencode.json'));
assert.ok((opencodeProject.mcp as Record<string, unknown>)['global-http']);
if (expectCursorGlobal) {
const cursorProject = await readJson(path.join(workspacePath, '.cursor', 'mcp.json'));
assert.ok((cursorProject.mcpServers as Record<string, unknown>)['global-http']);
}
const cursorProject = await readJson(path.join(workspacePath, '.cursor', 'mcp.json'));
assert.ok((cursorProject.mcpServers as Record<string, unknown>)['global-http']);
await assert.rejects(
providerMcpService.addMcpServerToAllProviders({

View File

@@ -1,4 +1,5 @@
import express from 'express';
import { apiKeysDb, credentialsDb, notificationPreferencesDb, pushSubscriptionsDb } from '../modules/database/index.js';
import { getPublicKey } from '../services/vapid-keys.js';
import { createNotificationEvent, notifyUserIfEnabled } from '../services/notification-orchestrator.js';
@@ -273,14 +274,4 @@ router.post('/push/unsubscribe', async (req, res) => {
}
});
// Host OS for UI (e.g. hide Cursor agent when the backend runs on Windows).
router.get('/server-env', async (req, res) => {
try {
res.json({ platform: process.platform });
} catch (error) {
console.error('Error reading server environment:', error);
res.status(500).json({ error: 'Failed to read server environment' });
}
});
export default router;

View File

@@ -1,8 +1,7 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import React, { useCallback, useMemo, useState } from "react";
import { Check, ChevronDown } from "lucide-react";
import { Trans, useTranslation } from "react-i18next";
import { useServerPlatform } from "../../../../hooks/useServerPlatform";
import type {
ProjectSession,
LLMProvider,
@@ -120,24 +119,15 @@ export default function ProviderSelectionEmptyState({
setInput,
}: ProviderSelectionEmptyStateProps) {
const { t } = useTranslation("chat");
const { isWindowsServer } = useServerPlatform();
const [dialogOpen, setDialogOpen] = useState(false);
const visibleProviderGroups = useMemo(() => {
const groups: ProviderGroup[] = PROVIDER_META.map((p) => ({
const visibleProviderGroups = useMemo<ProviderGroup[]>(() => {
return PROVIDER_META.map((p) => ({
id: p.id,
name: p.name,
models: providerModelCatalog[p.id]?.OPTIONS ?? [],
}));
return isWindowsServer ? groups.filter((p) => p.id !== "cursor") : groups;
}, [isWindowsServer, providerModelCatalog]);
useEffect(() => {
if (isWindowsServer && provider === "cursor") {
setProvider("claude");
localStorage.setItem("selected-provider", "claude");
}
}, [isWindowsServer, provider, setProvider]);
}, [providerModelCatalog]);
const nextTaskPrompt = t("tasks.nextTaskPrompt", {
defaultValue: "Start the next task",

View File

@@ -1,6 +1,5 @@
import { useEffect, useMemo, useState } from 'react';
import { useMemo, useState } from 'react';
import { useServerPlatform } from '../../../../../hooks/useServerPlatform';
import type { AgentCategory, AgentProvider } from '../../../types/types';
import type { AgentContext, AgentsSettingsTabProps } from './types';
@@ -23,22 +22,10 @@ export default function AgentsSettingsTab({
}: AgentsSettingsTabProps) {
const [selectedAgent, setSelectedAgent] = useState<AgentProvider>('claude');
const [selectedCategory, setSelectedCategory] = useState<AgentCategory>('account');
const { isWindowsServer } = useServerPlatform();
const visibleAgents = useMemo<AgentProvider[]>(() => {
const all: AgentProvider[] = ['claude', 'cursor', 'codex', 'gemini', 'opencode'];
if (isWindowsServer) {
return all.filter((id) => id !== 'cursor');
}
return all;
}, [isWindowsServer]);
useEffect(() => {
if (isWindowsServer && selectedAgent === 'cursor') {
setSelectedAgent('claude');
}
}, [isWindowsServer, selectedAgent]);
return ['claude', 'cursor', 'codex', 'gemini', 'opencode'];
}, []);
const agentContextById = useMemo<Record<AgentProvider, AgentContext>>(() => ({
claude: {

View File

@@ -1,40 +0,0 @@
import { useEffect, useState } from 'react';
import { authenticatedFetch } from '../utils/api';
/**
* Node `process.platform` from the API host (e.g. win32, darwin, linux).
* Null until loaded or if the request fails.
*/
export function useServerPlatform(): {
serverPlatform: string | null;
isWindowsServer: boolean;
} {
const [serverPlatform, setServerPlatform] = useState<string | null>(null);
useEffect(() => {
let cancelled = false;
(async () => {
try {
const response = await authenticatedFetch('/api/settings/server-env');
if (!response.ok) {
return;
}
const body = (await response.json()) as { platform?: string };
if (!cancelled && typeof body.platform === 'string') {
setServerPlatform(body.platform);
}
} catch {
// Keep null: treat as unknown host.
}
})();
return () => {
cancelled = true;
};
}, []);
return {
serverPlatform,
isWindowsServer: serverPlatform === 'win32',
};
}