From 880bfc46b4206f460e6d11a24f67562388e79795 Mon Sep 17 00:00:00 2001 From: Brayden Siew Date: Fri, 3 Apr 2026 08:53:27 +0800 Subject: [PATCH] feat: add any-buddy preview --all gallery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dumps all 23 preset builds to stdout in a scrollable gallery — each entry shows the preset name, rarity, species, star tier, eyes/hat, a one-line description, and the full ASCII sprite, separated by rules. any-buddy preview --all No preflight or binary required: the gallery is entirely static so it works even before any-buddy is applied. Useful for picking a preset before committing to the salt search. Also adds --all to the CliFlags type and to the help text. --- src/cli.ts | 4 +++ src/tui/commands/preview.ts | 52 ++++++++++++++++++++++++++++++++++++- src/types.ts | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index 30da609..272b0d7 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -66,6 +66,8 @@ function parseArgs(argv: string[]): { command: string | undefined; flags: CliFla flags.peak = args[++i]; } else if (arg === '--dump' && next !== undefined) { flags.dump = args[++i]; + } else if (arg === '--all') { + flags.all = true; } else if (arg === '--silent') { flags.silent = true; } else if (arg === '--no-hook') { @@ -137,6 +139,7 @@ Usage: Fully non-interactive any-buddy --preset "Arcane Dragon" Use a curated preset build any-buddy preview Browse pets without applying + any-buddy preview --all Show all preset builds at once any-buddy current Show your current pet any-buddy apply [--silent] Re-apply saved pet after update any-buddy restore Restore original pet @@ -144,6 +147,7 @@ Usage: any-buddy rehatch Delete companion to re-hatch via /buddy Options: + --all (preview only) Dump all preset builds with sprites to stdout --preset Use a curated preset (e.g., "Arcane Dragon", "Royal Capybara") -s, --species Species (duck, goose, blob, cat, dragon, octopus, owl, penguin, turtle, snail, ghost, axolotl, capybara, diff --git a/src/tui/commands/preview.ts b/src/tui/commands/preview.ts index 6399f38..c514c2b 100644 --- a/src/tui/commands/preview.ts +++ b/src/tui/commands/preview.ts @@ -1,10 +1,54 @@ import chalk from 'chalk'; import type { CliFlags } from '@/types.js'; -import { SPECIES, EYES, RARITIES, HATS } from '@/constants.js'; +import { SPECIES, EYES, RARITIES, HATS, RARITY_STARS } from '@/constants.js'; import { runPreflight } from '@/patcher/preflight.js'; import { banner, showPet } from '../display.ts'; import { validateFlag, selectSpecies, selectEyes, selectRarity, selectHat } from '../prompts.ts'; import { allTraitsFlagged } from '../builder/state.ts'; +import { PRESETS } from '@/presets.js'; +import { renderSprite } from '@/sprites/index.js'; +import { RARITY_CHALK } from '../format.ts'; + +function runPreviewAll(): void { + const cols = process.stdout.columns ?? 80; + const rule = chalk.dim(' ' + '─'.repeat(Math.min(cols - 4, 60))); + + console.log(chalk.bold(`\n Preset gallery `) + chalk.dim(`(${PRESETS.length} presets)\n`)); + + for (let i = 0; i < PRESETS.length; i++) { + const p = PRESETS[i]; + const color = RARITY_CHALK[p.rarity] ?? chalk.white; + const stars = RARITY_STARS[p.rarity] ?? ''; + const bones = { + species: p.species, + eye: p.eye, + hat: p.hat, + rarity: p.rarity, + shiny: false, + stats: {}, + }; + const spriteLines = renderSprite(bones, 0); + + console.log(color(` ${p.name} · ${p.rarity} ${p.species} ${stars}`)); + console.log(chalk.dim(` eyes: ${p.eye} hat: ${p.hat} "${p.description}"`)); + console.log(); + for (const line of spriteLines) { + console.log(color(' ' + line)); + } + console.log(); + + if (i < PRESETS.length - 1) { + console.log(rule); + console.log(); + } + } + + console.log( + chalk.dim( + ` ${PRESETS.length} presets total. Run 'any-buddy --preset ""' to apply one.\n`, + ), + ); +} async function runSequentialPreview(flags: CliFlags): Promise { const species = validateFlag('species', flags.species, SPECIES) ?? (await selectSpecies()); @@ -23,6 +67,12 @@ async function runSequentialPreview(flags: CliFlags): Promise { export async function runPreview(flags: CliFlags = {}): Promise { banner(); + + if (flags.all) { + runPreviewAll(); + return; + } + const preflight = runPreflight({ requireBinary: false }); if (!preflight.ok) process.exit(1); diff --git a/src/types.ts b/src/types.ts index 3672231..d020af5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -124,6 +124,7 @@ export interface CliFlags { silent?: boolean; noHook?: boolean; yes?: boolean; + all?: boolean; } export type RngFunction = () => number;