/** * Centralized prompt utilities using @clack/prompts. * Provides consistent UX across all interactive commands. * * @module */ import * as p from "@clack/prompts"; import type { ICoolifyApplication } from "../../coolify/types.js"; import type { ICoolifyAppState } from "../coolify-state.js"; import type { ICoolifyProject } from "../../coolify/types.js"; import type { ICoolifyEnvironment } from "../../coolify/types.js"; export { isCancel }; /** * Prompt for selecting an application from list. */ export async function promptAppSelection( apps: ICoolifyApplication[], options: { message?: string } = {}, ): Promise { const response = await p.select({ message: options.message || "Select an application:", options: apps.map((app) => ({ label: app.name, value: app.uuid, hint: app.status, })), }); if (p.isCancel(response)) return null; return response as string; } /** * Prompt for selecting multiple applications. */ export async function promptMultiAppSelection( apps: ICoolifyAppState[], options: { message?: string } = {}, ): Promise { const response = await p.multiselect({ message: options.message || "Select applications:", options: [ { label: "All (parallel)", value: "_all" }, ...apps.map((app) => ({ label: app.name, value: app.uuid, hint: app.domain, })), ], required: false, }); if (p.isCancel(response)) return null; return response as string[]; } /** * Prompt for selecting a project. */ export async function promptProjectSelection( projects: ICoolifyProject[], ): Promise { const response = await p.select({ message: "Select a project:", options: projects.map((proj) => ({ label: proj.name, value: proj.uuid, hint: `${proj.environments?.length || 0} environments`, })), }); if (p.isCancel(response)) return null; return response as string; } /** * Prompt for selecting an environment. */ export async function promptEnvironmentSelection( environments: ICoolifyEnvironment[], ): Promise { const response = await p.select({ message: "Select an environment:", options: environments.map((env) => ({ label: env.name, value: env.uuid, hint: `${env.applications?.length || 0} apps`, })), }); if (p.isCancel(response)) return null; return response as string; } /** * Prompt for text input (app name, etc). */ export async function promptText( message: string, options: { placeholder?: string; defaultValue?: string } = {}, ): Promise { const response = await p.text({ message, placeholder: options.placeholder, initialValue: options.defaultValue, }); if (p.isCancel(response)) return null; return response as string; } /** * Prompt for confirmation. */ export async function promptConfirm( message: string, ): Promise { const response = await p.confirm({ message, }); if (p.isCancel(response)) return null; return response as boolean; } /** * Show spinner for async operations. */ export function showSpinner() { return p.spinner(); } /** * Show intro message. */ export function showIntro(title: string) { p.intro(title); } /** * Show outro message. */ export function showOutro(message: string) { p.outro(message); } /** * Show note/group. */ export function showNote(message: string) { p.note(message); }