Make dashboard update actions report clear terminal outcomes and avoid unsupported installs. - Distinguish update checks, no-op responses, installation failures, and unsupported installation methods. - Block source-checkout, Homebrew, and missing-npm global installation attempts with actionable guidance. - Surface update results in dashboard controls and cover API, updater, and UI behavior with tests. Files changed: .changeset/fn-9042-update-now-outcomes.md | 7 ++ docs/dashboard-guide.md | 2 +- docs/settings-reference.md | 2 +- packages/dashboard/app/api/settings/settings.ts | 2 + .../dashboard/app/components/SettingsModal.tsx | 18 +-- .../app/components/UpdateAvailableBanner.tsx | 11 +- .../__tests__/SettingsModal.general.test.tsx | 20 ++++ .../__tests__/UpdateAvailableBanner.test.tsx | 19 ++++ .../dashboard/src/__tests__/auto-update.test.ts | 38 ++++++- .../dashboard/src/__tests__/update-check.test.ts | 19 +++- packages/dashboard/src/auto-update.ts | 33 +++++- .../__tests__/register-update-check-routes.test.ts | 104 ++++++++++++++++++ .../src/routes/register-update-check-routes.ts | 28 +++-- packages/dashboard/src/server.ts | 9 +- packages/dashboard/src/update-check.ts | 122 ++++++++++----------- 15 files changed, 338 insertions(+), 96 deletions(-) Fusion-Task-Id: FN-9042 Fusion-Task-Lineage: 22ae5540-e5b5-43cf-ad16-c7aa05782593 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
59 lines
2.2 KiB
TypeScript
59 lines
2.2 KiB
TypeScript
/**
|
|
* FNXC:CodeOrganization 2026-07-16-14:00:
|
|
* Settings/config/update client API peeled from legacy.ts.
|
|
*/
|
|
import type { Settings } from "@fusion/core";
|
|
import { api } from "../client/client.js";
|
|
import type { FetchOptions } from "../client/client.js";
|
|
import { withProjectId } from "../client/health.js";
|
|
import type { UpdateCheckResponse } from "../client/health.js";
|
|
import { dedupe } from "../client/dedupe.js";
|
|
|
|
export function fetchConfig(projectId?: string): Promise<{ maxConcurrent: number; rootDir: string }> {
|
|
const path = withProjectId("/config", projectId);
|
|
return dedupe(path, () => api<{ maxConcurrent: number; rootDir: string }>(path));
|
|
}
|
|
|
|
export function fetchSettings(projectId?: string, options?: FetchOptions): Promise<Settings> {
|
|
const path = withProjectId("/settings", projectId);
|
|
return dedupe(path, () => api<Settings>(path), options);
|
|
}
|
|
|
|
export function fetchTaskEffectiveSettings(taskId: string, projectId?: string, options?: FetchOptions): Promise<Settings> {
|
|
const path = withProjectId(`/tasks/${taskId}/effective-settings`, projectId);
|
|
return dedupe(path, () => api<Settings>(path), options);
|
|
}
|
|
|
|
export function updateSettings(settings: Partial<Settings>, projectId?: string): Promise<Settings> {
|
|
return api<Settings>(withProjectId("/settings", projectId), {
|
|
method: "PUT",
|
|
body: JSON.stringify(settings),
|
|
});
|
|
}
|
|
|
|
export function checkForUpdate(projectId?: string): Promise<UpdateCheckResponse> {
|
|
return api<UpdateCheckResponse>(withProjectId("/update-check", projectId));
|
|
}
|
|
|
|
export function refreshUpdateCheck(projectId?: string): Promise<UpdateCheckResponse> {
|
|
return api<UpdateCheckResponse>(withProjectId("/update-check/refresh", projectId), {
|
|
method: "POST",
|
|
});
|
|
}
|
|
|
|
export interface UpdateInstallResponse {
|
|
currentVersion: string;
|
|
latestVersion: string | null;
|
|
updated: boolean;
|
|
outcome?: "installed" | "no-update-available" | "check-failed" | "unsupported-install-method" | "failed";
|
|
message?: string;
|
|
error?: string;
|
|
}
|
|
|
|
export function installUpdate(projectId?: string): Promise<UpdateInstallResponse> {
|
|
return api<UpdateInstallResponse>(withProjectId("/update-check/install", projectId), {
|
|
method: "POST",
|
|
});
|
|
}
|
|
|