feat: startup banner with Elastic brand colors#256
Merged
Conversation
Renders a multi-color ASCII art logo on bare `elastic` invocation (the no-args help screen). The Elastic brand gradient runs across five rows: pink -> yellow -> teal -> blue -> light-blue. Three ways to suppress: - No TTY (pipe / subprocess / LLM tool use): always silent - ELASTIC_NO_BANNER=1 env var: always silent - banner: false in the config file: silent for that user's session Config integration: - banner field added to ConfigFileSchema and StructuralConfigSchema - Threaded through loader.ts (resolveContext + loadConfig pipeline) - Preserved on read/write round-trips in writer.ts (readRawConfig, serializeConfig with stable key ordering after commands) - ResolvedConfig carries banner?: boolean to the CLI entrypoint
✅MegaLinter analysis: Success
See detailed reports in MegaLinter artifacts MegaLinter is graciously provided by OX Security |
When the user passes --inline-secrets, there is no reason to call getSecretStore() (which runs `security -h` on macOS with a 2-second timeout). Skip the probe entirely by passing null as the store and short-circuiting isAvailable() in applyFieldUpdates. This removes ~2s of latency from integration tests that use --inline-secrets, preventing flaky timeouts against Bun's 5000ms limit.
…entries exist purgeContextSecrets now checks for resolver expressions first and returns early if there are none — skipping the OS keychain probe entirely. The probe (PowerShell on Windows, `security` on macOS) only runs when there is actually a $(…) expression to delete. This prevents the Windows CI integration tests from timing out: contexts created with --inline-secrets have no resolver expressions, so the 5-second PowerShell probe was occurring for nothing.
Contributor
Author
|
N.B. I also fixed a flakey test on bun windows in this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a multi-color ASCII art startup banner shown when the CLI is invoked with no arguments (the help/landing screen). The Elastic brand gradient sweeps across five rows: pink → yellow → teal → blue → light-blue.
src/lib/logo.tsmodule handles detection and renderingbanner: falseconfig file field to suppress per-userELASTIC_NO_BANNER=1env var to suppress globallyToken-safe by default
When an LLM or script invokes the CLI as a subprocess, stdout is piped (no TTY).
renderLogodetects this and returns an empty string — no tokens wasted on decorative output. This is unconditional: no env var or flag needed on the caller side.The suppression hierarchy (highest to lowest precedence):
ELASTIC_NO_BANNER=1— always silentbanner: falsein config file — silent for that user's sessionColor tiers
The banner degrades gracefully based on terminal capability:
COLORTERM=truecolor\x1b[38;2;R;G;BmTERM=*256*\x1b[38;5;Nm\x1b[9XmNO_COLORConfig schema changes
banneris a top-level field alongsidecommands:Threaded through the full config pipeline:
StructuralConfigSchema→ConfigFileSchema→resolveContext→ResolvedConfig. Also preserved on read/write round-trips inwriter.tswith stable key ordering (current_context→contexts→commands→banner).Open question: scope of the banner
Currently the banner only appears on bare
elastic(no args). This is intentional — showing it on every subcommand invocation would quickly become noise. If we want to show it in other contexts (e.g.elastic --help, or a future interactive/REPL mode), we should be deliberate about which entry points trigger it rather than adding it broadly.Test plan
elastic(no args, real TTY) — banner renders with Elastic gradient colorselastic | cat(piped) — no banner outputELASTIC_NO_BANNER=1 elastic— no banner outputNO_COLOR=1 elastic— plain text fallback (elastic CLI v0.1.0-alpha.1)banner: false— no banner outputbannerfield — banner shows (default enabled)elastic stack es search ...— no banner (banner is no-args only)elastic config context list— no banner