mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-13 13:18:56 +02:00
* feat(daemon): add minimum Claude Code version check during runtime registration The daemon now validates the detected agent CLI version against a minimum requirement before registering a runtime. Claude Code requires >= 2.0.0 (when --output-format stream-json and --permission-mode bypassPermissions were introduced). Older versions are skipped with a warning log, preventing silent failures. Closes #569 * feat(daemon): add minimum Codex CLI version check (>= 0.100.0) The `codex app-server --listen stdio://` flag was introduced in v0.100.0. Older versions lack this flag and fail silently. Add codex to the MinVersions map so the daemon skips outdated codex CLIs with a clear warning, matching the existing Claude version check. Refs #490
80 lines
2.0 KiB
Go
80 lines
2.0 KiB
Go
package agent
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseSemver(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
want semver
|
|
wantErr bool
|
|
}{
|
|
{"2.0.0", semver{2, 0, 0}, false},
|
|
{"v2.1.100", semver{2, 1, 100}, false},
|
|
{"2.1.100 (Claude Code)", semver{2, 1, 100}, false},
|
|
{"codex-cli 0.118.0", semver{0, 118, 0}, false},
|
|
{"1.0.20", semver{1, 0, 20}, false},
|
|
{"invalid", semver{}, true},
|
|
{"", semver{}, true},
|
|
}
|
|
for _, tt := range tests {
|
|
got, err := parseSemver(tt.input)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("parseSemver(%q) error = %v, wantErr %v", tt.input, err, tt.wantErr)
|
|
continue
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("parseSemver(%q) = %v, want %v", tt.input, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSemverLessThan(t *testing.T) {
|
|
tests := []struct {
|
|
a, b semver
|
|
want bool
|
|
}{
|
|
{semver{1, 0, 0}, semver{2, 0, 0}, true},
|
|
{semver{2, 0, 0}, semver{1, 0, 0}, false},
|
|
{semver{2, 0, 0}, semver{2, 1, 0}, true},
|
|
{semver{2, 1, 0}, semver{2, 0, 0}, false},
|
|
{semver{2, 1, 12}, semver{2, 1, 13}, true},
|
|
{semver{2, 1, 13}, semver{2, 1, 12}, false},
|
|
{semver{2, 0, 0}, semver{2, 0, 0}, false},
|
|
}
|
|
for _, tt := range tests {
|
|
got := tt.a.lessThan(tt.b)
|
|
if got != tt.want {
|
|
t.Errorf("%v.lessThan(%v) = %v, want %v", tt.a, tt.b, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCheckMinVersion(t *testing.T) {
|
|
tests := []struct {
|
|
agentType string
|
|
version string
|
|
wantErr bool
|
|
}{
|
|
{"claude", "2.0.0", false},
|
|
{"claude", "2.1.100", false},
|
|
{"claude", "2.1.100 (Claude Code)", false},
|
|
{"claude", "v2.0.0", false},
|
|
{"claude", "1.0.128", true},
|
|
{"claude", "1.9.99", true},
|
|
{"claude", "invalid", true},
|
|
{"codex", "codex-cli 0.118.0", false},
|
|
{"codex", "codex-cli 0.100.0", false},
|
|
{"codex", "codex-cli 0.99.0", true},
|
|
{"codex", "codex-cli 0.50.0", true},
|
|
{"unknown", "1.0.0", false},
|
|
}
|
|
for _, tt := range tests {
|
|
err := CheckMinVersion(tt.agentType, tt.version)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("CheckMinVersion(%q, %q) error = %v, wantErr %v", tt.agentType, tt.version, err, tt.wantErr)
|
|
}
|
|
}
|
|
}
|