diff --git a/crates/diffcore-tauri/ui/src/App.tsx b/crates/diffcore-tauri/ui/src/App.tsx
index 1c197bd..6498694 100644
--- a/crates/diffcore-tauri/ui/src/App.tsx
+++ b/crates/diffcore-tauri/ui/src/App.tsx
@@ -158,13 +158,15 @@ function GroupSummary({ group }: { group: FlowGroup }) {
* analysis, so the block never reflows as fields come and go between groups.
* A row the analysis never fills is dropped rather than left as dead space.
*/
-function GroupReviewSummary({ group, groups }: { group: FlowGroup; groups: FlowGroup[] }) {
+function GroupReviewSummary(
+ { group, groups, describing }: { group: FlowGroup; groups: FlowGroup[]; describing: boolean },
+) {
const focus = group.review_focus ?? [];
const hasMetadata = Boolean(
group.group_type || group.risk || group.impact || group.complexity ||
group.description || group.invariant || focus.length > 0,
);
- if (!hasMetadata) return null;
+ if (!hasMetadata && !describing) return null;
const reservesFocus = groups.some((g) => (g.review_focus ?? []).length > 0);
const reservesDescription = groups.some((g) => g.description);
@@ -198,11 +200,16 @@ function GroupReviewSummary({ group, groups }: { group: FlowGroup; groups: FlowG
)}
)}
- {reservesDescription && (
+ {describing && !group.description ? (
+
+
+ Writing group description...
+
+ ) : reservesDescription ? (
{group.description}
- )}
+ ) : null}
{reservesInvariant && (
{group.invariant && (
@@ -232,6 +239,9 @@ export default function App() {
const [overview, setOverview] = useState(null);
const [deepAnalyses, setDeepAnalyses] = useState>({});
const [deepAnalyzing, setDeepAnalyzing] = useState(false);
+ // The metadata pass runs in the background after analyze; without this the
+ // descriptions just appear minutes later with nothing having said they were coming.
+ const [describing, setDescribing] = useState(false);
// Counter to track concurrent deep analysis requests — prevents premature loading state clear
const deepAnalyzingCount = useRef(0);
const [activityJob, setActivityJob] = useState(null);
@@ -902,6 +912,7 @@ export default function App() {
*/
const describeGroups = useCallback(async () => {
if (!HAS_BACKEND || !llmSettings?.metadata_enabled) return;
+ setDescribing(true);
try {
const described = await tauriInvoke("describe_groups", {
repoPath: repoPath || null,
@@ -919,6 +930,8 @@ export default function App() {
// failure either: a silent catch here is indistinguishable from the pass
// working and returning nothing.
showToast(`Group descriptions unavailable: ${String(e)}`);
+ } finally {
+ setDescribing(false);
}
}, [llmSettings, repoPath, showToast]);
@@ -2598,7 +2611,7 @@ export default function App() {
) : (
<>
-
+
>
)}
diff --git a/crates/diffcore-tauri/ui/src/styles.css b/crates/diffcore-tauri/ui/src/styles.css
index 874186d..513acbe 100644
--- a/crates/diffcore-tauri/ui/src/styles.css
+++ b/crates/diffcore-tauri/ui/src/styles.css
@@ -1889,6 +1889,13 @@ body {
line-clamp: 2;
}
+.review-meta .review-meta-description-pending {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--text-muted);
+}
+
.review-meta .review-meta-invariant {
font-size: 11px;
height: 32px;