mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-19 01:04:32 +00:00
Rename Foundry handoffs to tasks (#239)
* Restore foundry onboarding stack * Consolidate foundry rename * Create foundry tasks without prompts * Rename Foundry handoffs to tasks
This commit is contained in:
parent
d30cc0bcc8
commit
d75e8c31d1
281 changed files with 9242 additions and 4356 deletions
84
foundry/packages/frontend/src/features/tasks/model.test.ts
Normal file
84
foundry/packages/frontend/src/features/tasks/model.test.ts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import type { TaskRecord } from "@sandbox-agent/foundry-shared";
|
||||
import { formatDiffStat, groupTasksByRepo } from "./model";
|
||||
|
||||
const base: TaskRecord = {
|
||||
workspaceId: "default",
|
||||
repoId: "repo-a",
|
||||
repoRemote: "https://example.com/repo-a.git",
|
||||
taskId: "task-1",
|
||||
branchName: "feature/one",
|
||||
title: "Feature one",
|
||||
task: "Ship one",
|
||||
providerId: "daytona",
|
||||
status: "running",
|
||||
statusMessage: null,
|
||||
activeSandboxId: "sandbox-1",
|
||||
activeSessionId: "session-1",
|
||||
sandboxes: [
|
||||
{
|
||||
sandboxId: "sandbox-1",
|
||||
providerId: "daytona",
|
||||
sandboxActorId: null,
|
||||
switchTarget: "daytona://sandbox-1",
|
||||
cwd: null,
|
||||
createdAt: 10,
|
||||
updatedAt: 10,
|
||||
},
|
||||
],
|
||||
agentType: null,
|
||||
prSubmitted: false,
|
||||
diffStat: null,
|
||||
prUrl: null,
|
||||
prAuthor: null,
|
||||
ciStatus: null,
|
||||
reviewStatus: null,
|
||||
reviewer: null,
|
||||
conflictsWithMain: null,
|
||||
hasUnpushed: null,
|
||||
parentBranch: null,
|
||||
createdAt: 10,
|
||||
updatedAt: 10,
|
||||
};
|
||||
|
||||
describe("groupTasksByRepo", () => {
|
||||
it("groups by repo and sorts by recency", () => {
|
||||
const rows: TaskRecord[] = [
|
||||
{ ...base, taskId: "h1", repoId: "repo-a", repoRemote: "https://example.com/repo-a.git", updatedAt: 10 },
|
||||
{ ...base, taskId: "h2", repoId: "repo-a", repoRemote: "https://example.com/repo-a.git", updatedAt: 50 },
|
||||
{ ...base, taskId: "h3", repoId: "repo-b", repoRemote: "https://example.com/repo-b.git", updatedAt: 30 },
|
||||
];
|
||||
|
||||
const groups = groupTasksByRepo(rows);
|
||||
expect(groups).toHaveLength(2);
|
||||
expect(groups[0]?.repoId).toBe("repo-a");
|
||||
expect(groups[0]?.tasks[0]?.taskId).toBe("h2");
|
||||
});
|
||||
|
||||
it("sorts repo groups by latest task activity first", () => {
|
||||
const rows: TaskRecord[] = [
|
||||
{ ...base, taskId: "h1", repoId: "repo-z", repoRemote: "https://example.com/repo-z.git", updatedAt: 200 },
|
||||
{ ...base, taskId: "h2", repoId: "repo-a", repoRemote: "https://example.com/repo-a.git", updatedAt: 100 },
|
||||
];
|
||||
|
||||
const groups = groupTasksByRepo(rows);
|
||||
expect(groups[0]?.repoId).toBe("repo-z");
|
||||
expect(groups[1]?.repoId).toBe("repo-a");
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatDiffStat", () => {
|
||||
it("returns No changes for zero-diff values", () => {
|
||||
expect(formatDiffStat("+0/-0")).toBe("No changes");
|
||||
expect(formatDiffStat("+0 -0")).toBe("No changes");
|
||||
});
|
||||
|
||||
it("returns dash for empty values", () => {
|
||||
expect(formatDiffStat(null)).toBe("-");
|
||||
expect(formatDiffStat("")).toBe("-");
|
||||
});
|
||||
|
||||
it("keeps non-empty non-zero diff stats", () => {
|
||||
expect(formatDiffStat("+12/-4")).toBe("+12/-4");
|
||||
});
|
||||
});
|
||||
50
foundry/packages/frontend/src/features/tasks/model.ts
Normal file
50
foundry/packages/frontend/src/features/tasks/model.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import type { TaskRecord } from "@sandbox-agent/foundry-shared";
|
||||
|
||||
export interface RepoGroup {
|
||||
repoId: string;
|
||||
repoRemote: string;
|
||||
tasks: TaskRecord[];
|
||||
}
|
||||
|
||||
export function groupTasksByRepo(tasks: TaskRecord[]): RepoGroup[] {
|
||||
const groups = new Map<string, RepoGroup>();
|
||||
|
||||
for (const task of tasks) {
|
||||
const group = groups.get(task.repoId);
|
||||
if (group) {
|
||||
group.tasks.push(task);
|
||||
continue;
|
||||
}
|
||||
|
||||
groups.set(task.repoId, {
|
||||
repoId: task.repoId,
|
||||
repoRemote: task.repoRemote,
|
||||
tasks: [task],
|
||||
});
|
||||
}
|
||||
|
||||
return Array.from(groups.values())
|
||||
.map((group) => ({
|
||||
...group,
|
||||
tasks: [...group.tasks].sort((a, b) => b.updatedAt - a.updatedAt),
|
||||
}))
|
||||
.sort((a, b) => {
|
||||
const aLatest = a.tasks[0]?.updatedAt ?? 0;
|
||||
const bLatest = b.tasks[0]?.updatedAt ?? 0;
|
||||
if (aLatest !== bLatest) {
|
||||
return bLatest - aLatest;
|
||||
}
|
||||
return a.repoRemote.localeCompare(b.repoRemote);
|
||||
});
|
||||
}
|
||||
|
||||
export function formatDiffStat(diffStat: string | null | undefined): string {
|
||||
const normalized = diffStat?.trim();
|
||||
if (!normalized) {
|
||||
return "-";
|
||||
}
|
||||
if (normalized === "+0/-0" || normalized === "+0 -0" || normalized === "0 files changed") {
|
||||
return "No changes";
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue