Skip to content

Implement accessibility preferences: OutputPrefs and emoji prefixes#267

Open
leynos wants to merge 4 commits intomainfrom
respect-accessibility-preferences-ubavwa
Open

Implement accessibility preferences: OutputPrefs and emoji prefixes#267
leynos wants to merge 4 commits intomainfrom
respect-accessibility-preferences-ubavwa

Conversation

@leynos
Copy link
Owner

@leynos leynos commented Feb 12, 2026

Summary

  • Introduces accessibility preferences for output formatting: emoji suppression and consistent semantic prefixes across modes.
  • Adds a centralized OutputPrefs resolution mechanism to determine whether emoji glyphs are allowed and to render localized semantic prefixes accordingly.
  • Integrates Preferences into CLI, status reporting, and main error handling.
  • Adds tests, BDD scenarios, and documentation to cover preference resolution, rendering, and edge cases.

Changes

Core functionality

  • New module: src/output_prefs.rs
    • OutputPrefs struct with emoji flag and helpers to render prefixes (error, warning, success).
    • resolve and resolve_with functions to determine emoji usage from explicit config, NO_COLOR, and NETSUKE_NO_EMOJI environment variables.
    • Prefix rendering uses Fluent localization with an emoji variant when allowed.
  • Status and reporting integration
    • src/runner/mod.rs: create prefs and pass to AccessibleReporter.
    • src/status.rs: AccessibleReporter now holds OutputPrefs and uses it to render completion prefixes (e.g.,
      “✖ Error: …” vs “Error: …”).
    • src/main.rs: on error, prefixes are applied to stderr alongside diagnostic output.

CLI and localization

  • CLI enhancements
    • src/cli/mod.rs: added no_emoji: Option to Cli and documented its behavior.
    • Updated cli_overrides_from_matches to consider no_emoji.
  • Localization updates
    • src/localization/keys.rs: added CLI_FLAG_NO_EMOJI_HELP and semantic prefix keys.
    • locales/en-US/messages.ftl and locales/es-ES/messages.ftl: added semantic prefix messages and help text for no-emoji flag.
    • src/cli_l10n.rs: map new no_emoji help key.

Documentation

  • ExecPlan for accessibility preferences
    • docs/execplans/3-8-2-respect-accessibility-preferences.md: new exec plan outlining constraints, risks, progress, and outcomes.
  • Roadmap status
    • docs/roadmap.md: 3.8.2 entry updated to mark as complete.
  • User guide updates
    • docs/users-guide.md: section added detailing emoji suppression rules and semantic prefixes.

Tests

  • Unit tests
    • New tests in src/output_prefs.rs validating resolve_with behavior and prefix rendering under emoji/no-emoji configurations.
  • BDD tests
    • New feature: tests/features/accessibility_preferences.feature and steps in tests/bdd/steps/accessibility_preferences.rs.
    • Updated fixtures to carry OutputPrefs state and rendered prefixes for assertions.
  • Test coverage
    • 18 unit tests for OutputPrefs resolution and prefix rendering.
    • 10 BDD scenarios covering emoji suppression, explicit no-emoji, NO_COLOR, and CLI parsing for --no-emoji.

Files touched

  • Added: src/output_prefs.rs
  • Added: tests/features/accessibility_preferences.feature
  • Added: tests/bdd/steps/accessibility_preferences.rs
  • Added/updated: src/main.rs, src/runner/mod.rs, src/status.rs, src/cli/mod.rs, src/cli_l10n.rs
  • Updated: src/lib.rs, src/localization/keys.rs
  • Updated: locales/en-US/messages.ftl, locales/es-ES/messages.ftl
  • Updated: docs/execplans/3-8-2-respect-accessibility-preferences.md (new)
  • Updated: docs/roadmap.md
  • Updated: docs/users-guide.md

How to test

  • Build and run
    • NETSUKE_NO_EMOJI=1 cargo run -- build (verify no emoji and semantic prefixes are present/printed)
    • NO_COLOR=1 cargo run -- build (verify no emoji and ASCII prefixes)
    • cargo run -- build with --no-emoji true/false to override auto-detection
  • Run unit tests and lint
    • make check-fmt && make lint && make test
  • Execute the new BDD scenarios under tests/features/accessibility_preferences.feature

Migration and compatibility

  • Public API signatures remain backward compatible; new CLI flag and internal module are opt-in.
  • Default behavior preserves emoji unless auto-detected as disallowed or explicitly disabled.
  • Fluent keys for semantic prefixes are used to render localized text with/without emoji as appropriate.

Risks and notes

  • The AccessibleReporter now depends on OutputPrefs; ensure all call sites construct reporters with proper prefs (handled in runner).
  • Roadmap entry 3.8.2 is completed by this change; ensure docs reflect the updated capabilities.

If you want, I can adjust the PR description to emphasize particular user-facing benefits or tailor the test matrix for CI.

◳ Generated by DevBoxer

📎 Task: https://www.devboxer.com/task/79254424-c0da-4f85-8b04-4116d4aa87d1

- Introduce OutputPrefs struct to encapsulate emoji allowance and semantic prefix formatting.
- Honor NO_COLOR and NETSUKE_NO_EMOJI environment variables and --no-emoji CLI flag.
- Update CLI to include no_emoji option; integrate output preferences into status reporting.
- Add localised semantic prefixes with and without emoji for Error, Warning, Success.
- Provide comprehensive unit and BDD tests covering preference resolution and output.
- Update documentation and roadmap to reflect new accessibility preference support.

This completes accessibility preference support for Netsuke output, ensuring emoji
can be suppressed and semantic prefixes remain consistent across modes.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 12, 2026

Reviewer's Guide

Adds a centralized OutputPrefs abstraction for emoji suppression and semantic prefixes, wires it through CLI parsing, status reporting, and main error handling, and updates localization, docs, and tests to cover accessibility preference behavior.

