diff --git a/frontend/src/renderer/__tests__/integration/board-empty-states.test.tsx b/frontend/src/renderer/__tests__/integration/board-empty-states.test.tsx
index ac1d9a570..1403a7474 100644
--- a/frontend/src/renderer/__tests__/integration/board-empty-states.test.tsx
+++ b/frontend/src/renderer/__tests__/integration/board-empty-states.test.tsx
@@ -118,6 +118,8 @@ describe("global board first launch", () => {
expect(screen.getByText("Describe a task")).toBeInTheDocument();
expect(screen.getByText("Ready to merge")).toBeInTheDocument();
expect(columnCount()).toBe(0);
+ // The welcome carries its own orientation — no dangling "Board" header.
+ expect(screen.queryByText("Board")).not.toBeInTheDocument();
});
it("opens the native folder picker from the welcome CTA", async () => {
@@ -154,7 +156,7 @@ describe("project board with no sessions", () => {
respondWith([project], []);
renderBoard();
- expect(await screen.findByText("No sessions yet")).toBeInTheDocument();
+ expect(await screen.findByText("No worker sessions yet")).toBeInTheDocument();
// Board header + empty state each offer the pair; the orchestrator is primary in both.
expect(screen.getAllByRole("button", { name: "Spawn Orchestrator" }).length).toBeGreaterThan(0);
expect(screen.getAllByRole("button", { name: "New task" }).length).toBeGreaterThan(0);
@@ -167,7 +169,7 @@ describe("project board with no sessions", () => {
spawnOrchestratorMock.mockRejectedValue(new Error("branch is already checked out in another worktree"));
renderBoard();
- await screen.findByText("No sessions yet");
+ await screen.findByText("No worker sessions yet");
const [spawnButton] = screen.getAllByRole("button", { name: "Spawn Orchestrator" });
await userEvent.click(spawnButton);
@@ -229,7 +231,7 @@ describe("project board with no sessions", () => {
,
);
- await screen.findByText("No sessions yet");
+ await screen.findByText("No worker sessions yet");
await waitFor(() => expect(useUiStore.getState().orchestratorStartupErrors["proj-1"]).toBeUndefined());
expect(screen.queryByText(/Project added, but orchestrator did not start/)).not.toBeInTheDocument();
});
@@ -244,7 +246,7 @@ describe("project board with no sessions", () => {
);
renderBoard();
- await screen.findByText("No sessions yet");
+ await screen.findByText("No worker sessions yet");
await waitFor(() => expect(useUiStore.getState().orchestratorStartupErrors["proj-1"]).toBeUndefined());
expect(screen.queryByText(/Project added, but orchestrator did not start/)).not.toBeInTheDocument();
});
@@ -255,7 +257,7 @@ describe("project board with no sessions", () => {
spawnOrchestratorMock.mockRejectedValue(new Error("branch is already checked out in another worktree"));
const { rerender } = renderBoard();
- await screen.findByText("No sessions yet");
+ await screen.findByText("No worker sessions yet");
const [spawnButton] = screen.getAllByRole("button", { name: "Spawn Orchestrator" });
await userEvent.click(spawnButton);
await screen.findByText(/branch is already checked out/);
@@ -267,7 +269,7 @@ describe("project board with no sessions", () => {
,
);
- await screen.findByText("No sessions yet");
+ await screen.findByText("No worker sessions yet");
expect(screen.queryByText(/branch is already checked out/)).not.toBeInTheDocument();
});
@@ -276,7 +278,7 @@ describe("project board with no sessions", () => {
renderBoard();
expect(await screen.findByText("fix the bug")).toBeInTheDocument();
- expect(screen.queryByText("No sessions yet")).not.toBeInTheDocument();
+ expect(screen.queryByText("No worker sessions yet")).not.toBeInTheDocument();
expect(columnCount()).toBe(4);
});
});
diff --git a/frontend/src/renderer/components/BoardEmptyState.tsx b/frontend/src/renderer/components/BoardEmptyState.tsx
index adf4a9263..e339844af 100644
--- a/frontend/src/renderer/components/BoardEmptyState.tsx
+++ b/frontend/src/renderer/components/BoardEmptyState.tsx
@@ -29,19 +29,19 @@ export function BoardWelcome() {
Welcome to Agent Orchestrator
- Point it at a git repository and delegate. Agents do the work on isolated branches; you review and merge the
- PRs from this board.
+ Add a git repository, describe the work, and AO coordinates agent sessions on isolated branches. This kanban
+ board tracks each session from work through review to merge.
- Pick a local git repository and choose which agents run it.
+ Choose a local git repository and select the agents AO should use.
- The orchestrator plans the work and spawns worker sessions, each on its own branch.
+ Tell the orchestrator what you want done; it creates worker sessions on isolated branches.
- Sessions move across this board as they progress:
+ Follow each session from work to review to merge readiness:
{FLOW_LEGEND.map((zone, index) => (
@@ -123,7 +123,7 @@ export function ProjectBoardEmpty({
return (
-
No sessions yet
+
No worker sessions yet
Describe a task and the orchestrator plans it, spawns worker sessions, and tracks them here from work to
merge.
diff --git a/frontend/src/renderer/components/SessionsBoard.tsx b/frontend/src/renderer/components/SessionsBoard.tsx
index 451666da7..cb6148f36 100644
--- a/frontend/src/renderer/components/SessionsBoard.tsx
+++ b/frontend/src/renderer/components/SessionsBoard.tsx
@@ -225,11 +225,16 @@ export function SessionsBoard({ projectId }: SessionsBoardProps) {
return (
-
+ {/* The first-launch welcome carries its own orientation; a "Board"
+ header above it would describe a board that isn't rendered
+ (review feedback on #2432). */}
+ {!showWelcome && (
+
+ )}
{projectId && health.state !== "ok" ? (