zz_

app/cli/lib/banner.ts

zzmq.dev@gmail.com/zz / app / cli / lib / banner.ts @ 15050aba Download
Ladder Summary
  • file The module provides utilities for displaying the tool’s ASCII banner and its current version: `readOwnVersion()` walks up the directory tree to read the package’s *package.json* and return the version string, which is cached in the exported `version` constant; `WIDE_BANNER` and `NARROW_BANNER` are pre‑written ASCII art strings that have the placeholder version token replaced with the actual version, and `BANNER` chooses the appropriate one based on the terminal width. Exported symbols: **readOwnVersion**, **version**, **WIDE_BANNER**, **NARROW_BANNER**, **BANNER**.
 // The ASCII banner and version-reading logic, shared between zz.ts
 // (--version/--help) and any command that wants to print the banner
 // itself (work.ts's --stdio mode, so a headless log capture still
 // opens with something identifying what produced it).
 import { readFileSync } from "node:fs";
 import { dirname, join } from "node:path";
 import { fileURLToPath } from "node:url";
 
 // Reads package.json's own version rather than a hardcoded literal --
 // `npm version` is the one standard place a release bump happens, so
 // this is the one place that reads it back, instead of a second
 // string that's easy to forget to update alongside it. Walks upward
 // (not a fixed relative offset) because this file sits at a different
 // depth relative to the package root in dev (cli/lib/banner.ts) vs.
 // built (dist/cli/lib/banner.js) -- a fixed offset would be right for
 // only one of the two.
 export function readOwnVersion(): string {
  let dir = dirname(fileURLToPath(import.meta.url));
  for (;;) {
  const candidate = join(dir, "package.json");
  try {
  return (JSON.parse(readFileSync(candidate, "utf8")) as { version?: string }).version ?? "0.0.0";
  } catch {
  const parent = dirname(dir);
  if (parent === dir) return "0.0.0"; // reached filesystem root -- shouldn't happen, fail soft
  dir = parent;
  }
  }
 }
 
 export const version = readOwnVersion();
 
 // The "v2.0.0"/"v0.1.0" tokens are the one place a real version gets
 // spliced in -- everything else here is verbatim ASCII art, not a
 // generated/figlet call, so it always renders pixel-for-pixel the same
 // regardless of terminal font. WIDE_BANNER uses String.raw so every
 // backslash is taken literally (no escaping needed to match the art
 // exactly); NARROW_BANNER can't use String.raw -- its own art uses
 // literal backtick characters, which still need escaping to not
 // terminate the template literal early regardless of the raw tag, so
 // it's a plain template literal with just those two backticks escaped.
 export const WIDE_BANNER = String.raw`
 __/\\\\\\\\\\\__/\\\\\\\\\\\___________________
  _\///////\\\/__\///////\\\/____________________
  ______/\\\/_________/\\\/___________v2.0.0_____
  ____/\\\/_________/\\\/________________________
  __/\\\\\\\\\\\__/\\\\\\\\\\\__/\\\\\\\\\\\\\\\_
  _\///////////__\///////////__\///////////////__`.replace("v2.0.0", `v${version}`);
 
 // Shown instead of WIDE_BANNER whenever the terminal is narrower than
 // 55 columns -- the wide art simply doesn't fit at common small
 // terminal sizes.
 export const NARROW_BANNER = `
 [_ ,[__ ,
  / / / /
 / /__ / /__ __v0.1.0__
 \`----'\`----'----------'`.replace("v0.1.0", `v${version}`);
 
 // No column-width signal at all (piped output, not a real TTY) keeps
 // the wide banner as the default -- same as the current behavior
 // before this existed, and --simple already exists for automation that
 // wants neither.
 export const BANNER = (process.stdout.columns ?? 9999) < 55 ? NARROW_BANNER : WIDE_BANNER;