Build your profile
Add a name and avatar. They’ll show up on your messages,
@@ -468,66 +493,67 @@ export function CommunityOnboardingFlow({
Meet your starter team
Buzz lets you bring multiple agents into the same workspace.
- This team will help you get started using Buzz.
+ Your team will help you get started using Buzz.
- {starterPersonas.length > 0 ? (
-
- {starterPersonas.map((persona) => {
- const animationUrl =
- STARTER_PERSONA_ANIMATIONS[persona.displayName];
- return (
-
- {animationUrl ? (
-
- ) : (
-
- )}
-
- {persona.displayName}
-
-
- );
- })}
-
- ) : null}
+
+ {starterPersonas.length > 0 ? (
+
+ {starterPersonas.map((persona) => {
+ const animationUrl =
+ STARTER_PERSONA_ANIMATIONS[persona.displayName];
+ return (
+
+ {animationUrl ? (
+
+ ) : (
+
+ )}
+
+ {persona.displayName}
+
+
+ );
+ })}
+
+ ) : null}
+
{transaction.error ? (
-
- {transaction.error}
-
+
{transaction.error}
) : null}
void finalize()}
>
- {transaction.stage === "finalizing" ||
- transaction.stage === "entering"
- ? "Preparing Welcome…"
- : `Enter ${transaction.communityName}`}
+ {isPending || transaction.stage === "entering" ? (
+
+ ) : (
+ "Take me to Buzz"
+ )}
+
+
+ Back
- {transaction.error ? (
- void finish()}
- variant="ghost"
- >
- Skip for now
-
- ) : null}
>
)}
diff --git a/desktop/tests/e2e/deep-link-invite.spec.ts b/desktop/tests/e2e/deep-link-invite.spec.ts
index efd3d9337..e8d45ba3c 100644
--- a/desktop/tests/e2e/deep-link-invite.spec.ts
+++ b/desktop/tests/e2e/deep-link-invite.spec.ts
@@ -243,7 +243,7 @@ test("queued add-community links open and acknowledge one at a time", async ({
]);
});
-test("Welcome failure can be skipped without abandoning community onboarding", async ({
+test("Welcome failure can go back without abandoning community onboarding", async ({
page,
}) => {
const welcomeError = "Channel creation is not permitted.";
@@ -291,30 +291,26 @@ test("Welcome failure can be skipped without abandoning community onboarding", a
);
}
- await page.getByRole("button", { name: "Enter hive" }).click();
+ await page.getByRole("button", { name: "Take me to Buzz" }).click();
await expect(page.getByText(welcomeError)).toBeVisible();
await expect(
- page.getByRole("button", { name: "Preparing Welcome…" }),
+ page.getByRole("button", { name: "Take me to Buzz" }),
).toBeEnabled();
- const skip = page.getByRole("button", { name: "Skip for now" });
- await expect(skip).toBeVisible();
- await skip.click();
+ await expect(page.getByRole("button", { name: "Back" })).toBeVisible();
+ await page.getByRole("button", { name: "Back" }).click();
- const completionKey = `buzz-community-onboarding-complete.v1:${encodeURIComponent(COMMUNITY_RELAY_URL)}:${WELCOME_FAILURE_PUBKEY}`;
+ await expect(
+ page.getByRole("heading", { name: "Build your profile" }),
+ ).toBeVisible();
await expect
.poll(() =>
page.evaluate(
- ({ completion, transaction }) => ({
- completion: window.localStorage.getItem(completion),
- transaction: window.localStorage.getItem(transaction),
- }),
- { completion: completionKey, transaction: TRANSACTION_STORAGE_KEY },
+ (transaction) => window.localStorage.getItem(transaction),
+ TRANSACTION_STORAGE_KEY,
),
)
- .toEqual({ completion: "true", transaction: null });
- await expect(page.getByTestId("community-onboarding-flow")).toHaveCount(0);
- await expect(page.getByTestId("app-sidebar")).toBeVisible();
+ .toContain('"stage":"profile"');
});
test("persisted deep-link invite hands off to Joining after machine onboarding", async ({
diff --git a/desktop/tests/e2e/onboarding.spec.ts b/desktop/tests/e2e/onboarding.spec.ts
index f620df928..b6749bf66 100644
--- a/desktop/tests/e2e/onboarding.spec.ts
+++ b/desktop/tests/e2e/onboarding.spec.ts
@@ -985,18 +985,15 @@ test("connected first-community profile step cannot discard resumable onboarding
await expect(
page.getByRole("heading", { name: "Build your profile" }),
).toBeVisible();
- const profileMain = page.getByTestId("community-profile-main");
- const profileMainBox = await profileMain.boundingBox();
- const viewport = page.viewportSize();
- if (!profileMainBox || !viewport) {
- throw new Error("Could not measure community profile body position");
+ const profileHeading = page.getByRole("heading", {
+ name: "Build your profile",
+ });
+ await expect(profileHeading).toBeVisible();
+ const profileHeadingBox = await profileHeading.boundingBox();
+ if (!profileHeadingBox) {
+ throw new Error("Could not measure community profile heading position");
}
- const chromeOffset = 106;
- const footerOffset = 144;
- const profileMainCenterY = profileMainBox.y + profileMainBox.height / 2;
- const centeredInUsableLaneY =
- chromeOffset + (viewport.height - chromeOffset - footerOffset) / 2;
- expect(Math.abs(profileMainCenterY - centeredInUsableLaneY)).toBeLessThan(32);
+ expect(Math.abs(profileHeadingBox.y - 106)).toBeLessThan(8);
const nameKey = page.getByTestId("community-profile-name-key");
const avatarButton = page.getByTestId("community-avatar-open");
await expect(nameKey).toBeVisible();
From 19d8ac2341e372b4451df3542208c66672992ab2 Mon Sep 17 00:00:00 2001
From: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3
<29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co>
Date: Sat, 18 Jul 2026 21:47:13 -0700
Subject: [PATCH 2/2] fix(desktop): allow skipping failed starter setup
Co-authored-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co>
---
.../onboarding/ui/CommunityOnboardingFlow.tsx | 17 +++++-
desktop/tests/e2e/deep-link-invite.spec.ts | 53 +++++++++++++++----
2 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx b/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx
index 02518fb26..25443ecd3 100644
--- a/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx
+++ b/desktop/src/features/onboarding/ui/CommunityOnboardingFlow.tsx
@@ -146,6 +146,8 @@ export function CommunityOnboardingFlow({
[],
);
const [isPending, setIsPending] = React.useState(false);
+ const [starterChannelFailureCount, setStarterChannelFailureCount] =
+ React.useState(0);
const [deniedPubkey, setDeniedPubkey] = React.useState("");
const [isMembershipDenied, setIsMembershipDenied] = React.useState(false);
const [isCommunityChangeOpen, setIsCommunityChangeOpen] =
@@ -248,6 +250,7 @@ export function CommunityOnboardingFlow({
}
await finish();
} catch (error) {
+ setStarterChannelFailureCount((count) => count + 1);
update({
error: error instanceof Error ? error.message : String(error),
});
@@ -257,6 +260,7 @@ export function CommunityOnboardingFlow({
const backToProfile = React.useCallback(() => {
if (isPending) return;
+ setStarterChannelFailureCount(0);
update({ stage: "profile", error: undefined });
}, [isPending, update]);
@@ -530,17 +534,26 @@ export function CommunityOnboardingFlow({
) : null}
+ {transaction.error}
+ {starterChannelFailureCount === 1 ? " Try again." : null}
+