feat: harden support, localize knowledge and add operator availability [skip ci]

Source-only publication of reviewed commit 64e96a7f423673dc29ad56485be9fc79bce8af1c.

Passed in isolation: focused frontend/backend tests, race checks, TypeScript typecheck, lint, Go compilation, Flowgram build, and deterministic SDK build/tests.

Not accepted as a production release: Next.js export/native assembly remains blocked by environment memory limits; browser interaction and MySQL staging acceptance remain unverified. No production server, database/schema, runtime configuration, deployment, release tag, or workflow execution was performed.

Expected source tree: 0a4a7528e9.
This commit is contained in:
2026-10-16 15:21:42 +00:00
parent 299ea50fb5
commit 2f7a491666
176 changed files with 11869 additions and 2716 deletions

View File

@@ -1,9 +1,9 @@
// Modified in AgentDeskFixes: safe, reviewed setup repairs and honest routing diagnostics.
"use client"
import {
AlertTriangleIcon,
CheckCircle2Icon,
Loader2Icon,
RefreshCwIcon,
ShieldAlertIcon,
SparklesIcon,
@@ -11,7 +11,6 @@ import {
} from "lucide-react"
import Link from "next/link"
import { useCallback, useEffect, useState } from "react"
import { toast } from "sonner"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
@@ -22,9 +21,7 @@ import {
} from "@/components/ui/popover"
import { useI18n } from "@/i18n/provider"
import {
applySetupQuickFix,
fetchSetupReadiness,
type SetupQuickFixAction,
type SetupReadinessResponse,
} from "@/lib/api/setup-readiness"
import { cn } from "@/lib/utils"
@@ -45,7 +42,6 @@ export function OperatorReadinessIndicator({
const t = useI18n()
const [readiness, setReadiness] = useState<SetupReadinessResponse | null>(null)
const [loading, setLoading] = useState(true)
const [fixing, setFixing] = useState(false)
const [open, setOpen] = useState(false)
const loadReadiness = useCallback(async () => {
@@ -66,30 +62,14 @@ export function OperatorReadinessIndicator({
}
window.addEventListener(SETUP_READINESS_UPDATED_EVENT, handleUpdated)
const interval = window.setInterval(() => {
void loadReadiness()
}, 45000)
if (document.visibilityState === "visible") void loadReadiness()
}, 60000)
return () => {
window.removeEventListener(SETUP_READINESS_UPDATED_EVENT, handleUpdated)
window.clearInterval(interval)
}
}, [loadReadiness])
async function handleQuickFix(action: SetupQuickFixAction) {
setFixing(true)
try {
const res = await applySetupQuickFix({ action })
setReadiness(res.readiness)
notifySetupReadinessUpdated()
toast.success(t("setupWizard.quickFixSuccess"))
} catch (error) {
toast.error(
error instanceof Error ? error.message : t("common.operationFailed"),
)
} finally {
setFixing(false)
}
}
if (loading && !readiness) {
return null
}
@@ -225,43 +205,10 @@ export function OperatorReadinessIndicator({
</div>
<div className="flex flex-col gap-1.5">
{!operatorOk && canEnableMyProfile ? (
<Button
size="sm"
className="w-full gap-1.5 rounded-md text-xs"
disabled={fixing}
onClick={() =>
void handleQuickFix(
chainOk || !canQuickSetupAll
? "enable_my_operator_profile"
: "quick_setup_all",
)
}
>
{fixing ? (
<Loader2Icon className="size-3.5 animate-spin" />
) : (
<SparklesIcon className="size-3.5" />
)}
<span>
{chainOk || !canQuickSetupAll
? t("setupWizard.enableMyReceptionBtn")
: t("setupWizard.quickSetupAll")}
</span>
</Button>
) : !chainOk && canQuickSetupAll ? (
<Button
size="sm"
className="w-full gap-1.5 rounded-md text-xs"
disabled={fixing}
onClick={() => void handleQuickFix("quick_setup_all")}
>
{fixing ? (
<Loader2Icon className="size-3.5 animate-spin" />
) : (
<SparklesIcon className="size-3.5" />
)}
<span>{t("setupWizard.quickSetupAll")}</span>
{(!operatorOk && canEnableMyProfile) || (!chainOk && canQuickSetupAll) ? (
<Button size="sm" className="w-full gap-1.5 rounded-md text-xs" render={<Link href="/dashboard/setup" />}>
<SparklesIcon className="size-3.5" />
<span>{t("setupWizard.preview.review")}</span>
</Button>
) : null}