a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
68 lines
2.1 KiB
Go
68 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// interactiveChoice is the outcome of the `gortex init` wizard. Now
|
|
// that global vs per-repo is owned by the separate `gortex install`
|
|
// command, the only remaining interactive knob is hooks — everything
|
|
// else has sensible defaults and non-interactive callers (CI,
|
|
// --yes, non-TTY stdin) skip the wizard entirely.
|
|
type interactiveChoice struct {
|
|
Hooks bool
|
|
}
|
|
|
|
// runInteractiveInit prompts the user for the few decisions `gortex
|
|
// init` still needs input for. Today that's just the hooks toggle.
|
|
// Separated from the caller so the prompt body stays unit-testable
|
|
// with a plain io.Reader.
|
|
//
|
|
// Returns the decided choice and whether the prompt completed
|
|
// successfully. A return of (_, false) means the user terminated the
|
|
// prompt early (EOF / Ctrl-D); the caller should fall back to
|
|
// historical defaults.
|
|
//
|
|
// hooksPreset tells the wizard that --hooks / --no-hooks was already
|
|
// passed on the command line; in that case we skip the prompt to
|
|
// avoid nagging the user about a decision they already made.
|
|
func runInteractiveInit(in io.Reader, out io.Writer, hooksPreset bool) (interactiveChoice, bool) {
|
|
reader := bufio.NewReader(in)
|
|
choice := interactiveChoice{Hooks: true}
|
|
|
|
if hooksPreset {
|
|
return choice, true
|
|
}
|
|
|
|
fmt.Fprint(out, "Install agent hooks (Claude Code + Codex SessionStart where supported)? [Y/n]: ")
|
|
line, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
return interactiveChoice{}, false
|
|
}
|
|
choice.Hooks = !isNo(line)
|
|
fmt.Fprintln(out)
|
|
return choice, true
|
|
}
|
|
|
|
// isNo returns true when the user answered "no" to a yes/no prompt.
|
|
// Blank input is yes (the capital Y in "[Y/n]" sets the default).
|
|
func isNo(line string) bool {
|
|
s := strings.ToLower(strings.TrimSpace(line))
|
|
return strings.HasPrefix(s, "n")
|
|
}
|
|
|
|
// isInteractive reports whether stdin is a terminal — the gate that
|
|
// separates "user typed gortex init at a prompt" from "CI script ran
|
|
// gortex init." We only prompt in the former case.
|
|
func isInteractive() bool {
|
|
fi, err := os.Stdin.Stat()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return fi.Mode()&os.ModeCharDevice != 0
|
|
}
|