Capture Board reference conversation replay

Co-authored-by: Larry <loganj+sbot-larry@squareup.com>
Signed-off-by: Logan Johnson <loganj@squareup.com>
This commit is contained in:
Logan Johnson
2026-08-20 01:32:39 +00:00
parent 797f1cdf89
commit e490776b63
3 changed files with 186 additions and 0 deletions

View File

@@ -28,6 +28,7 @@ export default defineConfig({
"**/navigation.spec.ts",
"**/channels.spec.ts",
"**/workstream-board-message-link.capture.spec.ts",
"**/workstream-board-context-references.capture.spec.ts",
"**/channel-shared-header-backdrop.spec.ts",
"**/channel-composer-overflow.spec.ts",
"**/badge.spec.ts",

View File

@@ -6904,6 +6904,7 @@ async function handleOpenDm(
pubkeys: string[];
expectedRelayUrl?: string | null;
expectedSignerPubkey?: string | null;
boardReferences?: Array<Record<string, unknown>> | null;
},
config: E2eConfig | undefined,
) {
@@ -9591,6 +9592,7 @@ async function handleSendChannelMessage(
suppressLinkPreviews?: boolean;
expectedRelayUrl?: string | null;
expectedSignerPubkey?: string | null;
boardReferences?: Array<Record<string, unknown>> | null;
},
config: E2eConfig | undefined,
): Promise<RawSendChannelMessageResponse> {
@@ -9666,6 +9668,11 @@ async function handleSendChannelMessage(
...linkPreviewTags,
...(args.sentFromThreadTag ? [args.sentFromThreadTag] : []),
...(args.suppressLinkPreviews ? [["link-preview", "none"]] : []),
...(args.boardReferences ?? []).map((reference) => [
"buzz:board-ref",
"1",
JSON.stringify(reference),
]),
];
const identity = getIdentity(config);
if (!identity) {
@@ -9796,6 +9803,7 @@ async function handleSendManagedAgentChannelMessage(
mentionPubkeys?: string[] | null;
parentEventId?: string | null;
additionalMarkers?: string[] | null;
boardReferences?: Array<Record<string, unknown>> | null;
},
_config: E2eConfig | undefined,
): Promise<RawSendChannelMessageResponse> {
@@ -9832,6 +9840,9 @@ async function handleSendManagedAgentChannelMessage(
args.mentionPubkeys ?? undefined,
agent.pubkey,
);
for (const reference of args.boardReferences ?? []) {
tags.push(["buzz:board-ref", "1", JSON.stringify(reference)]);
}
for (const clientMarker of [marker, ...(args.additionalMarkers ?? [])]) {
if (clientMarker?.trim()) tags.push(["client", clientMarker.trim()]);
}

View File

@@ -0,0 +1,174 @@
import { expect, test, type Page } from "@playwright/test";
import { installMockBridge } from "../helpers/bridge";
test.use({ video: "on" });
const CHANNEL_ID = "7b4d3d2e-3c15-4e88-9a11-1c0f7d2b6e55";
const ROOT_EVENT_ID = "c3".repeat(32);
const TARGET_EVENT_ID = "d4".repeat(32);
const AGENT_PUBKEY = "6".repeat(64);
const MESSAGE_LINK = `buzz://message?channel=${CHANNEL_ID}&id=${TARGET_EVENT_ID}&thread=${ROOT_EVENT_ID}`;
const CANVAS = `# Board context references demo
\`\`\`buzz-workstream-card
${JSON.stringify({
version: 1,
synopsis: "Discuss immutable Board context with humans and orchestrators.",
orchestrator: { pubkey: AGENT_PUBKEY, name: "Board Orchestrator" },
assignees: [{ pubkey: "7".repeat(64), name: "Field Agent" }],
pullRequests: ["https://github.com/block/buzz/pull/6357"],
waitingOn: [
{
key: "decision-thread",
actor: { kind: "person", name: "Logan", pubkey: "8".repeat(64) },
reason: "Decide the rollout in the cited thread",
since: "2026-08-19T21:00:00.000Z",
message: MESSAGE_LINK,
},
],
})}
\`\`\``;
type BoardReference = {
kind: "thread-blocker";
identity: string;
snapshot: { label: string; detail?: string };
placement: {
workstreamId: string;
workstreamLabel: string;
sectionId: string;
sectionLabel: string;
};
destination: {
channelId: string;
messageId: string;
threadRootId?: string;
};
};
async function invoke(
page: Page,
command: string,
payload: Record<string, unknown>,
) {
return page.evaluate(
async ({ command: target, payload: args }) => {
const fn = window.__BUZZ_E2E_INVOKE_MOCK_COMMAND__;
if (!fn) throw new Error("Mock invoke bridge is unavailable.");
return fn(target, args);
},
{ command, payload },
);
}
test("human and orchestrator references replay live and removed Board context", async ({
page,
}, testInfo) => {
test.setTimeout(90_000);
await installMockBridge(page, {
workstreamBoardFixture: {
channelId: CHANNEL_ID,
channelName: "loganj-ws-board-context",
canvas: CANVAS,
rootEventId: ROOT_EVENT_ID,
targetEventId: TARGET_EVENT_ID,
},
managedAgents: [
{
pubkey: AGENT_PUBKEY,
name: "Board Orchestrator",
channelIds: [CHANNEL_ID],
},
],
});
await page.goto("/", { waitUntil: "domcontentloaded" });
await expect(page.getByTestId("app-sidebar")).toBeVisible();
await page.getByTestId("open-workstream-board-view").click();
const board = page.getByTestId("workstream-board-view");
await expect(board).toBeVisible();
await board.getByRole("button", { name: "Discuss Board" }).click();
const options = page.getByTestId(`board-reference-options-${CHANNEL_ID}`);
await expect(options).toBeVisible();
await options.getByRole("button", { name: /workstream:/ }).click();
await options.getByRole("button", { name: /thread-blocker:/ }).click();
await expect(page.getByText("Reference tray (2)")).toBeVisible();
await page
.getByLabel("Discussion message")
.fill("Human: use this workstream and blocker context.");
await page.getByRole("button", { name: "Send", exact: true }).click();
const humanMessage = page.getByRole("button", {
name: /Human: use this workstream and blocker context\./,
});
await expect(humanMessage).toBeVisible();
await humanMessage.click();
await expect(page.getByTestId("board-discussion")).toContainText(
"Replay 1/2: 2 live",
);
await expect(page.getByTestId(`workstream-card-${CHANNEL_ID}`)).toHaveClass(
/ring-2/,
);
await page.screenshot({
path: testInfo.outputPath("human-live-replay.png"),
fullPage: true,
});
await page.waitForTimeout(1_500);
const removedReference: BoardReference = {
kind: "thread-blocker",
identity: "removed-deployment-gate",
snapshot: {
label: "Removed deployment approval",
detail: "Release captain",
},
placement: {
workstreamId: CHANNEL_ID,
workstreamLabel: "loganj-ws-board-context",
sectionId: "blockers",
sectionLabel: "Blockers",
},
destination: {
channelId: CHANNEL_ID,
messageId: TARGET_EVENT_ID,
threadRootId: ROOT_EVENT_ID,
},
};
await invoke(page, "send_managed_agent_channel_message", {
agentPubkey: AGENT_PUBKEY,
channelId: CHANNEL_ID,
content:
"Orchestrator: this points to the approval removed after state advanced.",
marker: "board-context-orchestrator",
boardReferences: [removedReference],
});
// Open the workstream conversation, where the orchestrator-authored live
// event renders its machine-readable reference chip. Clicking the chip
// carries immutable replay state back to the Board.
await options.getByRole("button", { name: "Open", exact: true }).click();
await expect(page).toHaveURL(new RegExp(`/channels/${CHANNEL_ID}`));
const orchestratorRow = page.getByText(
"Orchestrator: this points to the approval removed after state advanced.",
);
await expect(orchestratorRow).toBeVisible();
const orchestratorMessage = orchestratorRow.locator(
"xpath=ancestor::*[@data-testid='message-row']",
);
await orchestratorMessage.getByTestId("message-board-references").click();
await expect(page).toHaveURL(/\/workstreams$/);
await expect(page.getByTestId("workstream-board-view")).toBeVisible();
await expect(page.getByTestId("board-discussion")).toContainText(
"Replay 1/1: 0 live · 0 changed · 1 historical",
);
await expect(page.getByText("Historical references")).toBeVisible();
await expect(
page.getByText(/Removed deployment approval · formerly/),
).toContainText("loganj-ws-board-context / Blockers");
await page.screenshot({
path: testInfo.outputPath("orchestrator-removed-replay.png"),
fullPage: true,
});
await page.waitForTimeout(2_500);
});