mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
fix(agents): refresh edited shared instruction previews
Invalidate cached detail when a replaceable note gets a new event ID, and cover the edit-preview-edit path end to end. Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
@@ -60,6 +60,10 @@ export function RelaySkillPreviewButton({
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [previewState, setPreviewState] = React.useState<PreviewState>("idle");
|
||||
const [detail, setDetail] = React.useState<ResolvedRelaySkill | null>(null);
|
||||
const currentDetail =
|
||||
detail?.coordinate === skill.coordinate && detail.eventId === skill.eventId
|
||||
? detail
|
||||
: null;
|
||||
const contentRef = React.useRef<HTMLDivElement | null>(null);
|
||||
const hoverTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(
|
||||
null,
|
||||
@@ -140,7 +144,7 @@ export function RelaySkillPreviewButton({
|
||||
}, [clearHoverTimer, closeWithDelay, open]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!open || detail?.coordinate === skill.coordinate) {
|
||||
if (!open || currentDetail) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,10 +165,10 @@ export function RelaySkillPreviewButton({
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [detail?.coordinate, open, skill.coordinate]);
|
||||
}, [currentDetail, open, skill.coordinate]);
|
||||
|
||||
const displayTitle = detail?.title || skill.title || skill.slug;
|
||||
const displaySummary = detail?.summary || skill.summary;
|
||||
const displayTitle = currentDetail?.title || skill.title || skill.slug;
|
||||
const displaySummary = currentDetail?.summary || skill.summary;
|
||||
const focusPreviewOnTab = (event: React.KeyboardEvent<HTMLElement>) => {
|
||||
if (event.key !== "Tab" || event.shiftKey || !open) return;
|
||||
event.preventDefault();
|
||||
@@ -271,14 +275,14 @@ export function RelaySkillPreviewButton({
|
||||
<div className="flex items-center gap-2 text-xs font-medium text-muted-foreground">
|
||||
<BookOpen className="h-4 w-4" /> Shared instruction
|
||||
</div>
|
||||
{onEdit && detail?.editable ? (
|
||||
{onEdit && currentDetail?.editable ? (
|
||||
<Button
|
||||
className="h-7 gap-1.5 px-2 text-xs"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
setOpen(false);
|
||||
onEdit(detail);
|
||||
onEdit(currentDetail);
|
||||
}}
|
||||
size="sm"
|
||||
type="button"
|
||||
@@ -310,9 +314,9 @@ export function RelaySkillPreviewButton({
|
||||
replaced.
|
||||
</p>
|
||||
) : null}
|
||||
{detail ? (
|
||||
{currentDetail ? (
|
||||
<pre className="whitespace-pre-wrap break-words font-mono text-xs leading-5 text-foreground">
|
||||
{detail.content}
|
||||
{currentDetail.content}
|
||||
</pre>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -14034,14 +14034,40 @@ export function maybeInstallE2eTauriMocks() {
|
||||
}
|
||||
).input;
|
||||
const [, publisher = "", slug = ""] = input.coordinate.split(":", 3);
|
||||
const eventId = "de".repeat(32);
|
||||
const updatedAt = 1_700_000_001;
|
||||
const mock = getConfig()?.mock;
|
||||
const cover = mock?.relaySkills?.find(
|
||||
(candidate) => candidate.coordinate === input.coordinate,
|
||||
);
|
||||
if (cover) {
|
||||
Object.assign(cover, {
|
||||
title: input.title,
|
||||
summary: input.summary,
|
||||
eventId,
|
||||
updatedAt,
|
||||
});
|
||||
}
|
||||
const detail = mock?.relaySkillDetails?.find(
|
||||
(candidate) => candidate.coordinate === input.coordinate,
|
||||
);
|
||||
if (detail) {
|
||||
Object.assign(detail, {
|
||||
title: input.title,
|
||||
summary: input.summary,
|
||||
content: input.instructions,
|
||||
eventId,
|
||||
updatedAt,
|
||||
});
|
||||
}
|
||||
return {
|
||||
coordinate: input.coordinate,
|
||||
publisher,
|
||||
slug,
|
||||
title: input.title,
|
||||
summary: input.summary,
|
||||
eventId: "de".repeat(32),
|
||||
updatedAt: 1_700_000_001,
|
||||
eventId,
|
||||
updatedAt,
|
||||
compatible: true,
|
||||
incompatibilities: [],
|
||||
};
|
||||
|
||||
@@ -1058,6 +1058,21 @@ test("shared instruction editing is author-only and does not leak into creation"
|
||||
await editDialog.getByRole("button", { name: "Save changes" }).click();
|
||||
await expect(editDialog).toBeHidden();
|
||||
|
||||
await personaDialog
|
||||
.getByRole("button", { name: "Add shared instructions" })
|
||||
.click();
|
||||
await page.getByRole("menuitemcheckbox", { name: /Design review/ }).hover();
|
||||
const refreshedPreview = page.getByRole("region", {
|
||||
name: "Design review shared instruction preview",
|
||||
});
|
||||
await expect(refreshedPreview).toContainText(
|
||||
"Review interface decisions against product intent and evidence.",
|
||||
);
|
||||
await refreshedPreview.getByRole("button", { name: "Edit" }).click();
|
||||
await editDialog.locator("#relay-skill-title").fill("Design review v2");
|
||||
await editDialog.getByRole("button", { name: "Save changes" }).click();
|
||||
await expect(editDialog).toBeHidden();
|
||||
|
||||
const updateInput = await page.evaluate(() => {
|
||||
const call = [...(window.__BUZZ_E2E_COMMAND_PAYLOADS__ ?? [])]
|
||||
.reverse()
|
||||
@@ -1076,13 +1091,10 @@ test("shared instruction editing is author-only and does not leak into creation"
|
||||
| undefined
|
||||
)?.input;
|
||||
});
|
||||
expect(updateInput).toEqual({
|
||||
expect(updateInput).toMatchObject({
|
||||
coordinate: ownedCoordinate,
|
||||
expectedEventId: "a1".repeat(32),
|
||||
title: "Design review",
|
||||
summary: "Use when reviewing interface decisions.",
|
||||
instructions:
|
||||
"Review interface decisions against product intent and evidence.",
|
||||
expectedEventId: "de".repeat(32),
|
||||
title: "Design review v2",
|
||||
});
|
||||
|
||||
await personaDialog
|
||||
|
||||
Reference in New Issue
Block a user