feat(ui): add OpenClaw support to frontend components

- Update App.tsx with openclaw visibility and skills fallback
- Add OpenClaw to AppSwitcher icon and display name maps
- Update McpFormModal with openclaw in enabled apps
- Update PromptFormModal/Panel with openclaw filename map
- Update EndpointSpeedTest with openclaw timeout
- Update AppVisibilitySettings with openclaw toggle
- Update test state with openclaw defaults
This commit is contained in:
Jason
2026-02-01 20:32:02 +08:00
parent 545be56698
commit fedb08e846
9 changed files with 22 additions and 6 deletions
+3 -1
View File
@@ -123,6 +123,7 @@ function App() {
codex: true,
gemini: true,
opencode: true,
openclaw: true,
};
const getFirstVisibleApp = (): AppId => {
@@ -130,6 +131,7 @@ function App() {
if (visibleApps.codex) return "codex";
if (visibleApps.gemini) return "gemini";
if (visibleApps.opencode) return "opencode";
if (visibleApps.openclaw) return "openclaw";
return "claude"; // fallback
};
@@ -586,7 +588,7 @@ function App() {
return (
<SkillsPage
ref={skillsPageRef}
initialApp={activeApp === "opencode" ? "claude" : activeApp}
initialApp={activeApp === "opencode" || activeApp === "openclaw" ? "claude" : activeApp}
/>
);
case "mcp":
+2
View File
@@ -29,12 +29,14 @@ export function AppSwitcher({
codex: "openai",
gemini: "gemini",
opencode: "opencode",
openclaw: "openclaw",
};
const appDisplayName: Record<AppId, string> = {
claude: "Claude",
codex: "Codex",
gemini: "Gemini",
opencode: "OpenCode",
openclaw: "OpenClaw",
};
// Filter apps based on visibility settings (default all visible)
+2
View File
@@ -66,6 +66,7 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
codex: boolean;
gemini: boolean;
opencode: boolean;
openclaw: boolean;
}>(() => {
if (initialData?.apps) {
return { ...initialData.apps };
@@ -75,6 +76,7 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
codex: defaultEnabledApps.includes("codex"),
gemini: defaultEnabledApps.includes("gemini"),
opencode: defaultEnabledApps.includes("opencode"),
openclaw: defaultEnabledApps.includes("openclaw"),
};
});
@@ -35,6 +35,7 @@ const PromptFormModal: React.FC<PromptFormModalProps> = ({
codex: "AGENTS.md",
gemini: "GEMINI.md",
opencode: "AGENTS.md",
openclaw: "AGENTS.md",
};
const filename = filenameMap[appId];
const [name, setName] = useState("");
@@ -29,6 +29,7 @@ const PromptFormPanel: React.FC<PromptFormPanelProps> = ({
codex: "AGENTS.md",
gemini: "GEMINI.md",
opencode: "AGENTS.md",
openclaw: "AGENTS.md",
};
const filename = filenameMap[appId];
const [name, setName] = useState("");
@@ -14,6 +14,7 @@ const ENDPOINT_TIMEOUT_SECS: Record<AppId, number> = {
claude: 8,
gemini: 8,
opencode: 8,
openclaw: 8,
};
interface TestResult {
@@ -4,9 +4,10 @@ import {
setCodexBaseUrl as setCodexBaseUrlInConfig,
} from "@/utils/providerConfigUtils";
import type { ProviderCategory } from "@/types";
import type { AppId } from "@/lib/api";
interface UseBaseUrlStateProps {
appType: "claude" | "codex" | "gemini" | "opencode";
appType: AppId;
category: ProviderCategory | undefined;
settingsConfig: string;
codexConfig?: string;
@@ -20,6 +20,7 @@ const APP_CONFIG: Array<{
{ id: "codex", icon: "openai", nameKey: "apps.codex" },
{ id: "gemini", icon: "gemini", nameKey: "apps.gemini" },
{ id: "opencode", icon: "opencode", nameKey: "apps.opencode" },
{ id: "openclaw", icon: "openclaw", nameKey: "apps.openclaw" },
];
export function AppVisibilitySettings({
@@ -33,6 +34,7 @@ export function AppVisibilitySettings({
codex: true,
gemini: true,
opencode: true,
openclaw: true,
};
// Count how many apps are currently visible
+8 -4
View File
@@ -58,6 +58,7 @@ const createDefaultProviders = (): ProvidersByApp => ({
},
},
opencode: {},
openclaw: {},
});
const createDefaultCurrent = (): CurrentProviderState => ({
@@ -65,6 +66,7 @@ const createDefaultCurrent = (): CurrentProviderState => ({
codex: "codex-1",
gemini: "gemini-1",
opencode: "",
openclaw: "",
});
let providers = createDefaultProviders();
@@ -84,7 +86,7 @@ let mcpConfigs: McpConfigState = {
id: "sample",
name: "Sample Claude Server",
enabled: true,
apps: { claude: true, codex: false, gemini: false, opencode: false },
apps: { claude: true, codex: false, gemini: false, opencode: false, openclaw: false },
server: {
type: "stdio",
command: "claude-server",
@@ -96,7 +98,7 @@ let mcpConfigs: McpConfigState = {
id: "httpServer",
name: "HTTP Codex Server",
enabled: false,
apps: { claude: false, codex: true, gemini: false, opencode: false },
apps: { claude: false, codex: true, gemini: false, opencode: false, openclaw: false },
server: {
type: "http",
url: "http://localhost:3000",
@@ -105,6 +107,7 @@ let mcpConfigs: McpConfigState = {
},
gemini: {},
opencode: {},
openclaw: {},
};
const cloneProviders = (value: ProvidersByApp) =>
@@ -128,7 +131,7 @@ export const resetProviderState = () => {
id: "sample",
name: "Sample Claude Server",
enabled: true,
apps: { claude: true, codex: false, gemini: false, opencode: false },
apps: { claude: true, codex: false, gemini: false, opencode: false, openclaw: false },
server: {
type: "stdio",
command: "claude-server",
@@ -140,7 +143,7 @@ export const resetProviderState = () => {
id: "httpServer",
name: "HTTP Codex Server",
enabled: false,
apps: { claude: false, codex: true, gemini: false, opencode: false },
apps: { claude: false, codex: true, gemini: false, opencode: false, openclaw: false },
server: {
type: "http",
url: "http://localhost:3000",
@@ -149,6 +152,7 @@ export const resetProviderState = () => {
},
gemini: {},
opencode: {},
openclaw: {},
};
};