From 88149bbd29a680b4f8be79f54d8df44b8119ddce Mon Sep 17 00:00:00 2001
From: Dotta
Date: Tue, 3 Mar 2026 11:37:19 -0600
Subject: [PATCH] ui: show no-agents banner on dashboard with link to
onboarding step 2
When a company has no agents (e.g. user exited onboarding early), the
dashboard now shows an amber banner: "You have no agents. Create one
here" that opens the onboarding wizard directly at step 2 (agent
creation), skipping the company creation step.
Co-Authored-By: Claude Opus 4.6
---
ui/src/App.tsx | 2 +-
ui/src/components/OnboardingWizard.tsx | 30 ++++++++++++++++++++------
ui/src/context/DialogContext.tsx | 14 ++++++++++--
ui/src/pages/Companies.tsx | 2 +-
ui/src/pages/Dashboard.tsx | 19 ++++++++++++++++
5 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/ui/src/App.tsx b/ui/src/App.tsx
index 340ebdc0..5d7f2ceb 100644
--- a/ui/src/App.tsx
+++ b/ui/src/App.tsx
@@ -186,7 +186,7 @@ function NoCompaniesStartPage() {
Get started by creating a company.
-
+
diff --git a/ui/src/components/OnboardingWizard.tsx b/ui/src/components/OnboardingWizard.tsx
index 60bcd85f..b7c49f53 100644
--- a/ui/src/components/OnboardingWizard.tsx
+++ b/ui/src/components/OnboardingWizard.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useDialog } from "../context/DialogContext";
@@ -48,12 +48,15 @@ const DEFAULT_TASK_DESCRIPTION = `Setup yourself as the CEO. Use the ceo persona
Ensure you have a folder agents/ceo and then download this AGENTS.md as well as the sibling HEARTBEAT.md, SOUL.md, and TOOLS.md. and set that AGENTS.md as the path to your agents instruction file`;
export function OnboardingWizard() {
- const { onboardingOpen, closeOnboarding } = useDialog();
- const { setSelectedCompanyId } = useCompany();
+ const { onboardingOpen, onboardingOptions, closeOnboarding } = useDialog();
+ const { selectedCompanyId, companies, setSelectedCompanyId } = useCompany();
const queryClient = useQueryClient();
const navigate = useNavigate();
- const [step, setStep] = useState(1);
+ const initialStep = onboardingOptions.initialStep ?? 1;
+ const existingCompanyId = onboardingOptions.companyId;
+
+ const [step, setStep] = useState(initialStep);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [modelOpen, setModelOpen] = useState(false);
@@ -75,12 +78,25 @@ export function OnboardingWizard() {
const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
const [taskDescription, setTaskDescription] = useState(DEFAULT_TASK_DESCRIPTION);
- // Created entity IDs
- const [createdCompanyId, setCreatedCompanyId] = useState(null);
+ // Created entity IDs — pre-populate from existing company when skipping step 1
+ const [createdCompanyId, setCreatedCompanyId] = useState(existingCompanyId ?? null);
const [createdCompanyPrefix, setCreatedCompanyPrefix] = useState(null);
const [createdAgentId, setCreatedAgentId] = useState(null);
const [createdIssueRef, setCreatedIssueRef] = useState(null);
+ // Sync step and company when onboarding opens with options
+ useEffect(() => {
+ if (onboardingOpen) {
+ const cId = onboardingOptions.companyId ?? null;
+ setStep(onboardingOptions.initialStep ?? 1);
+ setCreatedCompanyId(cId);
+ if (cId) {
+ const company = companies.find((c) => c.id === cId);
+ if (company) setCreatedCompanyPrefix(company.issuePrefix);
+ }
+ }
+ }, [onboardingOpen, onboardingOptions, companies]);
+
const { data: adapterModels } = useQuery({
queryKey: ["adapter-models", adapterType],
queryFn: () => agentsApi.adapterModels(adapterType),
@@ -634,7 +650,7 @@ export function OnboardingWizard() {
{/* Footer navigation */}