Make remote daemon update failures actionable (#2120)

* fix(settings): show daemon update failures

React Native web ignores Alert.alert, so failed remote updates reset to an enabled button without any user-visible explanation. Keep updater progress and failure as explicit rendered state, including the daemon's error, and cover the real browser-to-daemon failure path.

* test(settings): harden daemon update regression

* fix(settings): disable Desktop-managed daemon updates

Desktop-bundled daemons advertised npm self-update even though the install-origin checks always rejected it. Report Desktop ownership to clients, render actionable guidance, and refuse stale requests before touching npm.
This commit is contained in:
Mohamed Boudra
2026-07-16 21:04:31 +08:00
committed by GitHub
parent f4509fe044
commit 6aba0370ae
33 changed files with 531 additions and 92 deletions
@@ -1,5 +1,9 @@
import { describe, expect, test } from "vitest";
import { formatHostRuntimeSection, redactAppDiagnosticReport } from "./app-diagnostic-report";
import {
formatHostRuntimeSection,
formatServerInfoSection,
redactAppDiagnosticReport,
} from "./app-diagnostic-report";
import type { HostRuntimeSnapshot } from "@/runtime/host-runtime";
import type { HostProfile } from "@/types/host-connection";
@@ -41,6 +45,18 @@ function makeHost(): HostProfile {
}
describe("app diagnostics report", () => {
test("reports whether the connected daemon is managed by Paseo Desktop", () => {
const report = formatServerInfoSection({
status: "server_info",
serverId: "srv-desktop-managed",
hostname: "desktop-host.local",
version: "0.1.108",
desktopManaged: true,
});
expect(report).toContain("Desktop managed: yes");
});
test("formats connection rows without raw connection details", () => {
const host = makeHost();
const snapshot: HostRuntimeSnapshot = {
@@ -7,6 +7,11 @@ interface DiagnosticEntry {
value: string;
}
function formatDiagnosticBoolean(value: boolean | undefined): string {
if (value === undefined) return "unknown";
return value ? "yes" : "no";
}
export function formatDiagnosticSection(title: string, entries: DiagnosticEntry[]): string {
return [title, ...entries.map((entry) => ` ${entry.label}: ${entry.value}`)].join("\n");
}
@@ -77,6 +82,10 @@ export function formatServerInfoSection(serverInfo: ServerInfoStatusPayload | nu
{ label: "Server ID", value: serverInfo.serverId },
{ label: "Hostname", value: serverInfo.hostname ?? "unknown" },
{ label: "Version", value: serverInfo.version ?? "unknown" },
{
label: "Desktop managed",
value: formatDiagnosticBoolean(serverInfo.desktopManaged),
},
{ label: "Features", value: features.length > 0 ? features.join(", ") : "none" },
]);
}