Repository navigation
[terminal-stylist] Terminal output consistency audit: stream-aware styling and interactive accessibility #66520
Closed
Replies: 1 comment
|
This discussion has been marked as outdated by Terminal Stylist. A newer discussion is available at Discussion #66843. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Overview
A static scan covered all 1,438 Go files under
pkg/that do not end in_test.go. This includes 1,288 production files and 150 linter fixtures undertestdata; fixture matches were scanned but excluded from actionable metrics.The terminal layer has a strong foundation: centralized semantic styles, adaptive light/dark colors, TTY-aware rendering helpers, Lipgloss tables, and a shared Huh theme/accessibility wrapper. The main consistency defect is that much of
pkg/cliwrites to stderr using stdout-aware formatters.Key metrics and issues
fmt.Print*/fmt.Fprint*console.*console.RenderTablepath1. High priority — make styling stream-aware by construction
Examples such as
pkg/cli/run_workflow_execution.go:84,pkg/cli/update_workflows.go:77, andpkg/cli/logs_metrics.go:68writeconsole.FormatInfoMessage(...)toos.Stderr.FormatInfoMessage,FormatWarningMessage,FormatSuccessMessage,FormatProgressMessage, andFormatCommandMessageinspect stdout TTY state, while their result is sent to stderr.Consequences:
stdoutredirected +stderrinteractive: useful stderr styling is unexpectedly disabled.stdoutinteractive +stderrredirected: ANSI can be emitted into redirected stderr.*Stderrhelpers.The scan found at least:
FormatInfoMessageFormatWarningMessageFormatSuccessMessageFormatProgressMessageFormatCommandMessageRecommendation: prefer
console.Print*Messagefor direct stderr output. Where composition is required, use the matchingFormat*MessageStderrhelper. Longer term, consider APIs that require an output stream/profile rather than maintaining easily confused stdout/stderr function pairs. Add a static check preventing stdout-aware formatter results from being written to stderr.2. Medium priority — provide a plain, responsive table mode
pkg/console/console.go:318always appliesstyles.RoundedBorder, even when the destination is not a TTY; only colors and row styles are disabled. This avoids ANSI leakage, but piped output still receives Unicode box drawing and padding. The renderer also has no terminal-width budget, while 35 CLI call sites depend on it.Recommendation: select a borderless/ASCII table for non-TTY or accessible output, and accept a width budget derived from the destination terminal. Truncate/wrap lower-priority columns or expose compact output for narrow terminals. Keep current rounded borders and zebra striping for interactive TTYs.
3. Medium priority — detect the input terminal for Huh forms
pkg/console/input.go:21,pkg/console/confirm.go:24,pkg/console/list.go:29, andpkg/console/prompt_form.go:35decide interactivity fromtty.IsStderrTerminal(). The comment ininput.gosays it checks stdin, butpkg/tty/tty.goexposes only stdout/stderr checks. A process can have terminal stderr and piped/closed stdin; Huh then attempts an interactive form without a terminal input. Conversely, the “non-TTY” list/confirm fallbacks still read stdin and can block pipelines.Recommendation: add
tty.IsStdinTerminal(). Require terminal stdin for Huh forms, and make non-interactive behavior explicit: supplied flag/default, clear error, or prompt only when input is intentionally available. Continue rendering the TUI to stderr.4. Low priority — prevent duplicated semantic prefixes
The semantic formatters already add
✓or⚠, but several messages embed another prefix. Examples includepkg/cli/run_interactive.go:101,pkg/cli/project_command.go:166, andpkg/cli/upgrade_command.go:280;pkg/cli/upgrade_command.go:330embedsWarning:insideFormatWarningMessage.Recommendation: pass plain message content to semantic formatters and let the formatter own the icon/label. Add focused tests or a lint check for leading semantic glyphs/labels.
Patterns that are already strong
pkg/styles/theme.gocentralizes semantic colors and provides light/dark variants.pkg/styles/huh_theme.gomaps the same palette into Huh withlipgloss.LightDark, including focused, blurred, selection, button, input, and error states.pkg/console/console.gogates color on TTY state, honors terminal color profiles/NO_COLOR, and centralizes Lipgloss table rendering.pkg/console/prompt_form.goapplies one Huh theme and accessibility mode to forms and cleans up completed prompts only on an interactive stderr.pkg/console/input.gomasks secrets and validates empty values.pkg/console/terminal.goguards raw cursor/screen ANSI behind stderr TTY detection. The other raw-ANSI locations are prompt cursor management and ANSI string processing, so replacing them with Lipgloss would not improve correctness.pkg/console/console.goproduces IDE-parseablefile:line:column: error:diagnostics with context and hints.Files using stderr-aware semantic formatters correctly
pkg/cli/add_interactive_secrets.gopkg/cli/compile_args.gopkg/cli/compile_compiler_setup.gopkg/cli/compile_external_tools.gopkg/cli/compile_file_operations.gopkg/cli/compile_guard_policy_report.gopkg/cli/compile_infrastructure.gopkg/cli/compile_orchestrator.gopkg/cli/compile_pipeline.gopkg/cli/compile_post_processing.gopkg/cli/compile_repository_manifest.gopkg/cli/compile_schedule_calendar.gopkg/cli/compile_stats.gopkg/cli/compile_update_check.gopkg/cli/compile_watch.gopkg/cli/compile_workflow_processor.gopkg/cli/copilot_setup.gopkg/cli/devcontainer.gopkg/cli/mcp_config_file.gopkg/cli/mcp_list_tools.gopkg/cli/org_runner.gopkg/cli/trial_confirmation.gopkg/cli/vscode_config.goFiles with direct stderr/stdout-aware formatter mismatches
pkg/cli/access_log.gopkg/cli/actionlint.gopkg/cli/actions_build_command.gopkg/cli/add_command_orchestrator.gopkg/cli/add_command_resources.gopkg/cli/add_init.gopkg/cli/add_interactive_auth.gopkg/cli/add_interactive_engine.gopkg/cli/add_interactive_git.gopkg/cli/add_interactive_orchestrator.gopkg/cli/add_interactive_schedule.gopkg/cli/add_interactive_workflow.gopkg/cli/add_package_ownership.gopkg/cli/add_skill_rewrite.gopkg/cli/add_workflow_compilation.gopkg/cli/add_workflow_content.gopkg/cli/add_workflow_pr.gopkg/cli/add_workflow_resolution.gopkg/cli/audit_analysis_fanout.gopkg/cli/audit_command.gopkg/cli/audit_cross_run_clusters_render.gopkg/cli/audit_cross_run_render.gopkg/cli/audit_diff_command.gopkg/cli/audit_diff_render.gopkg/cli/audit_group.gopkg/cli/audit_job.gopkg/cli/audit_render_output.gopkg/cli/audit_run_pipeline.gopkg/cli/audit_summary_build.gopkg/cli/audit_threat_detection_session.gopkg/cli/bootstrap_config.gopkg/cli/bootstrap_profile_actions_repo.gopkg/cli/bootstrap_profile_git.gopkg/cli/bootstrap_profile_github_app.gopkg/cli/bootstrap_profile_helpers.gopkg/cli/bootstrap_profile_runner.gopkg/cli/checks_command.gopkg/cli/codemod_bash_single_quoted_args.gopkg/cli/commands.gopkg/cli/compile_external_tools.gopkg/cli/compile_orchestrator.gopkg/cli/copilot_agent.gopkg/cli/copilot_agents.gopkg/cli/copilot_events_jsonl.gopkg/cli/deploy_org.gopkg/cli/deps_outdated.gopkg/cli/deps_report.gopkg/cli/deps_security.gopkg/cli/dispatch.gopkg/cli/domains_command.gopkg/cli/drain3_train.gopkg/cli/enable.gopkg/cli/env_command.gopkg/cli/experiments_analyze_statistics.gopkg/cli/experiments_command.gopkg/cli/experiments_render.gopkg/cli/fetch.gopkg/cli/file_tracker.gopkg/cli/firewall_log.gopkg/cli/fix_command.gopkg/cli/forecast.gopkg/cli/forecast_compute.gopkg/cli/forecast_render.gopkg/cli/forecast_resolution.gopkg/cli/format_command.gopkg/cli/gateway_logs_parsing.gopkg/cli/gateway_logs_rpc.gopkg/cli/generate_action_metadata_command.gopkg/cli/grant.gopkg/cli/grype.gopkg/cli/health_command.gopkg/cli/imports.gopkg/cli/includes.gopkg/cli/init.gopkg/cli/interactive.gopkg/cli/list_workflows_command.gopkg/cli/log_aggregation.gopkg/cli/logs_cache.gopkg/cli/logs_cached_json.gopkg/cli/logs_download.gopkg/cli/logs_download_artifacts.gopkg/cli/logs_download_flatten.gopkg/cli/logs_github_api.gopkg/cli/logs_github_rate_limit_usage.gopkg/cli/logs_metrics.gopkg/cli/logs_multi.gopkg/cli/logs_orchestrator_download.gopkg/cli/logs_orchestrator_filters.gopkg/cli/logs_orchestrator_render.gopkg/cli/logs_orchestrator_stdin.gopkg/cli/logs_parsing_core.gopkg/cli/logs_parsing_engines.gopkg/cli/logs_parsing_firewall.gopkg/cli/logs_parsing_javascript.gopkg/cli/logs_rate_limit.gopkg/cli/logs_report.gopkg/cli/logs_run_processor.gopkg/cli/logs_storage_limit.gopkg/cli/logs_utils.gopkg/cli/logs_work_queue.gopkg/cli/mcp_add.gopkg/cli/mcp_inspect.gopkg/cli/mcp_inspect_inspector.gopkg/cli/mcp_inspect_list.gopkg/cli/mcp_inspect_mcp.gopkg/cli/mcp_inspect_mcp_scripts_files.gopkg/cli/mcp_inspect_mcp_scripts_server.gopkg/cli/mcp_list.gopkg/cli/mcp_list_tools.gopkg/cli/mcp_registry_list.gopkg/cli/mcp_secrets.gopkg/cli/mcp_server_http.gopkg/cli/mcp_validation.gopkg/cli/mcp_workflow_scanner.gopkg/cli/org_issue_pr_helpers.gopkg/cli/org_runner.gopkg/cli/outcomes_command.gopkg/cli/outcomes_history.gopkg/cli/packages.gopkg/cli/poutine.gopkg/cli/pr_automerge.gopkg/cli/pr_command.gopkg/cli/pr_helpers.gopkg/cli/preconditions.gopkg/cli/project_command.gopkg/cli/redacted_domains.gopkg/cli/remove_command.gopkg/cli/resources.gopkg/cli/run_interactive.gopkg/cli/run_push.gopkg/cli/run_workflow_execution.gopkg/cli/run_workflow_tracking.gopkg/cli/run_workflow_validation.gopkg/cli/runner_guard.gopkg/cli/secret_set_command.gopkg/cli/sessions_download.gopkg/cli/setup_repository.gopkg/cli/shell_completion.gopkg/cli/shellcheck.gopkg/cli/signal_aware_poll.gopkg/cli/status_command.gopkg/cli/syft.gopkg/cli/token_usage_find.gopkg/cli/tokens_bootstrap.gopkg/cli/tool_graph.gopkg/cli/trial_helpers.gopkg/cli/trial_repository.gopkg/cli/trial_runner.gopkg/cli/trial_support.gopkg/cli/update_actions_content_refs.gopkg/cli/update_actions_lockfile.gopkg/cli/update_actions_release.gopkg/cli/update_actions_workflow_files.gopkg/cli/update_check.gopkg/cli/update_command.gopkg/cli/update_container_pins.gopkg/cli/update_display.gopkg/cli/update_extension_check.gopkg/cli/update_manifest.gopkg/cli/update_merge.gopkg/cli/update_org.gopkg/cli/update_org_search.gopkg/cli/update_redirects.gopkg/cli/update_workflows.gopkg/cli/upgrade_command.gopkg/cli/upgrade_org.gopkg/cli/view_command.gopkg/cli/workflow_run_metadata.gopkg/cli/workflows.gopkg/cli/yamllint.gopkg/cli/zizmor.goHuh implementation assessment
The codebase uses
Input,Text,Select,MultiSelect, andConfirm; no compelling current use case requires addingNoteorFilePicker. Most forms correctly go throughconsole.NewForm/NewInputForm/NewSelectForm/NewConfirmForm, which gives consistent theming andWithAccessible(...)behavior. Validation is present on required and secret-bearing inputs.Suggested refinements:
TextandMultiSelectpaths inpkg/cli/interactive.go.Next actions
pkg/cli/logs_metrics.go,pkg/cli/trial_repository.go,pkg/cli/pr_command.go, andpkg/cli/run_workflow_execution.go.fmt.Fprint*(stderr, console.Format*Message(...))when a stderr variant exists.References:
All reactions