trail: clarify unavailable resume findings · Entire

trail: clarify unavailable resume findings

0fc36f1→main·

peyton-alt·3w ago·3 files·+62 added/-7 removed

Sessions

132301f4f85cView transcript

[?
Add Trail Resume SubcommandCodex·GPT-5.5·1 step](/content/gh/entireio/cli/session/019ef5f3-3472-7f70-82f7-6f0ce46691f4#timeline-132301f4f85c/index.html)

Changes

3

99 unmodified lines

100
101
102
103
103
104
105
106

99 unmodified lines

resumeOutput := env.RunCLI("trail", "--insecure-http-auth", "resume", "321", "--session", secondSession.ID)
    for _, want := range []string{
        "Restored checkpoint session " + secondSession.ID,
        "Restored checkpoint " + checkpointID + " (1 session)",
        "claude -r " + secondSession.ID,
        "Create goodbye method",
    } {

Mcmd/entire/cli/integration_test/trail_resume_test.go+1/-1

785 unmodified lines

786
787
788
789
790
791
792
793
794
795
796
792
793
794
795
797
798
799
33 unmodified lines

833
834
835
835
836
837
838
839
3 unmodified lines

843
844
845
845
846
847
848
849
850
851
852
853
854
855
856
857
858

785 unmodified lines

}

func printTrailResumeFindings(w io.Writer, findings trailResumeFindingsContext) {
    if findings.Unavailable != "" {
        fmt.Fprintln(w, "  Findings:")
        fmt.Fprintf(w, "    unavailable: %s\n\n", findings.Unavailable)
        return
    }
    counts := findings.Counts
    fmt.Fprintf(w, "  Findings: open %d  high %d  medium %d  low %d  resolved %d  dismissed %d  stale %d\n",
        counts.Open, counts.OpenHigh, counts.OpenMedium, counts.OpenLow, counts.Resolved, counts.Dismissed, counts.Stale)
    if findings.Unavailable != "" {
        fmt.Fprintf(w, "    unavailable: %s\n\n", findings.Unavailable)
        return
    }
    if len(findings.Top) == 0 {
        fmt.Fprintln(w, "    no current high/medium open findings")
        fmt.Fprintln(w)
33 unmodified lines

Trail               trailResumeTrailContext     `json:"trail"`
    Sessions            []trailResumeSessionContext `json:"sessions"`
    SessionsUnavailable string                      `json:"sessions_unavailable,omitempty"`
    FindingsSummary     trailResumeFindingCounts    `json:"findings_summary"`
    FindingsSummary     *trailResumeFindingCounts   `json:"findings_summary,omitempty"`
    Findings            []api.TrailReviewComment    `json:"findings"`
    FindingsHasMore     bool                        `json:"findings_has_more,omitempty"`
    FindingsUnavailable string                      `json:"findings_unavailable,omitempty"`
3 unmodified lines

Trail:               ctx.Trail,
    Sessions:            ctx.Sessions,
    SessionsUnavailable: ctx.SessionsUnavailable,
    FindingsSummary:     trailResumeFindingCountsFromReviewCounts(ctx.Findings.Counts),
    Findings:            ctx.Findings.Top,
    FindingsHasMore:     ctx.Findings.HasMore,
    FindingsUnavailable: ctx.Findings.Unavailable,
    DefaultResume:       ctx.DefaultResume,
    Commands:            ctx.Commands,
    }
    if ctx.Findings.Unavailable == "" {
        summary := trailResumeFindingCountsFromReviewCounts(ctx.Findings.Counts)
        payload.FindingsSummary = &summary
    }

enc := json.NewEncoder(w)
    enc.SetIndent("", "  ")

Mcmd/entire/cli/trail_resume_cmd.go+10/-6

432 unmodified lines

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
66 unmodified lines

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

432 unmodified lines

}
}

func TestPrintTrailResumeContextSuppressesCountsWhenFindingsUnavailable(t *testing.T) {
    t.Parallel()

ctx := trailResumeContext{
        Trail: trailResumeTrailContext{
            Number: 575,
            Title:  "Add trail resume",
            Branch: "feature/trail-resume",
        },
        Findings: trailResumeFindingsContext{
            Unavailable: "reviews API unavailable",
        },
    }

var out strings.Builder
    printTrailResumeContext(&out, ctx)
    text := out.String()
    if !strings.Contains(text, "Findings:") || !strings.Contains(text, "unavailable: reviews API unavailable") {
        t.Fatalf("context output missing unavailable findings message:\n%s", text)
    }
    if strings.Contains(text, "open 0") || strings.Contains(text, "high 0") {
        t.Fatalf("context output should not print zero findings counts when findings are unavailable:\n%s", text)
    }
}

func TestEncodeTrailResumeContextJSON(t *testing.T) {
    t.Parallel()

66 unmodified lines

}
}

func TestEncodeTrailResumeContextJSONOmitsFindingsSummaryWhenUnavailable(t *testing.T) {
    t.Parallel()

ctx := trailResumeContext{
        Trail: trailResumeTrailContext{ID: "trl_1", Number: 575, Branch: "feature/trail-resume"},
        Findings: trailResumeFindingsContext{
            Unavailable: "reviews API unavailable",
        },
    }

var out bytes.Buffer
    if err := encodeTrailResumeContextJSON(&out, ctx); err != nil {
        t.Fatalf("encodeTrailResumeContextJSON: %v", err)
    }
    var decoded map[string]any
    if err := json.Unmarshal(out.Bytes(), &decoded); err != nil {
        t.Fatalf("unmarshal output: %v\n%s", err, out.String())
    }
    if decoded["findings_unavailable"] != "reviews API unavailable" {
        t.Fatalf("decoded findings_unavailable = %#v", decoded["findings_unavailable"])
    }
    if _, ok := decoded["findings_summary"]; ok {
        t.Fatalf("findings_summary should be omitted when findings are unavailable:\n%s", out.String())
    }
}

func TestBuildTrailResumeRestoredSessionChoicesDefaultsToMostRecent(t *testing.T) {
    t.Parallel()