Sequence diagram for status reporting with OutputPrefs

sequenceDiagram
    actor User
    participant Cli
    participant Main as MainModule
    participant Runner as RunnerModule
    participant OutputPrefsMod as OutputPrefsModule
    participant Reporter as AccessibleReporter
    participant Stderr as StderrStream

    User->>Cli: Invoke netsuke --accessible true --no-emoji true build
    Cli-->>Main: Parsed Cli{accessible: Some(true), no_emoji: Some(true)}

    Main->>OutputPrefsMod: resolve(merged_cli.no_emoji)
    OutputPrefsMod-->>Main: OutputPrefs{emoji: false}

    Main->>Runner: run(&merged_cli)
    Runner->>OutputPrefsMod: resolve(cli.no_emoji)
    OutputPrefsMod-->>Runner: OutputPrefs{emoji: false}
    Runner->>Runner: mode = OutputMode::resolve(cli.accessible)
    Runner->>Reporter: new(prefs)
    Runner-->>Main: Ok(()) after build

    loop build stages
        Runner->>Reporter: report_stage(current, total, description)
        Reporter->>Stderr: write Stage line
    end

    Runner->>Reporter: report_complete(tool_key)
    Reporter->>OutputPrefsMod: success_prefix() on prefs
    OutputPrefsMod-->>Reporter: LocalizedMessage "Success:" (no emoji)
    Reporter->>Stderr: write "Success: {localized status complete message}"
Loading

Sequence diagram for error handling with semantic prefixes

sequenceDiagram
    participant Main as MainModule
    participant OutputPrefsMod as OutputPrefsModule
    participant Runner as RunnerModule
    participant Stderr as StderrStream

    Main->>OutputPrefsMod: resolve(merged_cli.no_emoji)
    OutputPrefsMod-->>Main: OutputPrefs prefs

    Main->>Runner: run(&merged_cli)
    Runner-->>Main: Err(err)

    Main->>OutputPrefsMod: prefs.error_prefix()
    OutputPrefsMod-->>Main: LocalizedMessage prefix

    alt err is RunnerError
        Main->>Main: report = Report::new(runner_err)
        Main->>Stderr: write "{prefix} {report:?}"
    else other error type
        Main->>Stderr: write "{prefix} {other_err}"
    end
Loading

Class diagram for OutputPrefs and related CLI/status structures

