Stage 2: introduce `scout` command (review kept as hidden alias) · Entire

Stage 2: introduce scout command (review kept as hidden alias)

77e4c8d→main·

dipree·1mo ago·8 files·+62 added/-59 removed

Rebrand the multi-agent command as entire scout, reusing the existing review engine. review stays as a hidden cobra alias for back-compat, so both invocations work. Updated command Use/Short/Long, user-facing guidance strings ("entire review …" → "entire scout …"), the labs entry, and affected test expectations.

Internal package, settings keys (review_profiles), and env vars (ENTIRE_REVIEW_*) are unchanged — branding only, no behavior change.

Sessions

36ead1ea2f98View transcript

[?
List me all the potential command combinations for review.Pi·Opus 4.8·2 steps](/content/gh/entireio/cli/session/019e9fb5-004d-7145-8f48-db6a240d0ab3#timeline-36ead1ea2f98/index.html)

Changes

8

15 unmodified lines

16
17
18
19
20
21
19
20
21
22
23
24
33 unmodified lines

58
59
60
61
61
62
63
64
20 unmodified lines

85
86
87
88
88
89
90
91

15 unmodified lines

var experimentalCommands = []experimentalCommandInfo{
    {
        Name:       "review",
        Invocation: "entire review",
        Summary:    "Run a review profile against the current branch",
        Name:       "scout",
        Invocation: "entire scout",
        Summary:    "Run a multi-agent crew against the current branch (aliased as 'entire review')",
    },
    {
        Name:       "investigate",
33 unmodified lines

}
        err := fmt.Errorf("unknown labs topic %q", args[0])
        fmt.Fprintf(cmd.ErrOrStderr(),
            "%v\n\nRun `entire labs` to see available experimental commands, or run `entire review --help` for command-specific help.\n",
            "%v\n\nRun `entire labs` to see available experimental commands, or run `entire scout --help` for command-specific help.\n",
            err)
        return NewSilentError(err)
    },
20 unmodified lines

Available experimental commands:
` + renderExperimentalCommands(experimentalCommands) + `
Try:
  entire review --help
  entire scout --help
  entire investigate --help
  entire org --help
  entire project --help

Mcmd/entire/cli/labs.go+5/-5

23 unmodified lines

24
25
26
27
28
27
28
29
30
31
14 unmodified lines

46
47
48
49
49
50
51
52
16 unmodified lines

69
70
71
72
73
72
73
74
75
76

23 unmodified lines

"Labs",
        "newer Entire workflows",
        "Available experimental commands",
        "entire review",
        "entire review --help",
        "entire scout",
        "entire scout --help",
    } {
        if !strings.Contains(got, want) {
            t.Fatalf("entire labs output missing %q:\n%s", want, got)
        }
14 unmodified lines

t.Fatalf("entire labs --help failed: %v", err)
    }
    got := out.String()
    for _, want := range []string{"Labs", "entire review"} {
    for _, want := range []string{"Labs", "entire scout"} {
        if !strings.Contains(got, want) {
            t.Fatalf("entire labs --help output missing %q:\n%s", want, got)
        }
16 unmodified lines

if !strings.Contains(err.Error(), "unknown labs topic") {
        t.Fatalf("error should mention unknown labs topic, got: %v", err)
    }
    if !strings.Contains(errOut.String(), "entire review --help") {
        t.Fatalf("stderr should point to canonical review help, got:\n%s", errOut.String())
    if !strings.Contains(errOut.String(), "entire scout --help") {
        t.Fatalf("stderr should point to canonical scout help, got:\n%s", errOut.String())
    }
    if strings.Contains(out.String(), "Run the review skills configured") {
        t.Fatalf("entire labs review should not run or show review help, got stdout:\n%s", out.String())

Mcmd/entire/cli/labs_test.go+5/-5

83 unmodified lines

84
85
86
87
87
88
89
90
89
90
91
92
93
92
93
94
95
96
94
95
96
97
98
99
100
98
101
102
103
101
102
104
105
106
107
105
108
109
110
111
2 unmodified lines

114
115
116
114
115
117
118
119
120
121
119
120
122
123
124
122
123
124
125
125
126
127
128
129
127
128
130
131
132
133
134
125 unmodified lines

260
261
262
260
263
264
265
266
7 unmodified lines

274
275
276
274
277
278
279
280
56 unmodified lines

337
338
339
337
340
341
342
343
28 unmodified lines

372
373
374
372
375
376
377
378
9 unmodified lines

388
389
390
388
391
392
393
394
59 unmodified lines

454
455
456
454
457
458
459
460
132 unmodified lines

593
594
595
593
596
597
598
599
27 unmodified lines

627
628
629
627
630
631
632
633
558 unmodified lines

1192
1193
1194
1192
1195
1196
1197
1198

83 unmodified lines

var setSlots []string

cmd := &cobra.Command{
        Use: "review",
        Use: "scout",
        // `review` is kept as an alias for back-compat while scout matures.
        Aliases: []string{"review"},
        // Hidden from `entire help` while the feature is still maturing —
        // users who know about it can still run `entire review` / `entire
        // review --help` and the command works normally.
        // users who know about it can still run `entire scout` / `entire
        // scout --help` and the command works normally.
        Hidden: true,
        Short:  "Run a review profile against the current branch",
        Long: `Run a named review profile against the current branch. Review
profiles are loaded from Entire settings and clone-local preferences. On
first run, simple guided setup writes clone-local preferences and asks before
starting agents.
        Short:  "Run a multi-agent crew against the current branch",
        Long: `Run a multi-agent crew against the current branch: several worker
agents inspect the change in parallel, then a master agent synthesizes their
reports into a final verdict. Crews are saved as named profiles in Entire
settings and clone-local preferences. On first run, guided setup writes a
profile and asks before starting agents.

Labs entry: review is experimental. We are actively refining it based on user
Labs entry: scout is experimental. We are actively refining it based on user
feedback.

The review session is recorded as part of the next checkpoint, so the
review metadata is permanently attached to the commit it covers.
The session is recorded as part of the next checkpoint, so the metadata is
permanently attached to the commit it covers.

Flags:
  --configure    set up a review profile (shows available agents + profiles).
  --configure    set up a crew profile (shows available agents + profiles).
                 With --set-* flags it writes the profile non-interactively;
                 otherwise it opens the wizard (interactive) without starting agents.
  --set-agents   with --configure: comma-separated worker agents for the profile
2 unmodified lines

--set-model    with --configure: per-worker model as agent=model (repeatable)
  --set-slot     with --configure: a worker slot as agent[=model] (repeatable;
                 the same agent/model may repeat to run it multiple times)
  --edit         re-open the advanced review profile skill picker
  --findings     browse local review findings
  --edit         re-open the advanced profile skill picker
  --findings     browse local findings
  --agent NAME   run only one worker from the selected profile
  --agents       list the worker agents you can pass to --agent for the profile
  --model NAME   override the model for the --agent worker (requires --agent)
  --models       list the models each review agent advertises (optionally --agent NAME)
  --profile NAME select a review profile (also accepted as positional arg)
  --models       list the models each agent advertises (optionally --agent NAME)
  --profile NAME select a profile (also accepted as positional arg)
  --prompt TEXT  add one-off per-run instructions for this invocation
  --base REF     scope the review against REF instead of mainline. Useful
                 for stacked PRs where the review base is the parent feature
                 branch, not main. Default: first existing of origin/HEAD,
                 origin/main, origin/master, main, master.
  --base REF     scope against REF instead of mainline. Useful for stacked
                 PRs where the base is the parent feature branch, not main.
                 Default: first existing of origin/HEAD, origin/main,
                 origin/master, main, master.

To tag an already-finished session as a review, use
'entire attach --review <id>'.`,
        Aliased as 'entire review'. To tag an already-finished session as a review,
        use 'entire attach --review <id>'.`,
        Args: func(_ *cobra.Command, args []string) error {
            if len(args) > 1 {
                return fmt.Errorf("accepts at most one argument, received %d", len(args))
125 unmodified lines

return err
        }
        fmt.Fprintf(out, "Review profile %q saved with %s.\n", profileName, strings.Join(sortedProfileAgentNames(profile), ", "))
        fmt.Fprintf(out, "Run `entire review %s` to start.\n", profileName)
        fmt.Fprintf(out, "Run `entire scout %s` to start.\n", profileName)
        return nil
    }

if err := saveReviewProfile(ctx, name, profile, true); err != nil {
        return err
    }
    fmt.Fprintf(out, "Review profile %q saved. Run `entire review`, or `entire review %s`, to start.\n", name, name)
    fmt.Fprintf(out, "Crew profile %q saved. Run `entire scout`, or `entire scout %s`, to start.\n", name, name)
    return nil
    }

56 unmodified lines

fmt.Fprintln(out)
    fmt.Fprintln(out, "These are common models/aliases, not an exhaustive list. Use one with:")
    fmt.Fprintln(out, "  entire review --agent <name> --model <model>")
    fmt.Fprintln(out, "  entire scout --agent <name> --model <model>")
    return nil
}

28 unmodified lines

fmt.Fprintf(out, "  %s — %s%s\n", reviewWorkerLabel(worker, cfg), status, marker)
        }
        fmt.Fprintln(out)
        fmt.Fprintln(out, "See all available agents and profiles with `entire review --configure`.")
        fmt.Fprintln(out, "See all available agents and profiles with `entire scout --configure`.")
        return nil
    }
}

