chore: add lobster CLI banner art
This commit is contained in:
@@ -33,6 +33,41 @@ export function formatCliBannerLine(
|
|||||||
return `${title} ${version} (${commitLabel}) — ${tagline}`;
|
return `${title} ${version} (${commitLabel}) — ${tagline}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LOBSTER_ASCII = [
|
||||||
|
"░████░█░░░░░█████░█░░░█░███░░████░░████░░▀█▀",
|
||||||
|
"█░░░░░█░░░░░█░░░█░█░█░█░█░░█░█░░░█░█░░░█░░█░",
|
||||||
|
"█░░░░░█░░░░░█████░█░█░█░█░░█░████░░█░░░█░░█░",
|
||||||
|
"█░░░░░█░░░░░█░░░█░█░█░█░█░░█░█░░█░░█░░░█░░█░",
|
||||||
|
"░████░█████░█░░░█░░█░█░░███░░████░░░███░░░█░",
|
||||||
|
" 🦞 FRESH DAILY 🦞",
|
||||||
|
];
|
||||||
|
|
||||||
|
export function formatCliBannerArt(options: BannerOptions = {}): string {
|
||||||
|
const rich = options.richTty ?? isRich();
|
||||||
|
if (!rich) return LOBSTER_ASCII.join("\n");
|
||||||
|
|
||||||
|
const colorChar = (ch: string) => {
|
||||||
|
if (ch === "█") return theme.accentBright(ch);
|
||||||
|
if (ch === "░") return theme.accentDim(ch);
|
||||||
|
if (ch === "▀") return theme.accent(ch);
|
||||||
|
return theme.muted(ch);
|
||||||
|
};
|
||||||
|
|
||||||
|
const colored = LOBSTER_ASCII.map((line) => {
|
||||||
|
if (line.includes("FRESH DAILY")) {
|
||||||
|
return (
|
||||||
|
theme.muted(" ") +
|
||||||
|
theme.accent("🦞") +
|
||||||
|
theme.info(" FRESH DAILY ") +
|
||||||
|
theme.accent("🦞")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return [...line].map(colorChar).join("");
|
||||||
|
});
|
||||||
|
|
||||||
|
return colored.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
export function emitCliBanner(version: string, options: BannerOptions = {}) {
|
export function emitCliBanner(version: string, options: BannerOptions = {}) {
|
||||||
if (bannerEmitted) return;
|
if (bannerEmitted) return;
|
||||||
const argv = options.argv ?? process.argv;
|
const argv = options.argv ?? process.argv;
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ import { autoMigrateLegacyState } from "../infra/state-migrations.js";
|
|||||||
import { defaultRuntime } from "../runtime.js";
|
import { defaultRuntime } from "../runtime.js";
|
||||||
import { isRich, theme } from "../terminal/theme.js";
|
import { isRich, theme } from "../terminal/theme.js";
|
||||||
import { VERSION } from "../version.js";
|
import { VERSION } from "../version.js";
|
||||||
import { emitCliBanner, formatCliBannerLine } from "./banner.js";
|
import {
|
||||||
|
emitCliBanner,
|
||||||
|
formatCliBannerArt,
|
||||||
|
formatCliBannerLine,
|
||||||
|
} from "./banner.js";
|
||||||
import { registerBrowserCli } from "./browser-cli.js";
|
import { registerBrowserCli } from "./browser-cli.js";
|
||||||
import { hasExplicitOptions } from "./command-options.js";
|
import { hasExplicitOptions } from "./command-options.js";
|
||||||
import { registerCronCli } from "./cron-cli.js";
|
import { registerCronCli } from "./cron-cli.js";
|
||||||
@@ -95,8 +99,10 @@ export function buildProgram() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
program.addHelpText("beforeAll", () => {
|
program.addHelpText("beforeAll", () => {
|
||||||
const line = formatCliBannerLine(PROGRAM_VERSION, { richTty: isRich() });
|
const rich = isRich();
|
||||||
return `\n${line}\n`;
|
const art = formatCliBannerArt({ richTty: rich });
|
||||||
|
const line = formatCliBannerLine(PROGRAM_VERSION, { richTty: rich });
|
||||||
|
return `\n${art}\n${line}\n`;
|
||||||
});
|
});
|
||||||
|
|
||||||
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
||||||
@@ -231,7 +237,7 @@ export function buildProgram() {
|
|||||||
.option("--mode <mode>", "Wizard mode: local|remote")
|
.option("--mode <mode>", "Wizard mode: local|remote")
|
||||||
.option(
|
.option(
|
||||||
"--auth-choice <choice>",
|
"--auth-choice <choice>",
|
||||||
"Auth: oauth|claude-cli|openai-codex|codex-cli|antigravity|gemini-api-key|apiKey|minimax|skip",
|
"Auth: oauth|claude-cli|token|openai-codex|codex-cli|antigravity|gemini-api-key|apiKey|minimax|skip",
|
||||||
)
|
)
|
||||||
.option("--anthropic-api-key <key>", "Anthropic API key")
|
.option("--anthropic-api-key <key>", "Anthropic API key")
|
||||||
.option("--gemini-api-key <key>", "Gemini API key")
|
.option("--gemini-api-key <key>", "Gemini API key")
|
||||||
@@ -260,6 +266,7 @@ export function buildProgram() {
|
|||||||
authChoice: opts.authChoice as
|
authChoice: opts.authChoice as
|
||||||
| "oauth"
|
| "oauth"
|
||||||
| "claude-cli"
|
| "claude-cli"
|
||||||
|
| "token"
|
||||||
| "openai-codex"
|
| "openai-codex"
|
||||||
| "codex-cli"
|
| "codex-cli"
|
||||||
| "antigravity"
|
| "antigravity"
|
||||||
|
|||||||
Reference in New Issue
Block a user