classDiagram
    class Cli {
        +bool fetch_default_deny
        +Option~bool~ accessible
        +Option~bool~ no_emoji
        +Option~Command~ command
    }

    class OutputPrefs {
        -bool emoji
        +bool emoji_allowed()
        +LocalizedMessage error_prefix()
        +LocalizedMessage warning_prefix()
        +LocalizedMessage success_prefix()
        +static OutputPrefs resolve(no_emoji: Option~bool~)
        +static OutputPrefs resolve_with(no_emoji: Option~bool~, read_env: Fn~&str -> Option~String~~)
    }

    class StatusReporter {
        <<trait>>
        +report_stage(current: u32, total: u32, description: &str)
        +report_pending(tool_key: &str)
        +report_complete(tool_key: &'static str)
    }

    class AccessibleReporter {
        -OutputPrefs prefs
        +new(prefs: OutputPrefs) AccessibleReporter
        +report_stage(current: u32, total: u32, description: &str)
        +report_pending(tool_key: &str)
        +report_complete(tool_key: &'static str)
    }

    class OutputMode {
        <<enum>>
        Accessible
        Standard
        +static resolve(accessible: Option~bool~) OutputMode
    }

    class RunnerModule {
        +run(cli: &Cli) Result~()~
    }

    class MainModule {
        +main() ExitCode
    }

    Cli --> OutputPrefs : no_emoji
    MainModule ..> OutputPrefs : resolve(no_emoji)
    RunnerModule ..> OutputMode : resolve(accessible)
    RunnerModule ..> OutputPrefs : resolve(no_emoji)
    RunnerModule ..> StatusReporter
    AccessibleReporter ..|> StatusReporter
    AccessibleReporter o--> OutputPrefs
Loading

File-Level Changes

Change Details Files
Introduce OutputPrefs module to resolve emoji usage and provide localized semantic prefixes.
  • Add OutputPrefs struct with emoji flag and helpers for error/warning/success prefixes using Fluent messages and an emoji select argument.
  • Implement resolve and resolve_with to derive emoji allowance from explicit no_emoji config plus NO_COLOR and NETSUKE_NO_EMOJI environment variables, with clear precedence rules.
  • Expose output_prefs as a public module in the crate root and add comprehensive unit tests for resolution logic and prefix rendering, ensuring ASCII-only behavior when emoji is disabled.
src/output_prefs.rs
src/lib.rs
Propagate OutputPrefs into runner status reporting and main error output.
  • Resolve OutputPrefs in runner::run based on cli.no_emoji and pass it into AccessibleReporter only in Accessible mode.
  • Refactor AccessibleReporter into a struct holding OutputPrefs and prepend success_prefix() to completion messages when reporting status.
  • Resolve OutputPrefs in main before running the runner and use error_prefix() to prefix all stderr error diagnostics, both for RunnerError reports and generic errors.
src/runner/mod.rs
src/status.rs
src/main.rs
Extend CLI and localization to support a --no-emoji flag and semantic prefix messages.
  • Add no_emoji: Option field to Cli, include it in Default, argument parsing, and cli_overrides_from_matches so explicit CLI values override config.
  • Add new localization keys for no-emoji flag help and semantic prefixes (error/warning/success), wire them into cli_l10n flag_help_key, and provide English and Spanish Fluent messages with emoji/no variants.
  • Ensure semantic prefixes are used consistently via Fluent localization so that text labels are present regardless of emoji availability.
src/cli/mod.rs
src/cli_l10n.rs
src/localization/keys.rs
locales/en-US/messages.ftl
locales/es-ES/messages.ftl
Document accessibility preferences and mark roadmap item 3.8.2 complete.
  • Add an ExecPlan document for respecting accessibility preferences, describing constraints, risks, decisions, and outcomes for OutputPrefs and emoji suppression behavior.
  • Update roadmap entry 3.8.2 to marked completed with sub-items for honoring NO_COLOR/NETSUKE_NO_EMOJI and maintaining semantic prefixes in all modes.
  • Extend the user guide with a section describing emoji suppression rules, precedence between CLI/env/config, and the guarantee of semantic prefixes with or without emoji.
docs/execplans/3-8-2-respect-accessibility-preferences.md
docs/roadmap.md
docs/users-guide.md
Add BDD coverage and fixtures for accessibility preference behavior and CLI parsing.
  • Introduce a new accessibility_preferences.feature capturing scenarios for env-based emoji suppression, explicit no_emoji settings, prefix rendering behavior, and CLI parsing for --no-emoji true/false.
  • Implement corresponding rstest-bdd step definitions that simulate NO_COLOR/NETSUKE_NO_EMOJI, resolve OutputPrefs with a fake environment, render prefixes, and assert CLI.no_emoji values.
  • Extend the BDD TestWorld fixtures to store simulated emoji-related env vars, resolved OutputPrefs, and rendered prefixes for assertions, and register the new step module in the BDD test harness.
tests/features/accessibility_preferences.feature
tests/bdd/steps/accessibility_preferences.rs
tests/bdd/fixtures/mod.rs
tests/bdd/steps/mod.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

No actionable comments were generated in the recent review. 🎉


Summary by CodeRabbit

  • New Features

    • Added --no-emoji CLI flag and explicit config to suppress emoji glyphs; output also honours NO_COLOR and NETSUKE_NO_EMOJI.
    • Semantic prefixes (Error, Warning, Success) now render emoji or ASCII-only variants based on preferences.
  • Documentation

    • New user-guide section on emoji and accessibility preferences; roadmap item 3.8.2 marked complete.
    • Localised help text added for the no-emoji flag and semantic prefixes.
  • Tests

    • Unit and BDD tests added covering preference resolution and prefix rendering.

Walkthrough

Introduce an output preference system that resolves emoji rendering from CLI (--no-emoji), environment (NO_COLOR, NETSUKE_NO_EMOJI) and configuration; expose OutputPrefs; add localisation keys; and integrate preferences across main, runner and reporters with unit and BDD tests.

Changes

Cohort / File(s) Summary
Core Output Preferences
src/output_prefs.rs, src/lib.rs
Add OutputPrefs with resolve()/resolve_with() to determine emoji allowance and provide error_prefix(), warning_prefix(), success_prefix(); export module; include unit tests.
CLI surface
src/cli/mod.rs, src/cli_l10n.rs
Add no_emoji: Option<bool> to Cli, wire --no-emoji into override extraction, and map flag to localisation key.
Application wiring
src/main.rs, src/runner/mod.rs, src/status.rs
Resolve prefs in main, pass prefs into runner::run(cli, prefs), change AccessibleReporter to store OutputPrefs with new(prefs); use prefs to render prefixes.
Localisation files
locales/en-US/messages.ftl, locales/es-ES/messages.ftl, src/localization/keys.rs
Add cli.flag.no_emoji.help and semantic prefix keys; update ALL_KEYS; introduce Fluent variants for emoji vs ASCII prefixes (note: keys duplicated in locale files).
Documentation & Roadmap
docs/execplans/3-8-2-respect-accessibility-preferences.md, docs/roadmap.md, docs/users-guide.md
Add execplan, mark roadmap item 3.8.2 complete, and document emoji/accessibility preference precedence and controls in user guide.
BDD and unit tests
tests/features/accessibility_preferences.feature, tests/bdd/steps/accessibility_preferences.rs, tests/bdd/steps/mod.rs, tests/bdd/fixtures/mod.rs
Add Gherkin scenarios and Rust step implementations to simulate env and CLI combinations; extend TestWorld with output_prefs, simulated_no_emoji, rendered_prefix.
Test call-site updates
tests/runner_tests.rs, tests/runner_tool_subcommands_tests.rs, tests/bdd/steps/process.rs, tests/runner_tests.rs
Update test call sites to pass output_prefs::resolve(None) to runner::run(); import netsuke::output_prefs where required.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Parser
    participant Main as main()
    participant OutputPrefs as output_prefs::resolve()
    participant Env as Environment
    participant Runner as runner::run()
    participant Reporter as AccessibleReporter
    participant Stderr as Stderr

    CLI->>Main: provide merged_cli (includes no_emoji)
    Main->>OutputPrefs: resolve(merged_cli.no_emoji)
    OutputPrefs->>OutputPrefs: evaluate explicit CLI/config
    alt explicit no_emoji = true
        OutputPrefs->>OutputPrefs: disable emoji
    else
        OutputPrefs->>Env: read NO_COLOR
        Env-->>OutputPrefs: value or none
        alt NO_COLOR set
            OutputPrefs->>OutputPrefs: disable emoji
        else
            OutputPrefs->>Env: read NETSUKE_NO_EMOJI
            Env-->>OutputPrefs: value or none
            alt NETSUKE_NO_EMOJI set
                OutputPrefs->>OutputPrefs: disable emoji
            else
                OutputPrefs->>OutputPrefs: enable emoji (default)
            end
        end
    end
    OutputPrefs-->>Main: return prefs
    Main->>Runner: run(cli, prefs)
    Runner->>Reporter: AccessibleReporter::new(prefs)
    Reporter->>Reporter: compute prefix via prefs.success_prefix()
    Reporter-->>Stderr: write prefixed message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🎭 Toggle glyphs with a flag or a breeze,
Env whispers NO_COLOR, NETSUKE_NO_EMOJI agrees,
Prefixes speak plain or with a smiling muse,
OutputPrefs decides which symbols to use,
Celebrate clarity — accessibility enthuse.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly summarises the main change: introducing accessibility preferences through OutputPrefs and emoji prefixes, which is the core objective of the changeset.
Description check ✅ Passed The description comprehensively relates to the changeset, detailing the new OutputPrefs module, CLI enhancements, localization updates, documentation, tests, and integration points across the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch respect-accessibility-preferences-ubavwa

Comment @coderabbitai help to get the list of available commands and usage tips.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Owner Author

leynos commented Feb 13, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix:

src/output_prefs.rs

Comment on lines +213 to +224

    fn error_prefix_contains_error_text_without_emoji() {
        let prefs = OutputPrefs { emoji: false };
        let rendered = prefs.error_prefix().to_string();
        assert!(
            rendered.contains("Error:"),
            "expected 'Error:' in '{rendered}'"
        );
        assert!(
            rendered.is_ascii(),
            "expected ASCII-only prefix, got '{rendered}'"
        );
    }

❌ New issue: Code Duplication
The module contains 3 functions with similar structure: tests.error_prefix_contains_error_text_without_emoji,tests.success_prefix_contains_success_text_without_emoji,tests.warning_prefix_contains_warning_text_without_emoji

@leynos
Copy link
Owner Author

leynos commented Feb 13, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix:

tests/bdd/steps/accessibility_preferences.rs

Comment on lines +101 to +108

fn render_error_prefix(world: &TestWorld) -> Result<()> {
    let prefs = world
        .output_prefs
        .get()
        .ok_or_else(|| anyhow::anyhow!("output prefs have not been resolved"))?;
    world.rendered_prefix.set(prefs.error_prefix().to_string());
    Ok(())
}

❌ New issue: Code Duplication
The module contains 2 functions with similar structure: render_error_prefix,render_success_prefix

@coderabbitai

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

…stest

Replaced multiple similar unit tests for error, success, and warning prefixes with a single parameterized test using rstest. This reduces code duplication and improves test maintainability by covering both emoji and non-emoji cases in one test function.

Additionally, in accessibility preference BDD steps, introduced a helper function to abstract prefix rendering logic, simplifying step definitions for rendering error and success prefixes.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos marked this pull request as ready for review February 14, 2026 14:22
sourcery-ai[bot]

This comment was marked as resolved.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4dd8914b64

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 136 to 138
if let Some(forced) = no_emoji {
return OutputPrefs { emoji: !forced };
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid overriding NETSUKE_NO_EMOJI presence semantics

This early explicit-override branch causes a runtime regression when Cli.no_emoji is populated from environment merging (NETSUKE_ prefix in cli::merge_with_config): if a user exports NETSUKE_NO_EMOJI=false, it becomes Some(false) here and re-enables emoji, even though this resolver (and its docs/tests) define NETSUKE_NO_EMOJI as a presence-based signal where any set value should suppress emoji. In practice, templated env configs that emit boolean strings can now produce the opposite behaviour from the intended accessibility default.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Has this now been resolved in the latest commit?

Use codegraph analysis to determine your answer.

If this comment is now resolved, please mark it as such using the API. Otherwise, please provide an AI agent prompt for the remaining work to be done to address this comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check the current implementation of resolve_with in src/output_prefs.rs
echo "=== Current resolve_with implementation ==="
ast-grep --pattern $'pub fn resolve_with<$_>($$$) $$$
where
    $$$
{
    $$$
}'  src/output_prefs.rs

echo ""
echo "=== Checking for the problematic early return ==="
rg -A 5 'if let Some\(forced\) = no_emoji' src/output_prefs.rs

echo ""
echo "=== Check CLI merge logic for NETSUKE_NO_EMOJI handling ==="
rg -C 5 'NETSUKE_NO_EMOJI|no_emoji.*merge' src/cli/mod.rs

echo ""
echo "=== Check for any tests covering NETSUKE_NO_EMOJI=false ==="
rg -C 3 'NETSUKE_NO_EMOJI.*false|no_emoji.*false' tests/ src/

Length of output: 3971


🏁 Script executed:

#!/bin/bash

# Check how resolve is called in main.rs
echo "=== How resolve is called in main.rs ==="
rg -C 5 'output_prefs::resolve' src/main.rs

# Check for any environment variable merging in cli module
echo ""
echo "=== Check for environment variable merging with NETSUKE_ prefix ==="
rg -C 10 'merge_with|NETSUKE_' src/cli/mod.rs

# Check if there's any string to bool conversion for environment variables
echo ""
echo "=== Check for env var parsing to bool ==="
rg -C 5 'env::var.*parse|parse.*bool' src/

# Look for any config file parsing that might affect no_emoji
echo ""
echo "=== Check config module for no_emoji handling ==="
fd -e rs . src/ --exec rg -l 'no_emoji' {} \; | head -10

# Check the actual value passed to resolve in all callsites
echo ""
echo "=== All resolve callsites ==="
rg -C 3 'resolve\(' src/ tests/

Length of output: 11207


🏁 Script executed:

#!/bin/bash

# Check the full merge_with_config implementation to see environment layer handling
echo "=== Full merge_with_config function ==="
ast-grep --pattern $'pub fn merge_with_config($$$) -> $_ {
    $$$
}' src/cli/mod.rs

# Look for environment layer or env prefix usage
echo ""
echo "=== Check for environment layer with NETSUKE_ prefix ==="
rg -C 10 'push_env|env_layer|ENV_PREFIX' src/cli/mod.rs

# Check Cli struct definition for serde attributes
echo ""
echo "=== Check Cli struct definition and attributes ==="
ast-grep --pattern 'pub struct Cli {
    $$$
}' src/cli/mod.rs

# Check if ortho_config is in dependencies
echo ""
echo "=== Check Cargo.toml for ortho-config ==="
rg 'ortho' Cargo.toml

Length of output: 8202


@leynos, the issue has not been resolved in the latest commit.

The problematic code is still present at lines 136–138 of src/output_prefs.rs:

if let Some(forced) = no_emoji {
    return OutputPrefs { emoji: !forced };
}

Combined with the ortho-config environment merging at lines 369–378 of src/cli/mod.rs, the vulnerability remains: when a user sets NETSUKE_NO_EMOJI=false (or =0), Figment's Env provider parses it as boolean false, which becomes Some(false) in Cli.no_emoji. The early return then produces emoji: !false = true, re-enabling emoji and contradicting the documented presence-based semantics where any value should disable emoji.

Your tests explicitly cover this behaviour (explicit_emoji_on_overrides_netsuke_no_emoji), but the original concern was that environment-based boolean parsing undermines the intended "presence means suppress" contract for NETSUKE_NO_EMOJI.


AI agent prompt to address this issue:

Refactor `src/output_prefs.rs::resolve_with` to honour presence-based semantics for the `NETSUKE_NO_EMOJI` environment variable whilst preserving explicit CLI override behaviour. The function currently allows `no_emoji: Some(false)` to re-enable emoji unconditionally, but when this value originates from environment parsing (e.g., `NETSUKE_NO_EMOJI=false`), it violates the documented contract that any set value should suppress emoji.

Required changes:
1. Split the explicit override into two paths:
   - `Some(true)` → force emoji off
   - `Some(false)` → skip explicit override; proceed to environment checks
2. Update documentation and tests to reflect that `no_emoji: Some(false)` only acts as an override when explicitly set via CLI flag, not when derived from environment parsing.
3. Ensure that `NETSUKE_NO_EMOJI` (with any value, including "false" or "0") always suppresses emoji unless overridden by an explicit CLI `--no-emoji=false`.
4. Preserve existing test coverage for explicit CLI override behaviour (`explicit_emoji_on_overrides_no_color` and similar).

Maintain en-GB-oxendict spelling and adhere to the coding guidelines.

…nt output

Refactor runner::run to accept output preferences, improving output handling consistency. Update main, tests, and relevant modules to pass resolved output preferences explicitly. Add BDD scenarios for warning prefix rendering in no-emoji mode. Adjust docs for wording fixes and terminology consistency.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/execplans/3-8-2-respect-accessibility-preferences.md`:
- Around line 99-101: Update the British-variant -ise spellings to -ize in the
document: change "localised Fluent messages" to "localized Fluent messages" and
any other occurrences of "-ise" (e.g., in the semantic-prefix description that
uses `$emoji` select and the surrounding lines referenced) to their "-ize"
forms; apply the same replacement to the other affected occurrences noted (lines
108-110 and 117-118) so all instances use the en-GB-oxendict "-ize" spelling
consistently.

In `@src/status.rs`:
- Around line 33-35: Update the doc comment that currently reads "localised
messages from the Fluent resource bundle" to use en-GB-oxendict -ize spelling by
replacing "localised" with "localized"; locate the doc comment containing
"localised messages from the Fluent resource bundle" in src/status.rs (the
module/section documenting completion messages) and change the word only so the
rest of the comment remains unchanged.

Comment on lines 99 to 101
- Semantic prefixes use localised Fluent messages with `$emoji` select.
- Emoji-allowed mode: `✖ Error:`, `⚠ Warning:`, `✔ Success:`.
No-emoji mode: `Error:`, `Warning:`, `Success:`.
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Replace -ise spellings with -ize forms.

Align these terms with en-GB-oxendict spelling.

Proposed fix
- Semantic prefixes use localised Fluent messages with `$emoji` select.
+ Semantic prefixes use localized Fluent messages with `$emoji` select.
@@
-New tests: 18 unit tests in `output_prefs::tests` (10 parameterised resolve
+New tests: 18 unit tests in `output_prefs::tests` (10 parameterized resolve
@@
-The `src/cli/mod.rs` 400-line risk materialised (387 + new field). Mitigated
+The `src/cli/mod.rs` 400-line risk materialized (387 + new field). Mitigated

As per coding guidelines, documentation must use en-GB-oxendict spelling with -ize forms.

Also applies to: 108-110, 117-118

🧰 Tools
🪛 LanguageTool

[style] ~99-~99: Would you like to use the Oxford spelling “localized”? The spelling ‘localised’ is also correct.
Context: ...ome(false)/on). - Semantic prefixes use localised Fluent messages with $emoji select. -...

(OXFORD_SPELLING_Z_NOT_S)

🤖 Prompt for AI Agents
In `@docs/execplans/3-8-2-respect-accessibility-preferences.md` around lines 99 -
101, Update the British-variant -ise spellings to -ize in the document: change
"localised Fluent messages" to "localized Fluent messages" and any other
occurrences of "-ise" (e.g., in the semantic-prefix description that uses
`$emoji` select and the surrounding lines referenced) to their "-ize" forms;
apply the same replacement to the other affected occurrences noted (lines
108-110 and 117-118) so all instances use the en-GB-oxendict "-ize" spelling
consistently.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai Has this now been resolved in the latest commit?

Use codegraph analysis to determine your answer.

If this comment is now resolved, please mark it as such using the API. Otherwise, please provide an AI agent prompt for the remaining work to be done to address this comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the ExecPlan document and check for -ise vs -ize spellings
echo "=== Checking for -ise spellings that should be -ize ==="
cat docs/execplans/3-8-2-respect-accessibility-preferences.md | grep -n -E "(localised|parameterised|materialised)"

echo ""
echo "=== Checking for corrected -ize spellings ==="
cat docs/execplans/3-8-2-respect-accessibility-preferences.md | grep -n -E "(localized|parameterized|materialized)"

echo ""
echo "=== Showing lines around 99, 108-110, 117-118 ==="
sed -n '98,101p' docs/execplans/3-8-2-respect-accessibility-preferences.md
echo "---"
sed -n '107,111p' docs/execplans/3-8-2-respect-accessibility-preferences.md
echo "---"
sed -n '116,119p' docs/execplans/3-8-2-respect-accessibility-preferences.md

Length of output: 1078


@leynos, the comment has been partially resolved. The codegraph analysis shows:

Fixed:

  • Line 100: "localised" → "localized" ✓

Still requires correction:

  • Line 109: "parameterised" → needs "parameterized"
  • Line 118: "materialised" → needs "materialized"
🤖 Prompt for AI Agents
In `@docs/execplans/3-8-2-respect-accessibility-preferences.md`, update the remaining British-variant -ise spellings to -ize forms: change "parameterised resolve" on line 109 to "parameterized resolve" and "materialised (387 + new field)" on line 118 to "materialized (387 + new field)" to align with en-GB-oxendict spelling.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/execplans/3-8-2-respect-accessibility-preferences.md`:
- Around line 13-18: Update the semantic prefix list in the docs entry titled
"3-8-2-respect-accessibility-preferences.md" by inserting the Oxford comma so
the phrase reads "Error, Warning, and Success" instead of "Error, Warning,
Success"; locate the sentence containing "semantic prefixes (Error, Warning,
Success)" and edit it to include the comma before "and" to comply with the style
guideline.

In `@docs/users-guide.md`:
- Around line 625-628: Reflow the paragraph that describes semantic text
prefixes so it is wrapped at 80 columns and insert the Oxford comma when listing
the three prefixes — render them as `Error:`, `Warning:`, and `Success:` — and
ensure the sentence about including a leading glyph when emoji are permitted is
kept intact and grammatically correct while fitting the 80-column wrap.

Comment on lines +13 to +18
Netsuke's accessible output mode (roadmap 3.8.1, complete) auto-detects
`NO_COLOR` and `TERM=dumb` to switch from animated to static status output.
However, the tool does not yet honour emoji preferences, enforce ASCII-only
output when requested, or guarantee semantic prefixes (Error, Warning, Success)
in every output mode. This plan completes the remaining accessibility
preferences so that:
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the Oxford comma to the semantic prefix list.

Write the list as “Error, Warning, and Success”.

Proposed diff
-However, the tool does not yet honour emoji preferences, enforce ASCII-only
-output when requested, or guarantee semantic prefixes (Error, Warning, Success)
-in every output mode. This plan completes the remaining accessibility
-preferences so that:
+However, the tool does not yet honour emoji preferences, enforce ASCII-only
+output when requested, or guarantee semantic prefixes (Error, Warning, and
+Success) in every output mode. This plan completes the remaining accessibility
+preferences so that:

As per coding guidelines, "Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension."

🤖 Prompt for AI Agents
In `@docs/execplans/3-8-2-respect-accessibility-preferences.md` around lines 13 -
18, Update the semantic prefix list in the docs entry titled
"3-8-2-respect-accessibility-preferences.md" by inserting the Oxford comma so
the phrase reads "Error, Warning, and Success" instead of "Error, Warning,
Success"; locate the sentence containing "semantic prefixes (Error, Warning,
Success)" and edit it to include the comma before "and" to comply with the style
guideline.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai has this now been resolved?

Use sourcegraph analysis to determine your answer.

If the comment has been resolved, please mark it as resolved using the API. Otherwise, please provide an AI agent prompt for the work remaining.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the current content of the file for the Oxford comma in the semantic prefix list
cat docs/execplans/3-8-2-respect-accessibility-preferences.md | grep -A2 -B2 "semantic prefixes"

Length of output: 322


@leynos, the issue has not been resolved. The file still contains "semantic prefixes (Error, Warning, Success)" without the Oxford comma.

🤖 AI Agent Prompt for Remaining Work
In the file `docs/execplans/3-8-2-respect-accessibility-preferences.md` at line 15, insert the Oxford comma before "and" in the phrase "semantic prefixes (Error, Warning, Success)" so it reads "semantic prefixes (Error, Warning, and Success)". Locate the sentence "However, the tool does not yet honour emoji preferences, enforce ASCII-only output when requested, or guarantee semantic prefixes (Error, Warning, Success) in every output mode." and update it to include the comma before "and Success)".

Comment on lines +625 to +628
In all output modes, Netsuke uses semantic text prefixes (`Error:`,
`Warning:`, `Success:`) so that meaning is never conveyed solely by colour
or symbol. When emoji is permitted, these prefixes include a leading glyph
for quick visual scanning.
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Apply the Oxford comma and wrap the semantic-prefix paragraph to 80 columns.

Reflow the paragraph and render the three prefixes with an Oxford comma.

Proposed diff
-In all output modes, Netsuke uses semantic text prefixes (`Error:`,
-`Warning:`, `Success:`) so that meaning is never conveyed solely by colour
-or symbol. When emoji is permitted, these prefixes include a leading glyph
-for quick visual scanning.
+In all output modes, Netsuke uses semantic text prefixes (`Error:`,
+`Warning:`, and `Success:`) so that meaning is never conveyed solely
+by colour or symbol. When emoji is permitted, these prefixes include a
+leading glyph for quick visual scanning.

As per coding guidelines, "Markdown paragraphs and bullet points must be wrapped at 80 columns" and "Use the Oxford comma in documentation: 'ships, planes, and hovercraft' where it aids comprehension."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
In all output modes, Netsuke uses semantic text prefixes (`Error:`,
`Warning:`, `Success:`) so that meaning is never conveyed solely by colour
or symbol. When emoji is permitted, these prefixes include a leading glyph
for quick visual scanning.
In all output modes, Netsuke uses semantic text prefixes (`Error:`,
`Warning:`, and `Success:`) so that meaning is never conveyed solely
by colour or symbol. When emoji is permitted, these prefixes include a
leading glyph for quick visual scanning.
🤖 Prompt for AI Agents
In `@docs/users-guide.md` around lines 625 - 628, Reflow the paragraph that
describes semantic text prefixes so it is wrapped at 80 columns and insert the
Oxford comma when listing the three prefixes — render them as `Error:`,
`Warning:`, and `Success:` — and ensure the sentence about including a leading
glyph when emoji are permitted is kept intact and grammatically correct while
fitting the 80-column wrap.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai has this now been resolved?

Use sourcegraph analysis to determine your answer.

If the comment has been resolved, please mark it as resolved using the API. Otherwise, please provide an AI agent prompt for the work remaining.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Read the specific lines from the users guide to check if the review comment has been addressed
sed -n '625,628p' docs/users-guide.md

Length of output: 244


@leynos, the review comment has not been resolved.

The current text at lines 625-628 still reads:

In all output modes, Netsuke uses semantic text prefixes (`Error:`,
`Warning:`, `Success:`) so that meaning is never conveyed solely by colour
or symbol.

The Oxford comma is still missing (should be "Error:, Warning:, and Success:"), and the paragraph wrapping doesn't follow the 80-column guideline.


🤖 AI Agent Prompt for remaining work

In the file `docs/users-guide.md` at lines 625-628, update the paragraph
describing semantic text prefixes to:
1. Add the Oxford comma before the final item in the list, changing
   "`Error:`, `Warning:`, `Success:`" to "`Error:`, `Warning:`, and `Success:`"
2. Reflow the entire paragraph to wrap at 80 columns while maintaining
   grammatical correctness and readability

The corrected paragraph should read:
"In all output modes, Netsuke uses semantic text prefixes (`Error:`,
`Warning:`, and `Success:`) so that meaning is never conveyed solely
by colour or symbol. When emoji is permitted, these prefixes include a
leading glyph for quick visual scanning."

