From bce4ce32ec9c50098d1dc60cb42627a0a0edb902 Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Thu, 16 Apr 2026 19:33:47 -0700 Subject: [PATCH] feat(ui): show merged-into-parent badge on adopted observations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ObservationCard renders a secondary "merged → " chip when merged_into_project is set, next to the existing project label. Both are meaningful: project is origin provenance, merged_into_project is the current home. Extends PaginationHelper's observations and summaries queries with OR merged_into_project = ? so the single-project viewer fetch pulls in adopted rows — the plan's Phase 3 covered multi-project context injection; this is the single-project UI read path. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/services/worker-types.ts | 1 + src/services/worker/PaginationHelper.ts | 13 +++++++++---- src/ui/viewer-template.html | 13 +++++++++++++ src/ui/viewer/components/ObservationCard.tsx | 5 +++++ src/ui/viewer/types.ts | 1 + 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/services/worker-types.ts b/src/services/worker-types.ts index 1a8557a0..79dc9199 100644 --- a/src/services/worker-types.ts +++ b/src/services/worker-types.ts @@ -124,6 +124,7 @@ export interface Observation { id: number; memory_session_id: string; // Renamed from sdk_session_id project: string; + merged_into_project: string | null; platform_source: string; type: string; title: string; diff --git a/src/services/worker/PaginationHelper.ts b/src/services/worker/PaginationHelper.ts index 42ce1cce..07888ec7 100644 --- a/src/services/worker/PaginationHelper.ts +++ b/src/services/worker/PaginationHelper.ts @@ -80,6 +80,7 @@ export class PaginationHelper { o.id, o.memory_session_id, o.project, + o.merged_into_project, COALESCE(s.platform_source, 'claude') as platform_source, o.type, o.title, @@ -100,8 +101,10 @@ export class PaginationHelper { const conditions: string[] = []; if (project) { - conditions.push('o.project = ?'); - params.push(project); + // Include adopted merged-worktree rows so the parent project's view + // surfaces observations that originated under its merged children. + conditions.push('(o.project = ? OR o.merged_into_project = ?)'); + params.push(project, project); } if (platformSource) { conditions.push(`COALESCE(s.platform_source, 'claude') = ?`); @@ -156,8 +159,10 @@ export class PaginationHelper { const conditions: string[] = []; if (project) { - conditions.push('ss.project = ?'); - params.push(project); + // Include adopted merged-worktree summaries so the parent project's view + // surfaces rows that originated under its merged children. + conditions.push('(ss.project = ? OR ss.merged_into_project = ?)'); + params.push(project, project); } if (platformSource) { diff --git a/src/ui/viewer-template.html b/src/ui/viewer-template.html index c540310c..04f79156 100644 --- a/src/ui/viewer-template.html +++ b/src/ui/viewer-template.html @@ -1130,6 +1130,19 @@ color: var(--color-text-muted); } + /* Merged-into-parent provenance badge */ + .card-merged-badge { + padding: 1px 6px; + border-radius: 3px; + font-size: 9px; + font-weight: 500; + letter-spacing: 0.02em; + color: var(--color-text-muted); + background: var(--color-type-badge-bg); + border: 1px solid var(--color-border); + opacity: 0.85; + } + .summary-card { border-color: var(--color-border-summary); background: var(--color-bg-summary); diff --git a/src/ui/viewer/components/ObservationCard.tsx b/src/ui/viewer/components/ObservationCard.tsx index 71352756..14fbe6cb 100644 --- a/src/ui/viewer/components/ObservationCard.tsx +++ b/src/ui/viewer/components/ObservationCard.tsx @@ -56,6 +56,11 @@ export function ObservationCard({ observation }: ObservationCardProps) { {observation.platform_source || 'claude'} {observation.project} + {observation.merged_into_project && ( + + merged → {observation.merged_into_project} + + )}
{hasFactsContent && ( diff --git a/src/ui/viewer/types.ts b/src/ui/viewer/types.ts index cf0403e1..4078e0e9 100644 --- a/src/ui/viewer/types.ts +++ b/src/ui/viewer/types.ts @@ -2,6 +2,7 @@ export interface Observation { id: number; memory_session_id: string; project: string; + merged_into_project?: string | null; platform_source: string; type: string; title: string | null;