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
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/agy/agy.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package agy

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -182,7 +183,7 @@ func ResolveAgyBinary(ctx context.Context) (string, error) {
}
}

return "agy", nil
return "", fmt.Errorf("agy: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("agy"); err == nil && path != "" {
Expand Down Expand Up @@ -210,7 +211,7 @@ func ResolveAgyBinary(ctx context.Context) (string, error) {
}
}

return "agy", nil
return "", fmt.Errorf("agy: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) agyBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/aider/aider.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package aider

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -173,7 +174,7 @@ func ResolveAiderBinary(ctx context.Context) (string, error) {
return "", err
}
}
return "aider", nil
return "", fmt.Errorf("aider: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("aider"); err == nil && path != "" {
Expand All @@ -197,7 +198,7 @@ func ResolveAiderBinary(ctx context.Context) (string, error) {
}
}

return "aider", nil
return "", fmt.Errorf("aider: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) aiderBinary(ctx context.Context) (string, error) {
Expand Down
10 changes: 8 additions & 2 deletions backend/internal/adapters/agent/aider/aider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,17 @@ func TestContextCancellation(t *testing.T) {
}

func TestResolveAiderBinaryFallback(t *testing.T) {
// When the binary is not on PATH or any well-known location, the resolver
// MUST surface ports.ErrAgentBinaryNotFound rather than a silent string
// fallback that lets a missing CLI launch into an empty zellij pane.
bin, err := ResolveAiderBinary(context.Background())
if err != nil {
t.Fatalf("err: %v", err)
if !errors.Is(err, ports.ErrAgentBinaryNotFound) {
t.Fatalf("err = %v, want ports.ErrAgentBinaryNotFound", err)
}
return
}
if bin == "" {
t.Fatal("ResolveAiderBinary returned empty string")
t.Fatal("ResolveAiderBinary returned empty string with no error")
}
}
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/amp/amp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package amp

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -176,7 +177,7 @@ func ResolveAmpBinary(ctx context.Context) (string, error) {
return "", err
}
}
return "amp", nil
return "", fmt.Errorf("amp: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("amp"); err == nil && path != "" {
Expand All @@ -203,7 +204,7 @@ func ResolveAmpBinary(ctx context.Context) (string, error) {
}
}

return "amp", nil
return "", fmt.Errorf("amp: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) ampBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/auggie/auggie.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ package auggie

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -201,7 +202,7 @@ func ResolveAuggieBinary(ctx context.Context) (string, error) {
return "", err
}
}
return "auggie", nil
return "", fmt.Errorf("auggie: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("auggie"); err == nil && path != "" {
Expand Down Expand Up @@ -229,7 +230,7 @@ func ResolveAuggieBinary(ctx context.Context) (string, error) {
}
}

return "auggie", nil
return "", fmt.Errorf("auggie: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) auggieBinary(ctx context.Context) (string, error) {
Expand Down
12 changes: 8 additions & 4 deletions backend/internal/adapters/agent/auggie/auggie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,18 @@ func TestSessionInfoNoOp(t *testing.T) {
}

func TestResolveAuggieBinaryFallback(t *testing.T) {
// With a cancelled context the resolver returns the context error rather than
// a binary path; with a live context it always yields a non-empty path.
// When the binary is not on PATH or any well-known location, the resolver
// MUST surface ports.ErrAgentBinaryNotFound rather than a silent string
// fallback that lets a missing CLI launch into an empty zellij pane.
bin, err := ResolveAuggieBinary(context.Background())
if err != nil {
t.Fatalf("ResolveAuggieBinary err = %v", err)
if !errors.Is(err, ports.ErrAgentBinaryNotFound) {
t.Fatalf("err = %v, want ports.ErrAgentBinaryNotFound", err)
}
return
}
if bin == "" {
t.Fatal("ResolveAuggieBinary returned empty path")
t.Fatal("ResolveAuggieBinary returned empty path with no error")
}
}

Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/autohand/autohand.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package autohand

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -225,7 +226,7 @@ func ResolveAutohandBinary(ctx context.Context) (string, error) {
}
}

return "autohand", nil
return "", fmt.Errorf("autohand: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("autohand"); err == nil && path != "" {
Expand All @@ -252,7 +253,7 @@ func ResolveAutohandBinary(ctx context.Context) (string, error) {
}
}

