Files
multica/packages/core/runtimes/cli-version.test.ts
Naiyuan Qing f0d6d88069 fix(views): resolve handoff-note version gate locally for direct agent assigns (#4585)
The run-confirm interception box gated its handoff-note field on the
preview round-trip's `handoff_supported`, so every open showed a
"checking…" wait before the note box could even be used — to learn
something the client already holds. For a concrete agent assignee the
target runtime is exactly that agent's, and its CLI version is already
warm in the prefetched agent + runtime caches, so the box can settle
synchronously, the same way the quick-create version gate does.

Add a frontend `handoffSupported` mirror of the server's
MinHandoffCLIVersion gate, resolve the agent → runtime → cli_version
locally, and drive the note box from that verdict without waiting on
loading. Squad / batch-status / unresolved-agent paths — whose resolved
trigger set is only known server-side — keep falling back to the
preview's `handoff_supported`, unchanged.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-06-26 09:21:09 +08:00

58 lines
2.3 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
checkQuickCreateCliVersion,
handoffSupported,
MIN_HANDOFF_CLI_VERSION,
} from "./cli-version";
describe("checkQuickCreateCliVersion", () => {
it("returns ok for a tagged release at or above the minimum", () => {
expect(checkQuickCreateCliVersion("v0.2.21").state).toBe("ok");
expect(checkQuickCreateCliVersion("0.3.1").state).toBe("ok");
});
it("returns too_old for a tagged release below the minimum", () => {
expect(checkQuickCreateCliVersion("v0.2.20").state).toBe("too_old");
expect(checkQuickCreateCliVersion("v0.2.15").state).toBe("too_old");
});
it("returns missing for empty or unparsable input", () => {
expect(checkQuickCreateCliVersion("").state).toBe("missing");
expect(checkQuickCreateCliVersion(undefined).state).toBe("missing");
expect(checkQuickCreateCliVersion("not-a-version").state).toBe("missing");
});
it("treats git-describe dev builds as ok regardless of base tag", () => {
expect(checkQuickCreateCliVersion("v0.2.15-235-gdaf0e935").state).toBe("ok");
expect(checkQuickCreateCliVersion("v0.2.15-235-gdaf0e935-dirty").state).toBe("ok");
expect(checkQuickCreateCliVersion("0.1.0-1-gabc1234").state).toBe("ok");
});
});
// Mirrors server/pkg/agent/handoff_version_test.go so the frontend soft-gate
// signal and the server's authoritative one agree by construction.
describe("handoffSupported", () => {
it("supports a tagged release at or above the minimum", () => {
expect(handoffSupported(MIN_HANDOFF_CLI_VERSION)).toBe(true);
expect(handoffSupported("0.4.0")).toBe(true);
expect(handoffSupported("v0.3.28")).toBe(true);
});
it("does not support a tagged release below the minimum", () => {
expect(handoffSupported("0.3.26")).toBe(false);
expect(handoffSupported("0.2.21")).toBe(false);
});
it("fails closed on empty or unparsable input", () => {
expect(handoffSupported("")).toBe(false);
expect(handoffSupported(undefined)).toBe(false);
expect(handoffSupported(null)).toBe(false);
expect(handoffSupported("garbage")).toBe(false);
});
it("treats git-describe dev builds as supported regardless of base tag", () => {
expect(handoffSupported("v0.3.0-5-gabc1234")).toBe(true);
expect(handoffSupported("v0.1.0-235-gdaf0e935-dirty")).toBe(true);
});
});