Skip to content
Open
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
10 changes: 5 additions & 5 deletions backend/internal/adapters/agent/grok/grok.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// hook installation (which writes .claude/settings.local.json with AO
// hook commands). Grok will pick them up via its compat layer.
//
// Launch uses `-p <prompt>` for the initial task (in-command delivery).
// Permission bypass uses `--always-approve`. We also pass `--no-auto-update`
// Launch uses a positional prompt for the initial task (in-command delivery).
// Permission handling uses `--permission-mode`. We also pass `--no-auto-update`
// for headless/scripted use (parity with Codex no-update).
// Restore prefers the hook-captured native session id via `-r <id>`.
//
Expand Down Expand Up @@ -67,8 +67,8 @@ func (p *Plugin) Manifest() adapters.Manifest {
}
}

// GetLaunchCommand builds `grok --no-auto-update [--permission-mode <mode>] -p <prompt>`.
// Prompt is delivered via -p (in command).
// GetLaunchCommand builds `grok --no-auto-update [--permission-mode <mode>] [-- prompt]`.
// Prompt is delivered positionally so Grok starts an interactive coding session.
//
// Uses --permission-mode (acceptEdits / auto / bypassPermissions) to match
// `grok -h` output. Default omits the flag so Grok uses its config.
Expand All @@ -82,7 +82,7 @@ func (p *Plugin) GetLaunchCommand(ctx context.Context, cfg ports.LaunchConfig) (
appendApprovalFlags(&cmd, cfg.Permissions)

if cfg.Prompt != "" {
cmd = append(cmd, "-p", cfg.Prompt)
cmd = append(cmd, "--", cfg.Prompt)
}

return cmd, nil
Expand Down
36 changes: 32 additions & 4 deletions backend/internal/adapters/agent/grok/grok_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ func TestGetLaunchCommand(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
wantPrefix := []string{"grok", "--no-auto-update", "--permission-mode", "bypassPermissions", "-p", "do the thing"}
wantPrefix := []string{"grok", "--no-auto-update", "--permission-mode", "bypassPermissions", "--", "do the thing"}
if !reflect.DeepEqual(cmd, wantPrefix) {
t.Fatalf("cmd = %#v, want prefix %#v", cmd, wantPrefix)
}
assertNoPromptFlag(t, cmd)
}

func TestGetLaunchCommandDefaultPerms(t *testing.T) {
Expand All @@ -72,12 +73,14 @@ func TestGetLaunchCommandDefaultPerms(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
if len(cmd) < 4 || cmd[0] != "grok" || cmd[1] != "--no-auto-update" || cmd[2] != "-p" {
t.Fatalf("cmd = %#v, want grok --no-auto-update -p ...", cmd)
want := []string{"grok", "--no-auto-update", "--", "fix it"}
if !reflect.DeepEqual(cmd, want) {
t.Fatalf("cmd = %#v, want %#v", cmd, want)
}
if strings.Contains(strings.Join(cmd, " "), "permission-mode") {
t.Fatal("should not have --permission-mode for default perms")
}
assertNoPromptFlag(t, cmd)
}

func TestGetLaunchCommandAcceptEdits(t *testing.T) {
Expand All @@ -89,10 +92,35 @@ func TestGetLaunchCommandAcceptEdits(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
want := []string{"grok", "--no-auto-update", "--permission-mode", "acceptEdits", "-p", "refactor auth"}
want := []string{"grok", "--no-auto-update", "--permission-mode", "acceptEdits", "--", "refactor auth"}
if !reflect.DeepEqual(cmd, want) {
t.Fatalf("cmd = %#v, want %#v", cmd, want)
}
assertNoPromptFlag(t, cmd)
}

func TestGetLaunchCommandTerminatesFlagsBeforeLeadingDashPrompt(t *testing.T) {
plugin := &Plugin{resolvedBinary: "grok"}
cmd, err := plugin.GetLaunchCommand(context.Background(), ports.LaunchConfig{
Prompt: "-add a health check",
})
if err != nil {
t.Fatalf("err: %v", err)
}
want := []string{"grok", "--no-auto-update", "--", "-add a health check"}
if !reflect.DeepEqual(cmd, want) {
t.Fatalf("cmd = %#v, want %#v", cmd, want)
}
assertNoPromptFlag(t, cmd)
}

func assertNoPromptFlag(t *testing.T, cmd []string) {
t.Helper()
for _, arg := range cmd {
if arg == "-p" || arg == "--single" {
t.Fatalf("cmd = %#v unexpectedly contains single-turn prompt flag %q", cmd, arg)
}
}
}

func TestGetRestoreCommand(t *testing.T) {
Expand Down
Loading