/** * Secret list command */ import { eq } from 'drizzle-orm'; import { getDb } from '../../db/client'; import { modules, secrets } from '../../db/schema'; import { getArg, validateRequiredArgs } from '../parser'; import type { CommandResult } from '../types'; /** * Handle secret list command * * Usage: celilo secret list * * Lists all secrets declared in the module manifest and shows which ones are configured. * * @param args - Command arguments * @returns Command result */ export async function handleSecretList(args: string[]): Promise { // Validate arguments const error = validateRequiredArgs(args, 1); if (error) { return { success: false, error: `${error}\n\nUsage: celilo secret list `, }; } const moduleId = getArg(args, 0); if (!moduleId) { return { success: false, error: 'Module ID is required', }; } const db = getDb(); // Check if module exists const module = db.select().from(modules).where(eq(modules.id, moduleId)).get(); if (!module) { return { success: false, error: `Module not found: ${moduleId}`, }; } // Get declared secrets from manifest const manifest = module.manifestData as Record; const secretsSection = manifest.secrets as | { declares?: Array<{ name: string; type?: string; required?: boolean; description?: string }>; } | undefined; const declaredSecrets = secretsSection?.declares || []; if (declaredSecrets.length === 0) { return { success: true, message: `Module '${moduleId}' declares no secrets`, }; } // Get configured secrets from database const configuredSecrets = db .select({ name: secrets.name }) .from(secrets) .where(eq(secrets.moduleId, moduleId)) .all(); const configuredNames = new Set(configuredSecrets.map((s) => s.name)); // Build output const lines: string[] = [`\nSecrets for module '${moduleId}':\n`]; for (const secret of declaredSecrets) { const isConfigured = configuredNames.has(secret.name); const status = isConfigured ? '✓' : '✗'; const statusText = isConfigured ? 'configured' : 'not configured'; const requiredText = secret.required ? ' (required)' : ''; lines.push(` ${status} ${secret.name} - ${statusText}${requiredText}`); if (secret.description) { lines.push(` ${secret.description}`); } } // Summary const configuredCount = declaredSecrets.filter((s) => configuredNames.has(s.name)).length; const totalCount = declaredSecrets.length; lines.push(`\nConfigured: ${configuredCount}/${totalCount}`); return { success: true, message: lines.join('\n'), }; }