Files
magpie/internal/agent/install_missing_test.go
yetone ee3f83b59d agents: DeepSeek Harness Desktop installed is no missing dsh CLI — its version shows instead of 未找到 CLI (star on Discord)
star on Discord: "DeepSeek Harness 就是现在已经有桌面版了,但是他还是非要找CLI".
With DeepSeek Harness Desktop in use and no dsh on PATH, the Agents page
said 未找到 CLI and Install another agent offered npm's dsh: CLIMissing
(#843) took ~/.dsh without a CLI for an uninstall. The desktop app
(DeepSeek Harness.app, com.deepseek.dsh, 0.2.0-rc.2 from
download.deepseek.com) keeps the same ~/.dsh — its own profile,
profiles/desktop/cordis.patch.yml, and .credentials.yaml — and needs no
CLI; its terminal command (Manage dsh Command…) is optional.

- desktopapp.go: dsh's app is known by its bundle id on macOS and by
  %LOCALAPPDATA%\Programs\DeepSeek Harness\DeepSeek Harness.exe on
  Windows (electron-builder per-user NSIS, productName DeepSeek Harness,
  getWindowsInstallationDirName); HasApp says either is installed.
- install.go: CLIMissing is false with the agent's desktop app installed,
  so the GUI row, Install another agent and /api all follow; the app's
  version shows through the existing CLI().App path.
- dsh.go: the restart notice also sees DeepSeek Harness.app running.

The red "已不经过 magpie" line in the report is a separate dshCheck
finding, not caused by the missing CLI: a desktop-only ~/.dsh shaped
from the app's real new-profile template wires cleanly (Check "", no
Drift; TestDshDesktopOnlyWired). The reporter's exact detail is cut off
in the screenshot and is not reproduced.

Run: TestDshDesktopAppIsNoMissingCLI fails on the old code ("with the
desktop app: missing true, offered true"; with the Windows path removed,
"with the Windows app: missing true, offered true"), passes with the
fix. go test -tags nogui ./internal/agent ./internal/gui under a temp
HOME with pinned caches: ok. gofmt -l clean; go vet darwin, GOOS=linux
-tags nogui, GOOS=windows on both packages; go build darwin,
GOOS=linux -tags nogui, GOOS=windows: ok. Not tried: the real desktop
app running live (not installed here; its userData isn't redirected by
a sandbox HOME), a real Windows install.
2026-10-09 12:56:08 +08:00

72 lines
2.7 KiB
Go

package agent
import (
"os"
"path/filepath"
"runtime"
"testing"
"github.com/yetone/magpie/internal/testenv"
)
// An agent whose settings are left but whose CLI is gone (#843: dsh
// uninstalled, ~/.dsh kept) is still listed, and Install another agent
// offers it again, marked; one found where users' tools go though not on
// PATH (#839) isn't missing, nor one whose folder an app keeps too.
func TestCLIMissing(t *testing.T) {
home := t.TempDir()
t.Setenv("HOME", home)
t.Setenv("USERPROFILE", home)
t.Setenv("PATH", t.TempDir())
// no desktop app either, whatever this machine has installed
was := appFolders
appFolders = func() []string { return nil }
t.Cleanup(func() { appFolders = was })
bin := "magpie-test-gone-dsh"
dir := filepath.Join(home, ".dsh")
if err := os.MkdirAll(dir, 0o700); err != nil {
t.Fatal(err)
}
dsh := &Agent{ID: "dsh", Name: "DeepSeek Harness", Icon: "deepseek-color", Bin: bin, Dir: dir, Path: filepath.Join(dir, "config.yaml")}
codex := &Agent{ID: "codex", Name: "Codex", Bin: "magpie-test-gone-codex", Dir: dir, Path: filepath.Join(dir, "config.toml")}
never := &Agent{ID: "crush", Name: "Crush", Bin: "magpie-test-gone-crush", Dir: filepath.Join(home, "nope"), Path: filepath.Join(home, "nope", "crush.json")}
wsl := &Agent{ID: "dsh@wsl:Ubuntu", Name: "DeepSeek Harness", Bin: bin, WSL: "Ubuntu", Dir: dir, Path: filepath.Join(dir, "config.yaml")}
if !dsh.Detected() || !dsh.CLIMissing() {
t.Fatalf("dsh with ~/.dsh and no dsh: detected %v, missing %v", dsh.Detected(), dsh.CLIMissing())
}
if codex.CLIMissing() || never.CLIMissing() || wsl.CLIMissing() {
t.Fatalf("missing: codex %v, crush not here %v, wsl %v", codex.CLIMissing(), never.CLIMissing(), wsl.CLIMissing())
}
got := installsOf([]*Agent{dsh, codex, never, wsl}, "darwin", true)
ids := map[string]Install{}
for _, x := range got {
ids[x.ID] = x
}
if x, ok := ids["dsh"]; !ok || !x.Missing || len(x.Commands) != 1 || x.Commands[0].Command != "npm install -g @deepseek-ai/dsh" {
t.Fatalf("dsh offered as %+v (all: %+v)", x, got)
}
if x, ok := ids["crush"]; !ok || x.Missing {
t.Fatalf("crush, not here at all, offered as %+v", x)
}
if _, ok := ids["codex"]; ok {
t.Fatal("codex, its folder here, offered")
}
// installed in ~/.local/bin, which magpie's PATH hasn't: found
local := filepath.Join(home, ".local", "bin")
if err := os.MkdirAll(local, 0o755); err != nil {
t.Fatal(err)
}
name := bin
if runtime.GOOS == "windows" {
name += ".exe"
}
testenv.Program(t, filepath.Join(local, name), "#!/bin/sh\n")
if dsh.CLIMissing() {
t.Fatal("dsh in ~/.local/bin taken for missing")
}
for _, x := range installsOf([]*Agent{dsh}, "darwin", true) {
t.Fatalf("installed dsh offered: %+v", x)
}
}