Files
multica/server/internal/daemon/agent_command_names_test.go
Jordan c27919a4d0 feat(agents): add DevEco Code (deveco) runtime agent (MUL-4050) (#4916)
Adds DevEco Code (Huawei's HarmonyOS coding agent, built on the OpenCode engine) as a first-class runtime provider: backend/model parser, daemon discovery (probe + login-shell list + Windows .cmd native resolver), runtime profile migration (protocol_family whitelist), provider UI, metrics, and four-language docs. MCP injection is deferred (UI gates it off). Migration numbered 175.
2026-07-14 15:21:45 +08:00

66 lines
1.9 KiB
Go

package daemon
import (
"go/ast"
"go/parser"
"go/token"
"sort"
"testing"
)
// TestDefaultAgentCommandNamesCoversAllProbes guards the invariant documented
// on defaultAgentCommandNames: the shell-fallback resolver only pre-fetches
// canonical paths for the bare command names in that list, so every agent the
// LoadConfig probe loop tries must appear there. A GUI/Launchpad-started
// daemon does not inherit the interactive shell PATH, so an agent missing from
// this list is undetectable when its binary lives only on the login-shell PATH
// (e.g. an `npm install -g` global). This test parses config.go's probe(...)
// calls so a new probe can't silently diverge from the fallback list.
func TestDefaultAgentCommandNamesCoversAllProbes(t *testing.T) {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "config.go", nil, 0)
if err != nil {
t.Fatalf("parse config.go: %v", err)
}
known := make(map[string]bool, len(defaultAgentCommandNames))
for _, name := range defaultAgentCommandNames {
known[name] = true
}
var missing []string
ast.Inspect(file, func(n ast.Node) bool {
call, ok := n.(*ast.CallExpr)
if !ok {
return true
}
ident, ok := call.Fun.(*ast.Ident)
if !ok || ident.Name != "probe" {
return true
}
// probe(envPathVar, commandName, envModelVar): the command name is the
// second argument and is the value pre-fetched by the shell fallback.
if len(call.Args) < 2 {
return true
}
lit, ok := call.Args[1].(*ast.BasicLit)
if !ok || lit.Kind != token.STRING {
return true
}
name := lit.Value
if len(name) >= 2 {
name = name[1 : len(name)-1] // strip surrounding quotes
}
if !known[name] {
missing = append(missing, name)
}
return true
})
if len(missing) > 0 {
sort.Strings(missing)
t.Fatalf("probe() command names missing from defaultAgentCommandNames: %v; "+
"add them so GUI-launched daemons can resolve these agents via the login shell", missing)
}
}