@leynos
Copy link
Owner Author

leynos commented Feb 14, 2026

@coderabbitai Have the following now been resolved?

Please address the comments from this code review:

## Overall Comments
- Consider avoiding duplicated preference resolution by passing a single `OutputPrefs` instance from `main` into `runner::run` (or returning it), so both status reporting and error handling share one resolved source rather than each calling `output_prefs::resolve` independently.
- In `main.rs` the non-`RunnerError` branch switches from `tracing::error!` to writing directly to stderr; if structured logging is still useful for diagnostics, consider keeping the `tracing::error!` call in addition to the prefixed stderr output.

## Individual Comments

### Comment 1
<location> `tests/bdd/steps/accessibility_preferences.rs:118-120` </location>
<code_context>
+    render_prefix_with(world, |prefs| prefs.error_prefix().to_string())
+}
+
+#[when("the success prefix is rendered")]
+fn render_success_prefix(world: &TestWorld) -> Result<()> {
+    render_prefix_with(world, |prefs| prefs.success_prefix().to_string())
+}
+
</code_context>

<issue_to_address>
**suggestion (testing):** Add BDD coverage for the warning prefix to mirror error/success prefix checks.

The BDD steps assert error and success prefixes but don’t exercise the warning prefix, even though `OutputPrefs` exposes `warning_prefix` and it’s user-visible. Please add a `#[when("the warning prefix is rendered")]` step mirroring the existing ones, plus `.feature` scenarios that check the localized "Warning:" text and emoji vs. no-emoji behavior so BDD coverage matches the unit tests and guards against regressions in warning output.

