From 7769248c4b78715b81d4ded2ba77d0bb8bb5dc45 Mon Sep 17 00:00:00 2001 From: Bartek Lipinski Date: Wed, 8 Apr 2026 18:29:38 +0200 Subject: [PATCH 1/4] List mob names in purge confirmation prompt (#35) Instead of showing just a count, purge now lists each mob by name before asking for confirmation. --- cmd/root.go | 7 ++++++- internal/mob/integration_test.go | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index 501da40..6e379d0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -663,7 +663,12 @@ func cmdPurge(_ []string) error { fmt.Println() fmt.Printf(" %s⚠ DESTRUCTIVE OPERATION%s\n", r, rst) fmt.Println() - fmt.Printf(" This will permanently remove all %s%d mob(s)%s and their worktrees.\n", r, len(cfg.Mobs), rst) + fmt.Println(" The following mobs will be permanently removed:") + fmt.Println() + for _, m := range cfg.Mobs { + fmt.Printf(" %s✗%s %s\n", r, rst, m.Name) + } + fmt.Println() fmt.Printf(" Any %suncommitted or unpushed changes%s in those worktrees will be %spermanently lost%s.\n", r, rst, r, rst) fmt.Println() fmt.Printf(" %sThis cannot be undone.%s\n", r, rst) diff --git a/internal/mob/integration_test.go b/internal/mob/integration_test.go index 6ac0f7b..3e10c4d 100644 --- a/internal/mob/integration_test.go +++ b/internal/mob/integration_test.go @@ -766,6 +766,15 @@ func TestPurge(t *testing.T) { t.Fatalf("clear failed: %s\n%s", err, out) } + // then -> output lists mob names before confirmation + outStr := string(out) + if !strings.Contains(outStr, "one") { + t.Error("purge output should list mob 'one'") + } + if !strings.Contains(outStr, "two") { + t.Error("purge output should list mob 'two'") + } + // then -> no mobs cfg := readConfig(t, repoPath) mobs, _ := cfg["mobs"].([]interface{}) From 661139124f5d433f5326d714f29ec9e05611637b Mon Sep 17 00:00:00 2001 From: Bartek Lipinski Date: Wed, 8 Apr 2026 18:33:48 +0200 Subject: [PATCH 2/4] Include branch names in purge mob listing --- cmd/root.go | 3 ++- internal/mob/integration_test.go | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 6e379d0..162ada1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -666,7 +666,8 @@ func cmdPurge(_ []string) error { fmt.Println(" The following mobs will be permanently removed:") fmt.Println() for _, m := range cfg.Mobs { - fmt.Printf(" %s✗%s %s\n", r, rst, m.Name) + branch := mob.ActualBranch(root, cfg, &m) + fmt.Printf(" %s✗%s %s (%s)\n", r, rst, m.Name, branch) } fmt.Println() fmt.Printf(" Any %suncommitted or unpushed changes%s in those worktrees will be %spermanently lost%s.\n", r, rst, r, rst) diff --git a/internal/mob/integration_test.go b/internal/mob/integration_test.go index 3e10c4d..cb6450c 100644 --- a/internal/mob/integration_test.go +++ b/internal/mob/integration_test.go @@ -766,13 +766,13 @@ func TestPurge(t *testing.T) { t.Fatalf("clear failed: %s\n%s", err, out) } - // then -> output lists mob names before confirmation + // then -> output lists mob names and branches before confirmation outStr := string(out) - if !strings.Contains(outStr, "one") { - t.Error("purge output should list mob 'one'") + if !strings.Contains(outStr, "one") || !strings.Contains(outStr, "mob/one") { + t.Errorf("purge output should list mob 'one' with branch, got: %s", outStr) } - if !strings.Contains(outStr, "two") { - t.Error("purge output should list mob 'two'") + if !strings.Contains(outStr, "two") || !strings.Contains(outStr, "mob/two") { + t.Errorf("purge output should list mob 'two' with branch, got: %s", outStr) } // then -> no mobs From 6b7ab35c0681edabc1b42de1b945b183fceabbd4 Mon Sep 17 00:00:00 2001 From: Bartek Lipinski Date: Wed, 8 Apr 2026 18:37:03 +0200 Subject: [PATCH 3/4] Add 'branch:' label to purge mob listing --- cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index 162ada1..2849cfd 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -667,7 +667,7 @@ func cmdPurge(_ []string) error { fmt.Println() for _, m := range cfg.Mobs { branch := mob.ActualBranch(root, cfg, &m) - fmt.Printf(" %s✗%s %s (%s)\n", r, rst, m.Name, branch) + fmt.Printf(" %s✗%s %s (branch: %s)\n", r, rst, m.Name, branch) } fmt.Println() fmt.Printf(" Any %suncommitted or unpushed changes%s in those worktrees will be %spermanently lost%s.\n", r, rst, r, rst) From 5ef7e68fcf1dac83f93df527e1b7b579209e98a5 Mon Sep 17 00:00:00 2001 From: Bartek Lipinski Date: Wed, 8 Apr 2026 18:40:00 +0200 Subject: [PATCH 4/4] Fix table alignment in purge mob listing Render table to a buffer so ANSI codes don't skew tabwriter column widths, then indent each line on output. --- cmd/root.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index 2849cfd..45422bc 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "fmt" "os" "os/exec" @@ -665,9 +666,16 @@ func cmdPurge(_ []string) error { fmt.Println() fmt.Println(" The following mobs will be permanently removed:") fmt.Println() + var buf bytes.Buffer + w := tabwriter.NewWriter(&buf, 0, 0, 2, ' ', 0) + fmt.Fprintln(w, "NAME\tBRANCH") for _, m := range cfg.Mobs { branch := mob.ActualBranch(root, cfg, &m) - fmt.Printf(" %s✗%s %s (branch: %s)\n", r, rst, m.Name, branch) + fmt.Fprintf(w, "%s\t%s\n", m.Name, branch) + } + w.Flush() + for _, line := range strings.Split(strings.TrimRight(buf.String(), "\n"), "\n") { + fmt.Printf(" %s\n", line) } fmt.Println() fmt.Printf(" Any %suncommitted or unpushed changes%s in those worktrees will be %spermanently lost%s.\n", r, rst, r, rst)