9 unmodified lines

fmt.Fprintf(out, "  %-14s %s\n", e.Name, status)
    }
    fmt.Fprintln(out)
    fmt.Fprintln(out, "Configure a profile with `entire review --configure`.")
    fmt.Fprintln(out, "Configure a profile with `entire scout --configure`.")
    return nil
}

59 unmodified lines

fmt.Fprintln(out)
    fmt.Fprintf(out, "Configure %q non-interactively, e.g.:\n", profileName)
    fmt.Fprintf(out, "  entire review --configure --profile %s --set-agents %s --set-master <agent>\n",
    fmt.Fprintf(out, "  entire scout --configure --profile %s --set-agents %s --set-master <agent>\n",
    profileName, exampleAgentList(catalog))
}

132 unmodified lines

cmd.SilenceUsage = true
    fmt.Fprintf(cmd.ErrOrStderr(), "Failed to load settings: %v\n", err)
    fmt.Fprintln(cmd.ErrOrStderr(),
        "Fix your Entire settings or clone-local review preferences and re-run `entire review`.")
        "Fix your Entire settings or clone-local review preferences and re-run `entire scout`.")
    return silentErr(err)
    }
    installed := deps.GetAgentsWithHooksInstalled(ctx)
27 unmodified lines

}
        profile = defaultProfile
        fmt.Fprintf(out, "No review profiles found — using default %q profile with %s.\n", profileForSetup, strings.Join(sortedProfileAgentNames(profile), ", "))
        fmt.Fprintln(out, "Configure later with `entire review --configure`.")
        fmt.Fprintln(out, "Configure later with `entire scout --configure`.")
        fmt.Fprintln(out)
    }
    if saveErr := saveDefaultReviewProfile(ctx, profileForSetup, profile); saveErr != nil {
558 unmodified lines

fmt.Fprintln(out)
    fmt.Fprintln(out, "Note: review skills ran but findings were not persisted.")
    fmt.Fprintf(out, "  Reason: %s\n", reason)
    fmt.Fprintln(out, "  `entire review --findings` will not see this run.")
    fmt.Fprintln(out, "  `entire scout --findings` will not see this run.")
    fmt.Fprintln(out, "  Re-run with `ENTIRE_LOG_LEVEL=debug` for diagnostic detail.")
}