Suggested implementation:

```rust
#[when("the error prefix is rendered")]
fn render_error_prefix(world: &TestWorld) -> Result<()> {
    render_prefix_with(world, |prefs| prefs.error_prefix().to_string())
}

#[when("the warning prefix is rendered")]
fn render_warning_prefix(world: &TestWorld) -> Result<()> {
    render_prefix_with(world, |prefs| prefs.warning_prefix().to_string())
}

use crate::bdd::fixtures::TestWorld;

```

To fully implement the requested BDD coverage parity with error/success prefixes, you will also need to:

1. Update the relevant `.feature` file(s) under `tests/bdd/features/` (likely the one that currently covers accessibility/output preferences) to:
   - Add a scenario verifying the localized warning text (e.g. `Warning:`) is present when "the warning prefix is rendered".
   - Add a scenario verifying emoji vs. no-emoji behavior for the warning prefix, mirroring how error/success prefixes are tested (reusing the same Given steps that toggle emoji preferences / accessibility mode).
2. Wire the new step into those scenarios by using the new step phrase `When the warning prefix is rendered` so it binds to `render_warning_prefix`.
3. Ensure any existing step definitions or world state that compare the rendered prefix (e.g. `Then the rendered prefix is "⚠ Warning:"` / `Then the rendered prefix is "Warning:"`) are updated or extended to include the expected warning prefixes for both emoji-enabled and emoji-disabled configurations.
</issue_to_address>

