Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions cli/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ installation and returns an informative message.`,
RunE: runInit,
}

var initYes bool

func init() {
initCmd.Flags().BoolVarP(&initYes, "yes", "y", false, "Accept sensible defaults (non-interactive)")
}

type initResult struct {
RepoRoot string `json:"repo_root"`
PolicyDB string `json:"policy_db"`
Expand All @@ -56,7 +62,7 @@ func runInit(cmd *cobra.Command, args []string) error {
if flags.JSON {
out, _ := json.MarshalIndent(map[string]interface{}{
"already_initialised": true,
"repo_root": absRoot,
"repo_root": absRoot,
}, "", " ")
fmt.Println(string(out))
return nil
Expand Down Expand Up @@ -123,12 +129,17 @@ func runInit(cmd *cobra.Command, args []string) error {
return fmt.Errorf("init: store installed agents: %w", err)
}

// Standard guardrails — prompt user to opt in (skip in --json mode).
// Standard guardrails — prompt user to opt in.
// In --json mode this is skipped unless -y is set.
var addedCommands []string
var addedFiles []string
if !flags.JSON {
if !flags.JSON || initYes {
var err error
addedCommands, addedFiles, err = promptAndAddGuardrails(cmd, policyDB)
if initYes {
addedCommands, addedFiles, err = addStandardGuardrails(policyDB)
} else {
addedCommands, addedFiles, err = promptAndAddGuardrails(cmd, policyDB)
}
if err != nil {
return fmt.Errorf("init: guardrails: %w", err)
}
Expand Down Expand Up @@ -169,12 +180,12 @@ func runInit(cmd *cobra.Command, args []string) error {
return nil
}

// selectAgents presents the interactive TUI (or auto-selects in --json/non-TTY).
// selectAgents presents the interactive TUI (or auto-selects in --json/-y).
// Returns the selected agent IDs and display names.
func selectAgents(cmd *cobra.Command) (ids []string, names []string, err error) {
allAgents := agents.All()

if flags.JSON {
if flags.JSON || initYes {
// Auto-select all installable agents.
for _, a := range allAgents {
if a.Installable() {
Expand Down Expand Up @@ -264,6 +275,21 @@ func promptAndAddGuardrails(cmd *cobra.Command, policyDB *sql.DB) (addedCommands
return nil, nil, nil
}

addedCommands, addedFiles, err = addStandardGuardrails(policyDB)
if err != nil {
return nil, nil, err
}

total := len(addedCommands) + len(addedFiles)
if total > 0 {
fmt.Fprintf(cmd.OutOrStdout(), " added %d guardrail(s).\n", total)
} else {
fmt.Fprintln(cmd.OutOrStdout(), " already configured.")
}
return addedCommands, addedFiles, nil
}

func addStandardGuardrails(policyDB *sql.DB) (addedCommands []string, addedFiles []string, err error) {
user := store.CurrentOSUser()

for _, pattern := range store.StandardGuardrails {
Expand All @@ -288,11 +314,5 @@ func promptAndAddGuardrails(cmd *cobra.Command, policyDB *sql.DB) (addedCommands
addedFiles = append(addedFiles, f.Pattern)
}

total := len(addedCommands) + len(addedFiles)
if total > 0 {
fmt.Fprintf(cmd.OutOrStdout(), " added %d guardrail(s).\n", total)
} else {
fmt.Fprintln(cmd.OutOrStdout(), " already configured.")
}
return addedCommands, addedFiles, nil
}
58 changes: 58 additions & 0 deletions cli/tests/init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package tests

import "testing"

func TestInitYesAddsDefaultGuardrails(t *testing.T) {
repo := testRepo{
Dir: t.TempDir(),
Home: t.TempDir(),
}

runCordon(t, repo, "init", "-y")

var commandList struct {
Rules []struct {
Pattern string `json:"Pattern"`
} `json:"rules"`
}
r := runCordon(t, repo, "command", "list", "--json")
mustParseJSON(t, r.Stdout, &commandList)

if len(commandList.Rules) == 0 {
t.Fatal("expected default command guardrails after init -y, got none")
}

foundCommandGuardrail := false
for _, rule := range commandList.Rules {
if rule.Pattern == "git reset --hard*" {
foundCommandGuardrail = true
break
}
}
if !foundCommandGuardrail {
t.Fatal("expected guardrail 'git reset --hard*' after init -y")
}

var fileList struct {
FileRules []struct {
Pattern string `json:"Pattern"`
} `json:"file_rules"`
}
r = runCordon(t, repo, "file", "list", "--json")
mustParseJSON(t, r.Stdout, &fileList)

if len(fileList.FileRules) == 0 {
t.Fatal("expected default file guardrails after init -y, got none")
}

foundFileGuardrail := false
for _, rule := range fileList.FileRules {
if rule.Pattern == ".env" {
foundFileGuardrail = true
break
}
}
if !foundFileGuardrail {
t.Fatal("expected file guardrail '.env' after init -y")
}
}
Loading