return "autohand", nil
return "", fmt.Errorf("autohand: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) autohandBinary(ctx context.Context) (string, error) {
Expand Down
4 changes: 2 additions & 2 deletions backend/internal/adapters/agent/claudecode/claudecode.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ func ResolveClaudeBinary(ctx context.Context) (string, error) {
return candidate, nil
}
}
return "claude", nil
return "", fmt.Errorf("claude: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("claude"); err == nil && path != "" {
Expand All @@ -333,7 +333,7 @@ func ResolveClaudeBinary(ctx context.Context) (string, error) {
}
}

return "claude", nil
return "", fmt.Errorf("claude: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) claudeBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/cline/cline.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package cline

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -178,7 +179,7 @@ func ResolveClineBinary(ctx context.Context) (string, error) {
}
}

return "cline", nil
return "", fmt.Errorf("cline: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("cline"); err == nil && path != "" {
Expand Down Expand Up @@ -206,7 +207,7 @@ func ResolveClineBinary(ctx context.Context) (string, error) {
}
}

return "cline", nil
return "", fmt.Errorf("cline: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) clineBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/codex/codex.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package codex

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -175,7 +176,7 @@ func ResolveCodexBinary(ctx context.Context) (string, error) {
}
}

return "codex", nil
return "", fmt.Errorf("codex: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("codex"); err == nil && path != "" {
Expand All @@ -202,7 +203,7 @@ func ResolveCodexBinary(ctx context.Context) (string, error) {
}
}

return "codex", nil
return "", fmt.Errorf("codex: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) codexBinary(ctx context.Context) (string, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package continueagent

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -197,7 +198,7 @@ func ResolveContinueBinary(ctx context.Context) (string, error) {
return "", err
}
}
return "cn", nil
return "", fmt.Errorf("cn: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("cn"); err == nil && path != "" {
Expand Down Expand Up @@ -225,7 +226,7 @@ func ResolveContinueBinary(ctx context.Context) (string, error) {
}
}

return "cn", nil
return "", fmt.Errorf("cn: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) continueBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/copilot/copilot.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package copilot

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -189,7 +190,7 @@ func ResolveCopilotBinary(ctx context.Context) (string, error) {
}
}

return "copilot", nil
return "", fmt.Errorf("copilot: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("copilot"); err == nil && path != "" {
Expand Down Expand Up @@ -217,7 +218,7 @@ func ResolveCopilotBinary(ctx context.Context) (string, error) {
}
}

return "copilot", nil
return "", fmt.Errorf("copilot: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) copilotBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/crush/crush.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package crush

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -191,7 +192,7 @@ func ResolveCrushBinary(ctx context.Context) (string, error) {
}
}

return "crush", nil
return "", fmt.Errorf("crush: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("crush"); err == nil && path != "" {
Expand All @@ -218,7 +219,7 @@ func ResolveCrushBinary(ctx context.Context) (string, error) {
}
}

return "crush", nil
return "", fmt.Errorf("crush: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) crushBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/cursor/cursor.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package cursor

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -165,7 +166,7 @@ func ResolveCursorBinary(ctx context.Context) (string, error) {
return "", err
}
}
return "cursor-agent", nil
return "", fmt.Errorf("cursor: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("cursor-agent"); err == nil && path != "" {
Expand All @@ -190,7 +191,7 @@ func ResolveCursorBinary(ctx context.Context) (string, error) {
}
}

return "cursor-agent", nil
return "", fmt.Errorf("cursor: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) cursorBinary(ctx context.Context) (string, error) {
Expand Down
5 changes: 3 additions & 2 deletions backend/internal/adapters/agent/devin/devin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package devin

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -200,7 +201,7 @@ func ResolveDevinBinary(ctx context.Context) (string, error) {
return "", err
}
}
return "devin", nil
return "", fmt.Errorf("devin: %w", ports.ErrAgentBinaryNotFound)
}

if path, err := exec.LookPath("devin"); err == nil && path != "" {
Expand All @@ -227,7 +228,7 @@ func ResolveDevinBinary(ctx context.Context) (string, error) {
}
}

return "devin", nil
return "", fmt.Errorf("devin: %w", ports.ErrAgentBinaryNotFound)
}

func (p *Plugin) devinBinary(ctx context.Context) (string, error) {
Expand Down
Loading
Loading