### Comment 2
<location> `docs/users-guide.md:611` </location>
<code_context>
+Netsuke supports suppressing emoji glyphs in output for users who prefer
+ASCII-only output or use environments where emoji are not rendered correctly.
+
+Emoji is automatically suppressed when:
+
+- `NO_COLOR` is set (any value)
</code_context>

<issue_to_address>
**nitpick (typo):** Consider changing "Emoji is" to "Emoji are" for grammatical consistency with the rest of the docs.

The ExecPlan section already says “emoji are visual decoration,” so using “Emoji are automatically suppressed when:” here will keep the plural usage consistent.

```suggestion
Emoji are automatically suppressed when:
```
</issue_to_address>

### Comment 3
<location> `docs/execplans/3-8-2-respect-accessibility-preferences.md:70` </location>
<code_context>
+
+- Risk: `cli_overrides_from_matches` must be updated for `no_emoji`.
+  Severity: high. Likelihood: high.
+  Mitigation: add to `value_source` check array; covered by BDD scenario.
+
+## Progress
</code_context>

<issue_to_address>
**issue (review_instructions):** The acronym “BDD” is used here without being expanded on first use, which violates the acronym-definition requirement.

Please expand “BDD” the first time it appears, for example: “covered by a Behaviour-Driven Development (BDD) scenario.” Subsequent uses can then use just “BDD scenario.”

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Define uncommon acronyms on first use.

