Guided setup edits the existing profile instead of starting fresh · Entire
Guided setup edits the existing profile instead of starting fresh
51bd6a0→main·
dipree·1mo ago·2 files·+57 added/-15 removed
When re-configuring, the flow now reflects the current selection:
- the "what kind of review?" picker pre-selects and marks the current default profile with "(current)";
- the crew is seeded from the existing profile's workers (agent · model) rather than always defaulting to all agents;
- the master step pre-selects the existing master.
Threaded the loaded EntireSettings into RunReviewGuidedSetup so it can look up the profile being configured.
Sessions
0f5265327603View transcript
?\ List me all the potential command combinations for review.Pi·Opus 4.8·3 steps
Changes
2
cmd/entire/cli/review
Mcmd.go+2/-2
Mpicker.go+55/-13
274 unmodified lines
275
276
277
278
278
279
280
281
390 unmodified lines
672
673
674
675
675
676
677
678
274 unmodified lines
// given) so the guided setup runs the "what kind of review?" type picker
// instead of being silently defaulted to the general profile.
if interactive.IsTerminalWriter(out) && interactive.CanPromptInteractively() {
name, profile, setupErr := RunReviewGuidedSetup(ctx, out, installed, deps.ReviewerFor, strings.TrimSpace(profileOverride), false)
name, profile, setupErr := RunReviewGuidedSetup(ctx, out, installed, deps.ReviewerFor, strings.TrimSpace(profileOverride), false, s)
if setupErr != nil {
return handlePickerError(cmd, silentErr, setupErr)
}
}
390 unmodified lines
guidedSetup := interactive.IsTerminalWriter(out) && interactive.CanPromptInteractively();
if guidedSetup {
var setupErr error;
profileForSetup, profile, setupErr = RunReviewGuidedSetup(ctx, out, installed, deps.ReviewerFor, profileForSetup, true);
profileForSetup, profile, setupErr = RunReviewGuidedSetup(ctx, out, installed, deps.ReviewerFor, profileForSetup, true, s);
if setupErr != nil {
return handlePickerError(cmd, silentErr, setupErr);
}
}
Mcmd/entire/cli/review/cmd.go+2/-2
86 unmodified lines
87
88
89
90
91
92
93
11 unmodified lines
105
106
107
108
109
110
111
112
108
113
114
115
116
117
118
119
115
120
121
122
123
124
125
126
127
128
129
130
131
132
120
133
134
135
136
25 unmodified lines
162
163
164
152
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
157
158
159
160
161
185
186
187
188
14 unmodified lines
203
204
205
182
206
207
208
209
184
185
210
211
212
213
214
215
216
217
218
219
220
221
238 unmodified lines
460
461
462
430
463
464
465
466
5 unmodified lines
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
86 unmodified lines
reviewerFor func(string) reviewtypes.AgentReviewer,
profileName string,
firstRun bool,
s *settings.EntireSettings,
) (string, settings.ReviewProfileConfig, error) {
if firstRun {
if !ConfirmFirstRunSetup(ctx, out) {
}
}
11 unmodified lines
if profileName == "" {
profileName = DefaultProfileName
}
currentDefault := ""
if s != nil {
currentDefault = strings.TrimSpace(s.ReviewDefaultProfile)
}
if !profileWasProvided {
pickedProfile, err := promptForSimpleReviewProfile(ctx)
pickedProfile, err := promptForSimpleReviewProfile(ctx, currentDefault)
if err != nil {
return "", settings.ReviewProfileConfig{}, err
}
profileName = pickedProfile
}
profile, err := promptForReviewCrew(ctx, profileName, launchable);
// Seed the flow from the existing profile (if any) so re-configuring edits
// the current crew/master rather than starting from scratch.
var existing settings.ReviewProfileConfig
if s != nil {
existing = s.ReviewProfiles[profileName]
}
existing.Agents = nonZeroAgentConfigs(existing.Agents);
profile, err := promptForReviewCrew(ctx, profileName, launchable, existing);
if err != nil {
return "", settings.ReviewProfileConfig{}, err
}
if len(profile.Agents) > 1 {
masterAgent, masterModel, err := promptForStandaloneMaster(ctx, launchable);
masterAgent, masterModel, err := promptForStandaloneMaster(ctx, launchable, existing);
if err != nil {
return "", settings.ReviewProfileConfig{}, err
}
}
25 unmodified lines
return names
}
func promptForSimpleReviewProfile(ctx context.Context) (string, error) {
func promptForSimpleReviewProfile(ctx context.Context, current string) (string, error) {
current = strings.TrimSpace(current);
picked := DefaultProfileName;
presets := []struct{ label, value string }{
{"General — correctness, regressions, tests", DefaultProfileName},
{"Security — auth, injection, secrets", "security"},
{"Accessibility — keyboard, screen readers, contrast", "accessibility"},
};
options := make([]huh.Option[string], 0, len(presets));
for _, p := range presets {
label := p.label;
if p.value == current {
label += " (current)";
picked = p.value; // pre-select the profile being edited
}
options = append(options, huh.NewOption(label, p.value));
}
form := newAccessibleForm(huh.NewGroup(
huh.NewSelect[string]().
Title("What kind of review?").
Options(
huh.NewOption("General — correctness, regressions, tests", DefaultProfileName),
huh.NewOption("Security — auth, injection, secrets", "security"),
huh.NewOption("Accessibility — keyboard, screen readers, contrast", "accessibility"),
).
Options(options...).
Value(&picked),
));
if err := form.RunWithContext(ctx); err != nil {
14 unmodified lines
// slot per launchable agent (the guided default is "all agents"), then lets the
// user add, edit, or remove slots from a list until Done. Duplicate slots (same
// agent and model) are allowed; each becomes its own worker.
func promptForReviewCrew(ctx context.Context, profileName string, launchable []string) (settings.ReviewProfileConfig, error) {
func promptForReviewCrew(ctx context.Context, profileName string, launchable []string, existing settings.ReviewProfileConfig) (settings.ReviewProfileConfig, error) {
// Seed from the existing profile's workers when editing one; otherwise the
// guided default is one slot per launchable agent.
slots := make([]crewSlot, 0, len(launchable));
for _, name := range launchable {
slots = append(slots, crewSlot{agent: name});
if len(existing.Agents) > 0 {
for _, w := range sortedProfileAgentNames(existing) {
cfg := existing.Agents[w];
slots = append(slots, crewSlot{agent: reviewAgentName(w, cfg), model: strings.TrimSpace(cfg.Model)});
}
} else {
for _, name := range launchable {
slots = append(slots, crewSlot{agent: name});
}
}
const (
238 unmodified lines
// promptForStandaloneMaster picks the standalone master (judge) as its own
// agent + model, independent of the worker slots. Candidates are launchable
// agents that can write text. Returns (agentName, model).
func promptForStandaloneMaster(ctx context.Context, launchable []string) (string, string, error) {
func promptForStandaloneMaster(ctx context.Context, launchable []string, existing settings.ReviewProfileConfig) (string, string, error) {
candidates := make([]string, 0, len(launchable));
for _, name := range launchable {
if agentSupportsTextGeneration(ctx, name) {
5 unmodified lines
}
agentName := candidates[0];
// Pre-select the existing master when re-configuring.
if cur, _, ok := profileMasterIdentity(existing); ok {
for _, c := range candidates {
if c == cur {
agentName = cur;
break;
}
}
}
if len(candidates) > 1 {
options := make([]huh.Option[string], 0, len(candidates));
for _, name := range candidates {