Mcmd/entire/cli/review/cmd.go+34/-31

15 unmodified lines

16
17
18
19
19
20
21
22
63 unmodified lines

86
87
88
89
89
90
91
92

15 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/stringutil"

)

const reviewCommandBinary = "entire"
const reviewCommandBinary = "entire scout"

func runReviewFindings(ctx context.Context, cmd *cobra.Command, silentErr func(error) error) error {
    worktreeRoot, err := paths.WorktreeRoot(ctx)
63 unmodified lines

}
    fmt.Fprintln(w)
    fmt.Fprintln(w, "Browse findings:")
    fmt.Fprintf(w, "  %s review --findings\n", reviewCommandBinary)
    fmt.Fprintf(w, "  %s --findings\n", reviewCommandBinary)
}

func reviewManifestHandle(manifest LocalReviewManifest) string {

Mcmd/entire/cli/review/fix.go+2/-2

243 unmodified lines

244
245
246
247
247
248
249
250
128 unmodified lines

379
380
381
382
382
383
384
385

243 unmodified lines

writeReviewCompletionFooter(&b, manifest)

got := b.String()
    for _, want := range []string{"Review complete.", "entire review --findings"} {
    for _, want := range []string{"Review complete.", "entire scout --findings"} {
        if !strings.Contains(got, want) {
            t.Fatalf("footer missing %q:\n%s", want, got)
        }
128 unmodified lines

for _, want := range []string{
        "Note: review skills ran but findings were not persisted.",
        "Reason: test reason text",
        "`entire review --findings` will not see this run.",
        "`entire scout --findings` will not see this run.",
        "`ENTIRE_LOG_LEVEL=debug`",
    } {
        if !strings.Contains(got, want) {