# refactor(runner): move `trail tune` to `entire runner setup`

`b340e40`→[main](/content/gh/entireio/cli/commits/main/index.html)·
  
Soph·2w ago·14 files·+408 added/-324 removed

Reframe the tuning command as setup of a repo's runners, under a new `runner`
group (hidden during maturation, like `trail`):

- `entire trail tune` → `entire runner setup`.
- Renamed trail_tune_*.go → runner_*.go and the command type/funcs
  (newRunnerSetupCmd, runRunnerSetup, runnerSetupOptions, runnerInsecureHTTP).
- On re-run in a repo that already has runners (nothing to scaffold), setup now
offers to re-tune instead of silently re-emitting: interactive confirm, or
 --run as an explicit yes; non-interactive without --run prints a hint.

First-run behavior (create defaults → tailor) and all flags (--run, --yes,
--sources, --limit, --debug-dir, [runner]) are unchanged.

## Sessions

e9d8c60a8008View transcript

## Changes

14

- cmd/entire/cli

- Mroot.go+1
  
  - Rrunner_apply.go
  
  - Rrunner_apply_test.go
  
  - Rrunner_gather.go
  
  - Arunner_group.go+47
  
  - Arunner_init.go+96
  
  - Rrunner_init_test.go
  
  - Rrunner_prompt.go
  
  - Rrunner_prompt_test.go
  
  - Arunner_setup.go+263
  
  - runnerdefaults

- Membed.go+1/-1

- Mtrail_cmd.go-1
  
  - Dtrail_tune_cmd.go-244
  
  - Dtrail_tune_init.go-78

```go
126 unmodified lines

127
128
129
130
131
132
133

126 unmodified lines

// Hidden infrastructure.
cmd.AddCommand(newHooksCmd())
cmd.AddCommand(newTrailCmd())
cmd.AddCommand(newRunnerCmd()) // 'runner' (setup/tune runners); hidden during maturation
cmd.AddCommand(newSendAnalyticsCmd())
cmd.AddCommand(newCurlBashPostInstallCmd())
```

Mcmd/entire/cli/root.go+1

```
1

No patch available.
```

Rcmd/entire/cli/runner_apply.go

```
1

No patch available.
```

Rcmd/entire/cli/runner_apply_test.go

```
1

No patch available.
```

Rcmd/entire/cli/runner_gather.go

```
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

package cli

import (
	"fmt"

"github.com/spf13/cobra"
)

// newRunnerCmd is the root of the `entire runner` group, which manages the
// trail runner configs under .entire/runners/. Hidden during maturation, like
// the related `trail` group.
func newRunnerCmd() *cobra.Command {
	var insecureHTTPAuth bool

cmd := &cobra.Command{
		Use:    "runner",
		Short:  "Set up and tune trail runners for this repository",
		Hidden: true,
		Args:   cobra.NoArgs,
		Long: `Manage the trail runner configs in .entire/runners/.

Runners are the per-repo evaluators (risk, confidence, drift, security, review,
…) that score and review a branch's changes. Use ` + "`entire runner setup`" + ` to
create the default set in a repo that has none, and to tailor the runner
prompts to this repository.`,
		RunE: func(cmd *cobra.Command, _ []string) error {
			return cmd.Help()
		},
	}

cmd.PersistentFlags().BoolVar(&insecureHTTPAuth, "insecure-http-auth", false,
		"Allow API calls over plain HTTP (insecure, for local development only)")
	if err := cmd.PersistentFlags().MarkHidden("insecure-http-auth"); err != nil {
		panic(fmt.Sprintf("hide insecure-http-auth flag: %v", err))
	}

cmd.AddCommand(newRunnerSetupCmd())

return cmd
}

// runnerInsecureHTTP reads the persistent --insecure-http-auth flag from the
// runner root command.
func runnerInsecureHTTP(cmd *cobra.Command) bool {
	v, _ := cmd.Flags().GetBool("insecure-http-auth") //nolint:errcheck // flag is always registered
	return v
}
```

Acmd/entire/cli/runner_group.go+47

```
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

package cli

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

"github.com/entireio/cli/cmd/entire/cli/interactive"
	"github.com/entireio/cli/cmd/entire/cli/paths"
	"github.com/entireio/cli/cmd/entire/cli/runnerdefaults"

"charm.land/huh/v2"
)

// ensureRunnersPresent scaffolds the default runner set when a repo has none
// yet, so `tune` doubles as onboarding. It returns the IDs it created (nil when
// runners already existed) so the caller can flag any that tuning then leaves
// un-tailored. It is a no-op when runners already exist, and errors when the
// user declined or creation failed. Writing is gated on confirmation
// (interactive prompt, or the --yes flag for non-interactive runs).
func ensureRunnersPresent(w, errW io.Writer, repoRoot string, assumeYes bool) (created []string, err error) {
	dir := runnersDir(repoRoot)
	existing, _ := filepath.Glob(filepath.Join(dir, "*.json")) //nolint:errcheck // bad pattern only; treated as "none found"
	if len(existing) > 0 {
		return nil, nil
	}

defaults, err := runnerdefaults.Files()
	if err != nil {
		return nil, fmt.Errorf("loading default runners: %w", err)
	}

if !assumeYes {
		if !interactive.CanPromptInteractively() {
			return nil, fmt.Errorf("no runner configs found under %s; re-run with --yes to create the default set (%d runners)", dir, len(defaults))
		}
		confirmed, err := confirmCreateRunners(len(defaults))
		if err != nil {
			return nil, err
		}
		if !confirmed {
			return nil, errors.New("no runner configs created (declined)")
		}
	}

if err := os.MkdirAll(dir, 0o755); err != nil { //nolint:gosec // config dir, conventional perms
		return nil, fmt.Errorf("creating %s: %w", dir, err)
	}
	for _, f := range defaults {
		dest := filepath.Join(dir, f.Name)
		if err := os.WriteFile(dest, f.Data, 0o644); err != nil { //nolint:gosec // runner configs are repo-committed, world-readable config
			return nil, fmt.Errorf("writing %s: %w", dest, err)
		}
		fmt.Fprintf(w, "created %s\n", filepath.Join(paths.EntireDir, "runners", f.Name))
		created = append(created, strings.TrimSuffix(f.Name, ".json"))
	}
	fmt.Fprintf(errW, "Created %d default runner(s); tailoring them to this repo…\n", len(defaults))
	return created, nil
}

func confirmCreateRunners(n int) (bool, error) {
	var ok bool
	form := NewAccessibleForm(
		huh.NewGroup(
			huh.NewConfirm().
				Title(fmt.Sprintf("No trail runners found. Create the default set (%d runners) in .entire/runners/?", n)).
				Description("Written from the built-in defaults, then tailored to this repo.").
				Value(&ok),
			),
	)
	if err := form.Run(); err != nil {
		return false, fmt.Errorf("runner-creation prompt cancelled: %w", err)
	}
	return ok, nil
}
```

Dcmd/entire/cli/trail_tune_cmd.go-244

```
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

package cli

import (
	"errors"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

"github.com/entireio/cli/cmd/entire/cli/interactive"
	"github.com/entireio/cli/cmd/entire/cli/paths"
	"github.com/entireio/cli/cmd/entire/cli/runnerdefaults"

"charm.land/huh/v2"
)

defaults, err := runnerdefaults.Files()
	if err != nil {
		return nil, fmt.Errorf("loading default runners: %w", err)
	}

Dcmd/entire/cli/trail_tune_init.go-78
