



























@@ -9,6 +9,11 @@ import {
99} from "./agents.bind.test-support.js";
1010import { baseConfigSnapshot } from "./test-runtime-config-helpers.js";
111112+const pluginRegistryMocks = vi.hoisted(() => ({
13+loadPluginRegistrySnapshot: vi.fn(() => ({})),
14+listPluginContributionIds: vi.fn(() => ["external-chat"]),
15+}));
16+1217vi.mock("../agents/agent-scope.js", () => ({
1318listAgentEntries: (
1419cfg: {
@@ -28,6 +33,11 @@ vi.mock("../config/bindings.js", () => ({
2833(cfg.bindings ?? []).filter((binding) => Boolean(binding.match)),
2934}));
303536+vi.mock("../plugins/plugin-registry.js", () => ({
37+loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot,
38+listPluginContributionIds: pluginRegistryMocks.listPluginContributionIds,
39+}));
40+3141type BindingResolverTestPlugin = Pick<ChannelPlugin, "id" | "meta" | "capabilities" | "config"> & {
3242setup?: Pick<NonNullable<ChannelPlugin["setup"]>, "resolveBindingAccountId">;
3343};
@@ -59,6 +69,12 @@ function createBindingResolverTestPlugin(params: {
5969}
60706171vi.mock("../channels/plugins/index.js", () => {
72+return {
73+getLoadedChannelPlugin: () => undefined,
74+};
75+});
76+77+vi.mock("../channels/plugins/bundled.js", () => {
6278const knownChannels = new Map([
6379[
6480"discord",
@@ -78,17 +94,10 @@ vi.mock("../channels/plugins/index.js", () => {
7894],
7995]);
8096return {
81-getChannelPlugin: (channel: string) => {
97+getBundledChannelSetupPlugin: (channel: string) => {
8298const normalized = channel.trim().toLowerCase();
8399return knownChannels.get(normalized);
84100},
85-normalizeChannelId: (channel: string) => {
86-const normalized = channel.trim().toLowerCase();
87-if (knownChannels.has(normalized)) {
88-return normalized;
89-}
90-return undefined;
91-},
92101};
93102});
94103@@ -104,6 +113,8 @@ describe("agents bind/unbind commands", () => {
104113105114beforeEach(() => {
106115resetAgentsBindTestHarness();
116+pluginRegistryMocks.loadPluginRegistrySnapshot.mockClear();
117+pluginRegistryMocks.listPluginContributionIds.mockClear();
107118});
108119109120it("lists all bindings by default", async () => {
@@ -141,6 +152,29 @@ describe("agents bind/unbind commands", () => {
141152expect(runtime.exit).not.toHaveBeenCalled();
142153});
143154155+it("binds manifest-known external channels without loading plugin runtime", async () => {
156+readConfigFileSnapshotMock.mockResolvedValue({
157+ ...baseConfigSnapshot,
158+config: {},
159+});
160+161+await agentsBindCommand({ bind: ["external-chat:work"] }, runtime);
162+163+expect(writeConfigFileMock).toHaveBeenCalledWith(
164+expect.objectContaining({
165+bindings: [
166+{
167+type: "route",
168+agentId: "main",
169+match: { channel: "external-chat", accountId: "work" },
170+},
171+],
172+}),
173+);
174+expect(pluginRegistryMocks.loadPluginRegistrySnapshot).toHaveBeenCalled();
175+expect(runtime.exit).not.toHaveBeenCalled();
176+});
177+144178it("unbinds all routes for an agent", async () => {
145179readConfigFileSnapshotMock.mockResolvedValue({
146180 ...baseConfigSnapshot,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。