Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion desktop/src/app/RootErrorBoundary.test.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import { after, afterEach, before, test } from "node:test";

Expand Down Expand Up @@ -77,7 +78,7 @@ test("root boundary shows recovery UI without exposing error details", async ()
createElement(RootErrorBoundary, null, createElement(ThrowingProvider)),
);

assert.ok(screen.getByText("Buzz failed to start"));
assert.ok(screen.getByText(`${PRODUCT_NAME} failed to start`));
assert.ok(screen.getByRole("button", { name: "Reload" }));
assert.equal(document.body.textContent.includes(diagnostic), false);
assert.match(document.body.textContent, /contact support/i);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import test from "node:test";

Expand Down Expand Up @@ -96,6 +97,10 @@ test("buildTranscript renders Prompt context + user message for a multi-block se
const promptContext = items.find((i) => i.title === "Prompt context");
assert.deepEqual(
promptContext.sections.map((s) => s.title),
// This frame carries the bracket form `[Buzz event: …]` that buzz-acp
// writes on the wire, so the section title is parsed from the text and
// keeps the protocol spelling. The XML form `<buzz-event>` is titled by
// `semanticTurnTitle` instead and renders under the product name.
["Agent Memory — core", "Context", "Buzz event: @mention"],
"every section header is counted",
);
Expand Down Expand Up @@ -146,7 +151,7 @@ test("buildTranscript preserves a slash-command preamble before semantic prompt
);
assert.deepEqual(
promptContext?.sections.map((section) => section.title),
["Prompt", "Context", "Buzz event: @mention"],
["Prompt", "Context", `${PRODUCT_NAME} event: @mention`],
);
assert.equal(promptContext?.sections[0]?.body, "/goal ship it");
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import test from "node:test";

Expand Down Expand Up @@ -35,7 +36,7 @@ test("parsePromptText wraps header-less free text in a single Prompt section", (
);
assert.equal(result.sections[0].body, "just some free text");
assert.equal(result.userText, "");
assert.equal(result.userTitle, "Buzz event");
assert.equal(result.userTitle, `${PRODUCT_NAME} event`);
assert.equal(result.userPubkey, null);
assert.equal(result.userEventId, null);
});
Expand Down Expand Up @@ -124,7 +125,7 @@ test("parsePromptText yields a null pubkey when From has no hex", () => {
test("parsePromptText defaults the title to 'Buzz event' when no kind is present", () => {
const text = ["[Buzz event]", "Content: x"].join("\n");
const result = parsePromptText(text);
assert.equal(result.userTitle, "Buzz event");
assert.equal(result.userTitle, `${PRODUCT_NAME} event`);
});

test("parsePromptText leading text before a header becomes a Prompt section", () => {
Expand Down Expand Up @@ -191,7 +192,10 @@ test("parsePromptText splits paired top-level turn sections and preserves inner
body: "[1] Alice (2026-08-25T12:00:00Z): prior message",
},
{
title: "Buzz event: @mention",
// `<buzz-event>` sections are titled by `semanticTurnTitle`, which
// renders under the product name; the bracket form above is parsed
// from buzz-acp's wire text and keeps the protocol spelling.
title: `${PRODUCT_NAME} event: @mention`,
body: "Event ID: abc123\nFrom: Alice (hex: AABBCC)\nContent: ship it",
},
]);
Expand Down
22 changes: 17 additions & 5 deletions desktop/src/features/agents/ui/agentSessionTranscriptHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import type { ObserverEvent, PromptSection } from "./agentSessionTypes";
import {
findBuzzToolName,
Expand Down Expand Up @@ -74,7 +75,18 @@ export function parsePromptText(text: string): {

const eventSection = sections.find((section) => {
const title = section.title.toLowerCase();
return title.startsWith("buzz event");
// Two different producers reach this matcher, and they do not agree on the
// product name. The wire tag is `buzz-event` and buzz-acp emits
// `[Buzz event: …]`; both are protocol surfaces this fork deliberately
// leaves unrenamed. `semanticTurnTitle` below renders the same section
// under the product name for display. Matching only one spelling silently
// yields no event section, which empties `userText` and drops the user's
// message from the transcript entirely -- the failure this accepts both to
// prevent.
return (
title.startsWith("buzz event") ||
title.startsWith(`${PRODUCT_NAME.toLowerCase()} event`)
);
});
const eventContent = eventSection
? extractEventContent(eventSection.body)
Expand All @@ -88,7 +100,7 @@ export function parsePromptText(text: string): {
return {
sections,
userText: eventContent,
userTitle: eventKind ? titleCase(eventKind) : "Dreamforge event",
userTitle: eventKind ? titleCase(eventKind) : `${PRODUCT_NAME} event`,
userPubkey: eventAuthorPubkey,
userEventId: eventId,
};
Expand Down Expand Up @@ -470,10 +482,10 @@ function semanticTurnTitle(
}
case "buzz-event":
return attributes.type
? `Dreamforge event: ${attributes.type}`
: "Dreamforge event";
? `${PRODUCT_NAME} event: ${attributes.type}`
: `${PRODUCT_NAME} event`;
case "buzz-events":
return `Dreamforge events — ${attributes.count} events`;
return `${PRODUCT_NAME} events — ${attributes.count} events`;
case "what-you-were-working-on":
return "What you were working on";
case "new-message-arrived-while-you-were-working":
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SHARED_COMPUTE_LABEL } from "@/shared/constants/brand";
/**
* Unit tests for the agent-dialog local-mode readiness gate.
*
Expand Down Expand Up @@ -860,7 +861,7 @@ test("providerDefaultLabel_globalSetWithWhitespace_trimsAndReturnsInherit", () =
test("providerDefaultLabel_sharedCompute_neverLeaksInternalId", () => {
assert.equal(
getDefaultLlmProviderLabel("buzz-agent", "relay-mesh"),
"Use agent defaults (Buzz shared compute)",
`Use agent defaults (${SHARED_COMPUTE_LABEL})`,
);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import test from "node:test";

Expand Down Expand Up @@ -125,7 +126,7 @@ test("approval and needs-action titles match the home-feed conventions", () => {
}),
{
title: "Needs Action",
body: "Something in Buzz needs your attention.",
body: `Something in ${PRODUCT_NAME} needs your attention.`,
},
);
});
Expand Down
6 changes: 5 additions & 1 deletion desktop/src/features/onboarding/welcomeCanvas.test.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import test from "node:test";

Expand All @@ -10,7 +11,10 @@ test("welcome canvas covers purpose, agent use, a first challenge, and help", ()
assert.match(WELCOME_CANVAS_CONTENT, /private channel is your home base/i);
assert.match(WELCOME_CANVAS_CONTENT, /Mention an agent/i);
assert.match(WELCOME_CANVAS_CONTENT, /quick challenge/i);
assert.match(WELCOME_CANVAS_CONTENT, /Buzz user guide/i);
assert.match(
WELCOME_CANVAS_CONTENT,
new RegExp(`${PRODUCT_NAME} user guide`, "i"),
);
});

test("ensureWelcomeCanvas seeds a fresh channel with no canvas", async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import test from "node:test";

Expand Down Expand Up @@ -84,7 +85,7 @@ test("prompt footer contains current page details", () => {
const footer = projectDetailAgentContextBlock(
buildProjectDetailAgentContext(base),
);
assert.match(footer, /Current Buzz project page:/);
assert.match(footer, new RegExp(`Current ${PRODUCT_NAME} project page:`));
assert.match(footer, /Repository: "Buzz" \(address: "owner:buzz"\)/);
assert.match(footer, /View: Files/);
assert.match(footer, /File: "src\/app\.tsx"/);
Expand Down
4 changes: 2 additions & 2 deletions desktop/src/features/projects/lib/projectGitError.test.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import { test } from "node:test";

Expand All @@ -13,8 +14,7 @@ test("explains unsupported authenticated GitHub clones without exposing git outp
),
{
title: "Repository access required",
description:
"This repository requires GitHub authentication. Buzz currently clones public GitHub repositories without credentials.",
description: `This repository requires GitHub authentication. ${PRODUCT_NAME} currently clones public GitHub repositories without credentials.`,
},
);
});
Expand Down
3 changes: 2 additions & 1 deletion desktop/src/features/terminal/TerminalBootstrap.test.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TERMINAL_LABEL } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import { after, afterEach, before, beforeEach, test } from "node:test";

Expand Down Expand Up @@ -378,7 +379,7 @@ test("opening a tab keeps terminal ownership while its attachment is pending", a
);

attachResolver = () => {};
fireEvent.click(view.getByLabelText("New Buzz Term tab"));
fireEvent.click(view.getByLabelText(`New ${TERMINAL_LABEL} tab`));
await waitFor(() => assert.equal(typeof attachResolver, "function"));
assert.equal(
substrate.dataset.terminalOwner,
Expand Down
9 changes: 5 additions & 4 deletions desktop/src/features/terminal/TerminalSubstrate.test.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TERMINAL_LABEL } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import { after, before, beforeEach, test } from "node:test";

Expand Down Expand Up @@ -219,7 +220,7 @@ test("tab actions restore terminal input focus", async () => {
const actions = [
["select", view.getByRole("tab")],
["close", view.getByLabelText("Close SHELL")],
["new", view.getByLabelText("New Buzz Term tab")],
["new", view.getByLabelText(`New ${TERMINAL_LABEL} tab`)],
];
for (const [label, target] of actions) {
target.focus();
Expand All @@ -237,7 +238,7 @@ test("drag resize batches visual updates and commits state only on release", asy
const { view } = fixture({ mode: "docked" });
await ready(view);
const substrate = view.container.querySelector(".buzz-terminal-substrate");
const handle = view.getByLabelText("Resize Buzz Term");
const handle = view.getByLabelText(`Resize ${TERMINAL_LABEL}`);

fireEvent.pointerDown(handle, { clientY: 500, pointerId: 1 });
fireEvent.pointerMove(handle, { clientY: 400, pointerId: 2 });
Expand Down Expand Up @@ -278,7 +279,7 @@ test("drag resize repaints the canvas without reporting PTY geometry until relea
const canvas = view.container.querySelector(
".buzz-terminal-viewport > canvas:not(.buzz-terminal-welcome)",
);
const handle = view.getByLabelText("Resize Buzz Term");
const handle = view.getByLabelText(`Resize ${TERMINAL_LABEL}`);
await waitFor(() => assert.equal(canvas.height, 280));
const reportsBeforeDrag = viewportSizes.length;

Expand All @@ -300,7 +301,7 @@ test("drag resize repaints the canvas without reporting PTY geometry until relea
test("unmount cancels a queued drag update", async () => {
const { view } = fixture({ mode: "docked" });
await ready(view);
const handle = view.getByLabelText("Resize Buzz Term");
const handle = view.getByLabelText(`Resize ${TERMINAL_LABEL}`);
const previousHeight = handle.closest(".buzz-terminal-substrate").style
.height;

Expand Down
11 changes: 6 additions & 5 deletions desktop/src/shared/lib/linkPreview.test.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRODUCT_NAME } from "@/shared/constants/brand";
import assert from "node:assert/strict";
import test from "node:test";

Expand Down Expand Up @@ -97,7 +98,7 @@ test("parseSupportedLinkPreview parses Buzz relay git clone URLs", () => {
{
kind: "buzz-repository",
href: `buzz://repo?owner=${BUZZ_OWNER}&d=buzz-world-galaxy`,
provider: "Buzz",
provider: PRODUCT_NAME,
title: "buzz-world-galaxy",
typeLabel: "repo",
},
Expand All @@ -120,7 +121,7 @@ test("parseSupportedLinkPreview strips .git suffix from clone URLs", () => {
{
kind: "buzz-repository",
href: `buzz://repo?owner=${BUZZ_OWNER}&d=buzz-world`,
provider: "Buzz",
provider: PRODUCT_NAME,
title: "buzz-world",
typeLabel: "repo",
},
Expand Down Expand Up @@ -186,7 +187,7 @@ test("parseSupportedLinkPreview parses buzz:// PR and issue deep links", () => {
{
kind: "buzz-pull-request",
href: `buzz://pr?id=${BUZZ_EVENT_ID}&owner=${BUZZ_OWNER}&d=buzz-world`,
provider: "Buzz",
provider: PRODUCT_NAME,
title: "buzz-world #c3b589fa",
typeLabel: "Review",
},
Expand All @@ -202,7 +203,7 @@ test("parseSupportedLinkPreview parses buzz:// PR and issue deep links", () => {
{
kind: "buzz-repository",
href: `buzz://repo?owner=${BUZZ_OWNER}&d=buzz-world`,
provider: "Buzz",
provider: PRODUCT_NAME,
title: "buzz-world",
typeLabel: "repo",
},
Expand All @@ -217,7 +218,7 @@ test("parseSupportedLinkPreview parses buzz:// project deep links", () => {
{
kind: "buzz-project",
href: `buzz://project?owner=${BUZZ_OWNER}&d=buzz-world`,
provider: "Buzz",
provider: PRODUCT_NAME,
title: "buzz-world",
typeLabel: "project",
},
Expand Down
13 changes: 10 additions & 3 deletions desktop/src/shared/lib/useDocumentVisible.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,16 @@ describe("visibility-gated hooks", () => {
focused = true;
await act(async () => window.dispatchEvent(new window.Event("focus")));
assert.deepEqual(observed, [1_000, false]);
await act(
async () => new Promise((resolve) => window.setTimeout(resolve, 10)),
);
// The resume is scheduled, not synchronous, so wait for it to land rather
// than for a fixed delay. A hardcoded sleep here is a race: it passes on a
// warm run and fails whenever the machine is busy or this file runs alone,
// which is a flake that costs more attention than the test is worth.
await act(async () => {
const deadline = Date.now() + 2_000;
while (observed.length < 3 && Date.now() < deadline) {
await new Promise((resolve) => window.setTimeout(resolve, 5));
}
});
assert.deepEqual(observed, [1_000, false, 1_000]);

await act(async () => root.unmount());
Expand Down
Loading