import type { AccountBinding, MarketplaceLibrarySnapshot } from './account-plugin-cache'; import { MarketplaceClientError, type MarketplaceClient } from './marketplace-client'; import type { PluginPackageStore } from './package-store'; import { isMakeLoreVersionCompatible } from './release-descriptor'; export const DEFAULT_CHILD_REPLIES_PLUGIN_ID = 'makelore.child-friendly-replies'; /** Defaults use the normal signed Artifact flow and the account's removal receipt. */ export async function installDefaultChildReplies(options: { marketplace: MarketplaceClient; packageStore: PluginPackageStore; clientVersion: string; binding: AccountBinding | null; library: MarketplaceLibrarySnapshot; onInstalled(): Promise; }): Promise { let library = options.library; const binding = options.binding; if (!binding || library.stale) return library; const assertAccount = () => { const current = options.marketplace.getCurrentAccountBinding(); if (current?.accountKey !== binding.accountKey || current?.epoch !== binding.epoch) { throw new MarketplaceClientError('marketplace_account_changed', 409, 'Marketplace account changed'); } }; const pluginId = DEFAULT_CHILD_REPLIES_PLUGIN_ID; const entry = library.items.find((item) => item.pluginId === pluginId); if (entry?.removedAt || entry?.runtimeStatus === 'suspended' || entry?.catalogStatus === 'retired') return library; try { assertAccount(); if (entry && await options.packageStore.getInstalled(pluginId)) return library; const detail = await options.marketplace.readDetail(pluginId); assertAccount(); const release = detail.stableRelease; if (detail.stale || detail.runtimeStatus !== 'enabled' || detail.acquisition !== 'free' || release?.deliveryKind !== 'artifact' || !release.signingKeyId || !release.descriptorSignature || !isMakeLoreVersionCompatible(options.clientVersion, release.minMakeloreVersion, release.maxMakeloreVersion)) return library; if (!entry) { library = await options.marketplace.acquire(pluginId); assertAccount(); } await options.packageStore.resolveAndInstall({ pluginId, makeloreVersion: options.clientVersion, channel: 'stable', }); assertAccount(); await options.onInstalled(); } catch (error) { assertAccount(); if (error instanceof MarketplaceClientError && error.code === 'marketplace_account_changed') throw error; // An unavailable default must not hide the rest of the Library. A later // session/list refresh retries; no local success or removal receipt is invented. } return library; }