</details>
</issue_to_address>

### Comment 4
<location> `docs/execplans/3-8-2-respect-accessibility-preferences.md:99` </location>
<code_context>
+- `NO_COLOR` implies no-emoji (visual decoration suppressed with colour).
+- `no_emoji` is `Option<bool>` (tri-state: None/auto, Some(true)/off,
+  Some(false)/on).
+- Semantic prefixes use localised Fluent messages with `$emoji` select.
+- Emoji-allowed mode: `✖ Error:`, `⚠ Warning:`, `✔ Success:`.
+  No-emoji mode: `Error:`, `Warning:`, `Success:`.
</code_context>

<issue_to_address>
**issue (review_instructions):** “localised” uses -ise spelling where the guidelines require -ize forms for this project’s en-GB-oxendic style.

To match the specified en-GB-oxendic (-ize / -yse / -our) style, please change “localised” to “localized” here.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Use en-GB-oxendic (-ize / -yse / -our) spelling and grammar.

</details>
</issue_to_address>

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check main.rs for OutputPrefs passing and tracing::error! usage
echo "=== Checking main.rs ==="
cat src/main.rs

Length of output: 2557


🏁 Script executed:

#!/bin/bash
# Check tests/bdd/steps/accessibility_preferences.rs for warning prefix
echo "=== Checking accessibility_preferences.rs ==="
cat tests/bdd/steps/accessibility_preferences.rs | grep -A 5 "warning_prefix"

