feat(FN-5358): add smart pull API route with stash conflict detection and r

Implements stash conflict detection and resolution with a new smart pull API route, resolution endpoints, and a dedicated conflict modal UI — backed by extended git audit taxonomy and route tests.

Fusion-Task-Id: FN-5358
This commit is contained in:
Fusion (runfusion.ai)
2026-05-21 17:46:10 -07:00
committed by gsxdsm
parent 50a5ddd4fb
commit 921e0e616f
11 changed files with 1422 additions and 52 deletions

View File

@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import type { TaskStore, RunAuditEventInput } from "@fusion/core";
import { createRunAuditor, type DatabaseMutationType } from "../run-audit.js";
import { createRunAuditor, type DatabaseMutationType, type GitMutationType } from "../run-audit.js";
class AuditStoreStub {
events: RunAuditEventInput[] = [];
@@ -88,6 +88,18 @@ describe("run-audit provisioning mutation types", () => {
]);
});
it("accepts smart-pull git mutation types", async () => {
const store = new AuditStoreStub();
const auditor = createRunAuditor(store as unknown as TaskStore, { runId: "r1", agentId: "a1", taskId: "FN-5358" });
const types: GitMutationType[] = ["pull:fast-forward", "stash:pop-conflict"];
for (const type of types) {
await auditor.git({ type, target: "feature/worktree", metadata: { taskId: "FN-5358" } });
}
expect(store.events.map((event) => event.mutationType)).toEqual(types);
});
it("records merge:scope:auto-widen git events", async () => {
const store = new AuditStoreStub();
const auditor = createRunAuditor(store as unknown as TaskStore, { runId: "r1", agentId: "a1", taskId: "FN-5226" });

View File

@@ -228,8 +228,62 @@ export type GitMutationType =
// reserved; refusal currently thrown pre-audit
| "project:bootstrap-refused-linked-worktree"
| "branch:reanchor"
/**
* Metadata shape:
* ```ts
* {
* taskId?: string;
* worktreePath: string;
* stashSha: string;
* stashLabel: string;
* untrackedIncluded: true;
* }
* ```
*/
| "stash:push"
| "stash:pop";
/**
* Metadata shape:
* ```ts
* {
* taskId?: string;
* worktreePath: string;
* stashSha: string;
* stashLabel: string;
* manualResolution?: boolean;
* }
* ```
*/
| "stash:pop"
/**
* Metadata shape:
* ```ts
* {
* taskId?: string;
* worktreePath: string;
* integrationBranch: string;
* fromSha: string;
* toSha: string;
* durationMs: number;
* succeeded: boolean;
* error?: string;
* }
* ```
*/
| "pull:fast-forward"
/**
* Metadata shape:
* ```ts
* {
* taskId?: string;
* worktreePath: string;
* stashSha: string;
* stashLabel: string;
* conflictedFiles: string[];
* advice: string;
* }
* ```
*/
| "stash:pop-conflict";
// ── Database mutation types ────────────────────────────────────────────────────