/** * Module search command — search the registry for modules * * Usage: celilo module search [] [--registry ] [--limit ] */ import { RegistryClient } from '../../registry/client'; import { getArg, getFlag } from '../parser'; import type { CommandResult } from '../types'; export async function handleModuleSearch( args: string[], flags: Record, ): Promise { const query = getArg(args, 0) ?? ''; const limit = Number(getFlag(flags, 'limit', '25')); const registryUrl = getFlag(flags, 'registry', ''); const client = new RegistryClient(registryUrl || undefined); let result: Awaited>; try { result = await client.search(query, limit); } catch (err) { return { success: false, error: `Registry unreachable: ${err instanceof Error ? err.message : String(err)}`, }; } if (result.modules.length === 0) { return { success: true, message: query ? `No modules found matching "${query}"` : 'Registry is empty', }; } const nameWidth = Math.max(4, ...result.modules.map((m) => m.name.length)); const versionWidth = Math.max(7, ...result.modules.map((m) => m.max_version.length)); const header = `${'NAME'.padEnd(nameWidth)} ${'VERSION'.padEnd(versionWidth)} DESCRIPTION`; const divider = '-'.repeat(header.length); const rows = result.modules.map( (m) => `${m.name.padEnd(nameWidth)} ${m.max_version.padEnd(versionWidth)} ${m.description || ''}`, ); const footer = result.total > result.modules.length ? `\n(showing ${result.modules.length} of ${result.total} — use --limit to see more)` : ''; return { success: true, message: [header, divider, ...rows].join('\n') + footer, data: result, }; }