CLI: preserve active setup plugin lookup

This commit is contained in:
Gustavo Madeira Santana
2026-04-17 12:06:42 -04:00
parent 1ca444081e
commit 64837e1eb9
2 changed files with 76 additions and 1 deletions

View File

@@ -269,6 +269,75 @@ describe("setupChannels workspace shadow exclusion", () => {
expect(collectChannelStatus).not.toHaveBeenCalled();
});
it("uses an active deferred setup plugin without enabling config on selection", async () => {
const setupWizard = {
channel: "custom-chat",
getStatus: vi.fn(async () => ({
channel: "custom-chat",
configured: false,
statusLines: [],
})),
configure: vi.fn(async ({ cfg }: { cfg: Record<string, unknown> }) => ({
cfg: {
...cfg,
channels: {
"custom-chat": { token: "secret" },
},
},
})),
};
const activePlugin = {
id: "custom-chat",
meta: { id: "custom-chat", label: "Custom Chat", blurb: "" },
capabilities: {},
config: {
resolveAccount: vi.fn(() => ({})),
},
setupWizard,
};
listActiveChannelSetupPlugins.mockReturnValue([activePlugin]);
resolveChannelSetupEntries.mockReturnValue({
entries: [
{
id: "custom-chat",
meta: { id: "custom-chat", label: "Custom Chat", blurb: "" },
},
],
installedCatalogEntries: [],
installableCatalogEntries: [],
installedCatalogById: new Map(),
installableCatalogById: new Map(),
});
const select = vi.fn().mockResolvedValueOnce("custom-chat").mockResolvedValueOnce("__done__");
const next = await setupChannels(
{} as never,
{} as never,
{
confirm: vi.fn(async () => true),
note: vi.fn(async () => undefined),
select,
} as never,
{
deferStatusUntilSelection: true,
skipConfirm: true,
skipDmPolicyPrompt: true,
},
);
expect(loadChannelSetupPluginRegistrySnapshotForChannel).not.toHaveBeenCalled();
expect(setupWizard.configure).toHaveBeenCalledWith(
expect.objectContaining({
cfg: {},
}),
);
expect(next).toEqual({
channels: {
"custom-chat": { token: "secret" },
},
});
});
it("loads the selected bundled catalog plugin without writing explicit plugin enablement", async () => {
const setupWizard = {
channel: "telegram",

View File

@@ -125,8 +125,14 @@ export async function setupChannels(
scopedPluginsById.set(channel, plugin);
options?.onResolvedPlugin?.(channel, plugin);
};
const activePluginsById = new Map<ChannelChoice, ChannelSetupPlugin>();
const rememberActivePlugin = (plugin: ChannelSetupPlugin) => {
activePluginsById.set(plugin.id, plugin);
return plugin;
};
const getVisibleChannelPlugin = (channel: ChannelChoice): ChannelSetupPlugin | undefined =>
scopedPluginsById.get(channel) ??
activePluginsById.get(channel) ??
(deferStatusUntilSelection ? undefined : getChannelSetupPlugin(channel));
const listVisibleInstalledPlugins = (params?: {
includeRegistry?: boolean;
@@ -135,7 +141,7 @@ export async function setupChannels(
const merged = new Map<string, ChannelSetupPlugin>();
const registryPlugins = includeRegistry
? listChannelSetupPlugins()
: listActiveChannelSetupPlugins();
: listActiveChannelSetupPlugins().map(rememberActivePlugin);
for (const plugin of registryPlugins) {
if (shouldShowChannelInSetup(plugin.meta)) {
merged.set(plugin.id, plugin);