feat(prime): add --state, --dry-run, --explain flags with mutual exclusivity validation
Add three new flags to gt prime command: - --state: Output role state as JSON and exit early (for scripting) - --dry-run: Skip side effects (persistence, locks, events) - --explain: Show verbose role detection reasoning The --state flag is mutually exclusive with all other flags and errors if combined. The other flags (--dry-run, --explain, --hook) can be combined freely. Also fixes missing filepath import in beads.go. Closes: bd-t8ven Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,9 @@ package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/steveyegge/gastown/internal/beads"
|
||||
@@ -95,3 +97,73 @@ func TestGetAgentBeadID_UsesRigPrefix(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrimeFlagCombinations(t *testing.T) {
|
||||
// Find the gt binary - we need to test CLI flag validation
|
||||
gtBin, err := exec.LookPath("gt")
|
||||
if err != nil {
|
||||
t.Skip("gt binary not found in PATH")
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
args []string
|
||||
wantError bool
|
||||
errorMsg string
|
||||
}{
|
||||
{
|
||||
name: "state_alone_is_valid",
|
||||
args: []string{"prime", "--state"},
|
||||
wantError: false, // May fail for other reasons (not in workspace), but not flag validation
|
||||
},
|
||||
{
|
||||
name: "state_with_hook_errors",
|
||||
args: []string{"prime", "--state", "--hook"},
|
||||
wantError: true,
|
||||
errorMsg: "--state cannot be combined with other flags",
|
||||
},
|
||||
{
|
||||
name: "state_with_dry_run_errors",
|
||||
args: []string{"prime", "--state", "--dry-run"},
|
||||
wantError: true,
|
||||
errorMsg: "--state cannot be combined with other flags",
|
||||
},
|
||||
{
|
||||
name: "state_with_explain_errors",
|
||||
args: []string{"prime", "--state", "--explain"},
|
||||
wantError: true,
|
||||
errorMsg: "--state cannot be combined with other flags",
|
||||
},
|
||||
{
|
||||
name: "dry_run_and_explain_valid",
|
||||
args: []string{"prime", "--dry-run", "--explain"},
|
||||
wantError: false, // May fail for other reasons, but not flag validation
|
||||
},
|
||||
{
|
||||
name: "hook_and_dry_run_valid",
|
||||
args: []string{"prime", "--hook", "--dry-run"},
|
||||
wantError: false, // May fail for other reasons, but not flag validation
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cmd := exec.Command(gtBin, tc.args...)
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
if tc.wantError {
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got success with output: %s", output)
|
||||
}
|
||||
if tc.errorMsg != "" && !strings.Contains(string(output), tc.errorMsg) {
|
||||
t.Fatalf("expected error containing %q, got: %s", tc.errorMsg, output)
|
||||
}
|
||||
}
|
||||
// For non-error cases, we don't fail on other errors (like "not in workspace")
|
||||
// because we're only testing flag validation
|
||||
if !tc.wantError && tc.errorMsg != "" && strings.Contains(string(output), tc.errorMsg) {
|
||||
t.Fatalf("unexpected error message %q in output: %s", tc.errorMsg, output)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user