feat: add safe Gitea sync and signed updates
ForgeFlow quality gate / secret-scan (push) Failing after 32s
ForgeFlow quality gate / quality (push) Failing after 0s

This commit is contained in:
NuklearRabbit
2026-08-27 00:38:58 +02:00
parent cb9bdcd713
commit d47c7b5e41
46 changed files with 1658 additions and 246 deletions
+65
View File
@@ -121,6 +121,71 @@ Force repair after you have closed all Git tools for this repository?`)
}
setLoading(false);
render();
} else if (action === "preview-workspace-sync") {
if (!repository?.localPath) return;
setLoading(true, "Fetching Gitea and building a safe synchronization plan…");
try {
ui.workspaceSyncPlan = await window.forgeflow.previewWorkspaceSync(
repository.localPath,
);
ui.modal = { type: "workspace-sync" };
showToast(
ui.workspaceSyncPlan.needsSync
? "Workspace sync preview ready"
: "Workspace already synchronized",
ui.workspaceSyncPlan.needsSync
? `${ui.workspaceSyncPlan.summary.resultingTrackedChanges} tracked change(s) and ${ui.workspaceSyncPlan.summary.localFilesToStash} local file(s) reviewed.`
: `Local ${ui.workspaceSyncPlan.branch} already matches ${ui.workspaceSyncPlan.upstream}.`,
ui.workspaceSyncPlan.blockers?.length ? "error" : "success",
);
} catch (error) {
showToast("Could not preview Gitea sync", error.message, "error");
}
setLoading(false);
render();
} else if (action === "confirm-workspace-sync") {
if (!repository?.localPath || !ui.workspaceSyncPlan) return;
const expectedPlanId = target.dataset.planId;
setLoading(true, "Protecting local work and synchronizing exact Gitea state…");
try {
const result = await window.forgeflow.applyWorkspaceSync(
repository.localPath,
expectedPlanId,
);
ui.modal = null;
ui.workspaceSyncPlan = null;
await refreshRepositories(false);
[ui.branches, ui.stashes] = await Promise.all([
window.forgeflow.branches(repository.localPath),
window.forgeflow.stashList(repository.localPath),
]);
const recovery = [
result.backupBranch ? `recovery branch ${result.backupBranch}` : null,
result.stash ? `stash ${result.stash.ref}` : null,
].filter(Boolean).join(" and ");
showToast(
"Workspace synchronized with Gitea",
recovery
? `Local work is preserved in ${recovery}. Ignored runtime files were retained.`
: `Tracked files now match ${result.plan.upstream}; ignored runtime files were retained.`,
"success",
);
} catch (error) {
if (error.code === "WORKSPACE_SYNC_PLAN_STALE") {
try {
ui.workspaceSyncPlan = await window.forgeflow.previewWorkspaceSync(
repository.localPath,
);
ui.modal = { type: "workspace-sync" };
} catch {
ui.modal = null;
ui.workspaceSyncPlan = null;
}
}
showToast("Workspace synchronization stopped", error.message, "error");
}
setLoading(false);
render();
} else if (action === "repair-repository-sync") {
if (!repository?.localPath) return;
const strategy = target.dataset.strategy;