Improve queued comment thread UX

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta 2026-03-28 11:25:25 -05:00
parent 4226e15128
commit 74687553f3
4 changed files with 331 additions and 107 deletions

View file

@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
import {
applyOptimisticIssueCommentUpdate,
createOptimisticIssueComment,
isQueuedIssueComment,
mergeIssueComments,
upsertIssueComment,
} from "./optimistic-issue-comments";
@ -46,6 +47,20 @@ describe("optimistic issue comments", () => {
mathSpy.mockRestore();
});
it("supports queued optimistic comments for active-run follow-ups", () => {
const comment = createOptimisticIssueComment({
companyId: "company-1",
issueId: "issue-1",
body: "Queue this",
authorUserId: "board-1",
clientStatus: "queued",
queueTargetRunId: "run-1",
});
expect(comment.clientStatus).toBe("queued");
expect(comment.queueTargetRunId).toBe("run-1");
});
it("merges optimistic comments into the server thread in chronological order", () => {
const merged = mergeIssueComments(
[
@ -161,4 +176,40 @@ describe("optimistic issue comments", () => {
expect(next?.assigneeAgentId).toBeNull();
expect(next?.assigneeUserId).toBe("board-2");
});
it("treats comments without a run id as queued when they arrive during an active run", () => {
expect(
isQueuedIssueComment({
comment: {
createdAt: new Date("2026-03-28T16:20:05.000Z"),
},
activeRunStartedAt: new Date("2026-03-28T16:20:00.000Z"),
runId: null,
}),
).toBe(true);
});
it("does not mark comments with an associated run as queued", () => {
expect(
isQueuedIssueComment({
comment: {
createdAt: new Date("2026-03-28T16:20:05.000Z"),
},
activeRunStartedAt: new Date("2026-03-28T16:20:00.000Z"),
runId: "run-1",
}),
).toBe(false);
});
it("does not mark interrupt comments as queued", () => {
expect(
isQueuedIssueComment({
comment: {
createdAt: new Date("2026-03-28T16:20:05.000Z"),
},
activeRunStartedAt: new Date("2026-03-28T16:20:00.000Z"),
interruptedRunId: "run-1",
}),
).toBe(false);
});
});