- Updated CLI tool components to accept initial status as a prop, improving state management for tool statuses.

- Added functionality to fetch and set statuses for various CLI tools (Claude, Codex, Droid, OpenClaw, Antigravity) on component mount.
- Enhanced error handling and logging in the OAuth provider test utilities and DNS management functions.
- Improved the MITM server to handle multiple target hosts and provide clearer error messages regarding port usage.
This commit is contained in:
decolua committed 2026-02-25 16:32:05 +07:00
1 parent 484e7025e8
commit 9003675b71
13 files changed
+244 -133

No files matched your search

@@ -8,6 +8,14 @@ import { ClaudeToolCard, CodexToolCard, DroidToolCard, OpenClawToolCard, Default
const CLOUD_URL = process.env.NEXT_PUBLIC_CLOUD_URL;
const STATUS_ENDPOINTS = {
claude: "/api/cli-tools/claude-settings",
codex: "/api/cli-tools/codex-settings",
droid: "/api/cli-tools/droid-settings",
openclaw: "/api/cli-tools/openclaw-settings",
antigravity: "/api/cli-tools/antigravity-mitm",
};
export default function CLIToolsPageClient({ machineId }) {
const [connections, setConnections] = useState([]);
const [loading, setLoading] = useState(true);
@@ -17,13 +25,34 @@ export default function CLIToolsPageClient({ machineId }) {
const [tunnelEnabled, setTunnelEnabled] = useState(false);
const [tunnelUrl, setTunnelUrl] = useState("");
const [apiKeys, setApiKeys] = useState([]);
const [toolStatuses, setToolStatuses] = useState({});
useEffect(() => {
fetchConnections();
loadCloudSettings();
fetchApiKeys();
fetchAllStatuses();
}, []);
const fetchAllStatuses = async () => {
try {
const entries = await Promise.all(
Object.entries(STATUS_ENDPOINTS).map(async ([toolId, url]) => {
try {
const res = await fetch(url);
const data = await res.json();
return [toolId, data];
} catch {
return [toolId, null];
}
})
);
setToolStatuses(Object.fromEntries(entries));
} catch (error) {
console.log("Error fetching tool statuses:", error);
}
};
const loadCloudSettings = async () => {
try {
const [settingsRes, tunnelRes] = await Promise.all([
@@ -165,16 +194,17 @@ export default function CLIToolsPageClient({ machineId }) {
onModelMappingChange={(alias, target) => handleModelMappingChange(toolId, alias, target)}
hasActiveProviders={hasActiveProviders}
cloudEnabled={cloudEnabled}
initialStatus={toolStatuses.claude}
/>
);
case "codex":
return <CodexToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} cloudEnabled={cloudEnabled} />;
return <CodexToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} cloudEnabled={cloudEnabled} initialStatus={toolStatuses.codex} />;
case "droid":
return <DroidToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
return <DroidToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} initialStatus={toolStatuses.droid} />;
case "openclaw":
return <OpenClawToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
return <OpenClawToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} initialStatus={toolStatuses.openclaw} />;
case "antigravity":
return <AntigravityToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} />;
return <AntigravityToolCard key={toolId} {...commonProps} activeProviders={getActiveProviders()} hasActiveProviders={hasActiveProviders} cloudEnabled={cloudEnabled} initialStatus={toolStatuses.antigravity} />;
default:
return <DefaultToolCard key={toolId} toolId={toolId} {...commonProps} activeProviders={getActiveProviders()} cloudEnabled={cloudEnabled} />;
}
@@ -13,8 +13,9 @@ export default function AntigravityToolCard({
activeProviders,
hasActiveProviders,
cloudEnabled,
initialStatus,
}) {
const [status, setStatus] = useState(null);
const [status, setStatus] = useState(initialStatus || null);
const [loading, setLoading] = useState(false);
const [showPasswordModal, setShowPasswordModal] = useState(false);
const [sudoPassword, setSudoPassword] = useState("");
@@ -30,12 +31,17 @@ export default function AntigravityToolCard({
}
}, [apiKeys, selectedApiKey]);
useEffect(() => {
if (initialStatus) setStatus(initialStatus);
}, [initialStatus]);
useEffect(() => {
if (isExpanded && !status) {
fetchStatus();
loadSavedMappings();
}
}, [isExpanded, status]);
if (isExpanded) loadSavedMappings();
}, [isExpanded]);
const loadSavedMappings = async () => {
try {
@@ -17,8 +17,9 @@ export default function ClaudeToolCard({
hasActiveProviders,
apiKeys,
cloudEnabled,
initialStatus,
}) {
const [claudeStatus, setClaudeStatus] = useState(null);
const [claudeStatus, setClaudeStatus] = useState(initialStatus || null);
const [checkingClaude, setCheckingClaude] = useState(false);
const [applying, setApplying] = useState(false);
const [restoring, setRestoring] = useState(false);
@@ -51,12 +52,17 @@ export default function ClaudeToolCard({
}
}, [apiKeys, selectedApiKey]);
useEffect(() => {
if (initialStatus) setClaudeStatus(initialStatus);
}, [initialStatus]);
useEffect(() => {
if (isExpanded && !claudeStatus) {
checkClaudeStatus();
fetchModelAliases();
}
}, [isExpanded, claudeStatus]);
if (isExpanded) fetchModelAliases();
}, [isExpanded]);
const fetchModelAliases = async () => {
try {
@@ -4,8 +4,8 @@ import { useState, useEffect } from "react";
import { Card, Button, ModelSelectModal, ManualConfigModal } from "@/shared/components";
import Image from "next/image";
export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, apiKeys, activeProviders, cloudEnabled }) {
const [codexStatus, setCodexStatus] = useState(null);
export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, apiKeys, activeProviders, cloudEnabled, initialStatus }) {
const [codexStatus, setCodexStatus] = useState(initialStatus || null);
const [checkingCodex, setCheckingCodex] = useState(false);
const [applying, setApplying] = useState(false);
const [restoring, setRestoring] = useState(false);
@@ -24,12 +24,17 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
}
}, [apiKeys, selectedApiKey]);
useEffect(() => {
if (initialStatus) setCodexStatus(initialStatus);
}, [initialStatus]);
useEffect(() => {
if (isExpanded && !codexStatus) {
checkCodexStatus();
fetchModelAliases();
}
}, [isExpanded, codexStatus]);
if (isExpanded) fetchModelAliases();
}, [isExpanded]);
const fetchModelAliases = async () => {
try {
@@ -15,8 +15,9 @@ export default function DroidToolCard({
apiKeys,
activeProviders,
cloudEnabled,
initialStatus,
}) {
const [droidStatus, setDroidStatus] = useState(null);
const [droidStatus, setDroidStatus] = useState(initialStatus || null);
const [checkingDroid, setCheckingDroid] = useState(false);
const [applying, setApplying] = useState(false);
const [restoring, setRestoring] = useState(false);
@@ -48,12 +49,17 @@ export default function DroidToolCard({
}
}, [apiKeys, selectedApiKey]);
useEffect(() => {
if (initialStatus) setDroidStatus(initialStatus);
}, [initialStatus]);
useEffect(() => {
if (isExpanded && !droidStatus) {
checkDroidStatus();
fetchModelAliases();
}
}, [isExpanded, droidStatus]);
if (isExpanded) fetchModelAliases();
}, [isExpanded]);
const fetchModelAliases = async () => {
try {
@@ -13,8 +13,9 @@ export default function OpenClawToolCard({
apiKeys,
activeProviders,
cloudEnabled,
initialStatus,
}) {
const [openclawStatus, setOpenclawStatus] = useState(null);
const [openclawStatus, setOpenclawStatus] = useState(initialStatus || null);
const [checkingOpenclaw, setCheckingOpenclaw] = useState(false);
const [applying, setApplying] = useState(false);
const [restoring, setRestoring] = useState(false);
@@ -45,12 +46,17 @@ export default function OpenClawToolCard({
}
}, [apiKeys, selectedApiKey]);
useEffect(() => {
if (initialStatus) setOpenclawStatus(initialStatus);
}, [initialStatus]);
useEffect(() => {
if (isExpanded && !openclawStatus) {
checkOpenclawStatus();
fetchModelAliases();
}
}, [isExpanded, openclawStatus]);
if (isExpanded) fetchModelAliases();
}, [isExpanded]);
const fetchModelAliases = async () => {
try {