Length of output: 358


🏁 Script executed:

#!/bin/bash
# Check docs/users-guide.md for "Emoji is" vs "Emoji are"
echo "=== Checking users-guide.md ==="
rg -n "Emoji (is|are) automatically suppressed" docs/users-guide.md

Length of output: 76


🏁 Script executed:

#!/bin/bash
# Check docs/execplans for "BDD" acronym and "localised"
echo "=== Checking execplans document ==="
cat docs/execplans/3-8-2-respect-accessibility-preferences.md | grep -n -A 2 -B 2 "BDD\|localised\|localized"

Length of output: 1413


🏁 Script executed:

#!/bin/bash
# Check for warning prefix in feature files
echo "=== Checking for warning prefix scenarios ==="
rg -n "warning prefix" tests/features/

Length of output: 229


@leynos: Yes, all the review comments have been resolved! Here's the verification:

Overall Comments ✅

1. Single OutputPrefs instance passed to runner:

  • Resolved – Line 42 in src/main.rs shows let prefs = output_prefs::resolve(merged_cli.no_emoji); resolves preferences once, then line 43 passes it to runner::run(&merged_cli, prefs), and line 46 reuses the same prefs instance for error prefixing. No duplication exists.

2. Retain tracing::error! alongside stderr output:

  • Resolved – Lines 50-52 in src/main.rs show:
    Err(other_err) => {
        tracing::error!(error = %other_err, "runner failed");
        drop(writeln!(io::stderr(), "{prefix} {other_err}"));
    }
    The structured logging call is preserved in addition to the prefixed stderr output.

Individual Comments ✅

Comment 1 – BDD coverage for warning prefix:

  • Resolvedtests/bdd/steps/accessibility_preferences.rs includes the render_warning_prefix function, and tests/features/accessibility_preferences.feature contains scenarios at lines 45 and 51 that exercise "When the warning prefix is rendered".

Comment 2 – "Emoji are" (plural):

  • Resolved – Line 611 in docs/users-guide.md reads "Emoji are automatically suppressed when:" using the correct plural form.

Comment 3 – Expand "BDD" acronym:

  • Resolved – Lines 70-71 in docs/execplans/3-8-2-respect-accessibility-preferences.md read: "covered by Behaviour-Driven Development (BDD) scenario." The acronym is expanded on first use.

Comment 4 – "localized" (not "localised"):

  • Resolved – Line 100 in docs/execplans/3-8-2-respect-accessibility-preferences.md reads: "Semantic prefixes use localized Fluent messages" using the en-GB-oxendict -ize spelling.

All issues have been addressed! 🎉

The output preference resolution logic was updated so that an explicit
no_emoji value of Some(false) no longer forces emoji on unconditionally.
Instead, Some(false) defers to environment variables like NO_COLOR and
NETSUKE_NO_EMOJI, both of which use presence-based semantics to suppress
emoji output.

Only Some(true) forces emoji suppression unconditionally.

This change ensures that setting --no-emoji false does not override environment
variables that suppress emoji, addressing user expectations and aligning
cli behavior with documented semantics.

Updates include documentation, unit tests, BDD scenarios, and examples.

Co-authored-by: devboxerhub[bot] <devboxerhub[bot]@users.noreply.github.com>
@leynos leynos changed the title Implement accessibility preferences: emoji suppression and semantic prefixes Implement accessibility preferences: OutputPrefs and emoji prefixes Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant