File size: 3,509 Bytes
1dbc34b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { describe, it, expect } from 'vitest';
import { parseAllPhaseSummaries, isAccumulatedSummary } from '../../../../ui/src/lib/log-parser.ts';
import { getFirstNonEmptySummary } from '../../../../ui/src/lib/summary-selection.ts';

/**
 * Mirrors summary source priority in agent-info-panel.tsx:
 * freshFeature.summary > feature.summary > summaryProp > agentInfo.summary
 */
function getCardEffectiveSummary(params: {
  freshFeatureSummary?: string | null;
  featureSummary?: string | null;
  summaryProp?: string | null;
  agentInfoSummary?: string | null;
}): string | undefined | null {
  return getFirstNonEmptySummary(
    params.freshFeatureSummary,
    params.featureSummary,
    params.summaryProp,
    params.agentInfoSummary
  );
}

/**
 * Mirrors SummaryDialog raw summary selection in summary-dialog.tsx:
 * summaryProp > feature.summary > agentInfo.summary
 */
function getDialogRawSummary(params: {
  summaryProp?: string | null;
  featureSummary?: string | null;
  agentInfoSummary?: string | null;
}): string | undefined | null {
  return getFirstNonEmptySummary(
    params.summaryProp,
    params.featureSummary,
    params.agentInfoSummary
  );
}

describe('Summary Source Flow Integration', () => {
  it('uses fresh per-feature summary in card and preserves it through summary dialog', () => {
    const staleListSummary = '## Old summary from stale list cache';
    const freshAccumulatedSummary = `### Implementation

Implemented auth + profile flow.

---

### Testing

- Unit tests: 18 passed
- Integration tests: 6 passed`;
    const parsedAgentInfoSummary = 'Fallback summary from parsed agent output';

    const cardEffectiveSummary = getCardEffectiveSummary({
      freshFeatureSummary: freshAccumulatedSummary,
      featureSummary: staleListSummary,
      summaryProp: undefined,
      agentInfoSummary: parsedAgentInfoSummary,
    });

    expect(cardEffectiveSummary).toBe(freshAccumulatedSummary);

    const dialogRawSummary = getDialogRawSummary({
      summaryProp: cardEffectiveSummary,
      featureSummary: staleListSummary,
      agentInfoSummary: parsedAgentInfoSummary,
    });

    expect(dialogRawSummary).toBe(freshAccumulatedSummary);
    expect(isAccumulatedSummary(dialogRawSummary ?? undefined)).toBe(true);

    const phases = parseAllPhaseSummaries(dialogRawSummary ?? undefined);
    expect(phases).toHaveLength(2);
    expect(phases[0]?.phaseName).toBe('Implementation');
    expect(phases[1]?.phaseName).toBe('Testing');
  });

  it('falls back in order when fresher sources are absent', () => {
    const cardEffectiveSummary = getCardEffectiveSummary({
      freshFeatureSummary: undefined,
      featureSummary: '',
      summaryProp: undefined,
      agentInfoSummary: 'Agent parsed fallback',
    });

    expect(cardEffectiveSummary).toBe('Agent parsed fallback');

    const dialogRawSummary = getDialogRawSummary({
      summaryProp: undefined,
      featureSummary: undefined,
      agentInfoSummary: cardEffectiveSummary,
    });

    expect(dialogRawSummary).toBe('Agent parsed fallback');
    expect(isAccumulatedSummary(dialogRawSummary ?? undefined)).toBe(false);
  });

  it('treats whitespace-only summaries as empty during fallback selection', () => {
    const cardEffectiveSummary = getCardEffectiveSummary({
      freshFeatureSummary: '   \n',
      featureSummary: '\t',
      summaryProp: '   ',
      agentInfoSummary: 'Agent parsed fallback',
    });

    expect(cardEffectiveSummary).toBe('Agent parsed fallback');
  });
});