---
phase: 27-global-flag-infrastructure
plan: 02
type: execute
wave: 2
depends_on:
  - 27-01
files_modified:
  - cargo-pmcp/src/commands/mod.rs
  - cargo-pmcp/src/main.rs
  - cargo-pmcp/src/commands/loadtest/run.rs
  - cargo-pmcp/src/commands/loadtest/upload.rs
  - cargo-pmcp/src/commands/loadtest/init.rs
  - cargo-pmcp/src/commands/test/check.rs
  - cargo-pmcp/src/commands/test/run.rs
  - cargo-pmcp/src/commands/test/generate.rs
  - cargo-pmcp/src/commands/test/list.rs
  - cargo-pmcp/src/commands/test/download.rs
  - cargo-pmcp/src/commands/test/upload.rs
  - cargo-pmcp/src/commands/deploy/mod.rs
  - cargo-pmcp/src/commands/deploy/deploy.rs
  - cargo-pmcp/src/commands/deploy/init.rs
  - cargo-pmcp/src/commands/secret/mod.rs
  - cargo-pmcp/src/commands/schema.rs
  - cargo-pmcp/src/commands/validate.rs
  - cargo-pmcp/src/commands/preview.rs
  - cargo-pmcp/src/commands/app.rs
  - cargo-pmcp/src/commands/connect.rs
  - cargo-pmcp/src/commands/dev.rs
  - cargo-pmcp/src/commands/new.rs
  - cargo-pmcp/src/commands/add.rs
  - cargo-pmcp/src/commands/landing/mod.rs
  - cargo-pmcp/src/commands/landing/init.rs
  - cargo-pmcp/src/commands/landing/dev.rs
  - cargo-pmcp/src/commands/landing/deploy.rs
autonomous: true
requirements:
  - FLAG-09
must_haves:
  truths:
    - "User can pass --quiet to any cargo pmcp command and only errors and explicitly requested output appear"
    - "All decorative output (banners, progress, success messages, warnings, informational text) is suppressed when --quiet is active"
    - "If both --quiet and --verbose are passed, --verbose wins (quiet is overridden)"
    - "Both --no-color and --quiet work when placed before or after the subcommand"
  artifacts:
    - path: "cargo-pmcp/src/commands/mod.rs"
      provides: "GlobalFlags with quiet_eprintln!, quiet_println! macros or helper methods for conditional output"
      contains: "quiet"
    - path: "cargo-pmcp/src/main.rs"
      provides: "Verbose-wins-over-quiet precedence logic"
  key_links:
    - from: "cargo-pmcp/src/main.rs (precedence logic)"
      to: "GlobalFlags.quiet field"
      via: "If verbose && quiet, set quiet=false"
      pattern: "verbose.*quiet"
    - from: "GlobalFlags quiet helpers"
      to: "all command handler output"
      via: "Replace decorative println!/eprintln! with quiet-aware equivalents"
      pattern: "global_flags"
---

<objective>
Implement `--quiet` output filtering across all commands and add the verbose-wins-over-quiet precedence rule. Every decorative output call becomes quiet-aware.

Purpose: Complete the `--quiet` global flag behavior. Plan 01 wired the flag through all handlers; this plan makes it actually suppress output. Also validates both `--no-color` and `--quiet` work correctly end-to-end.

Output: When `--quiet` is passed, only stderr error messages (from `anyhow::bail!`, `anyhow::Error`, and explicit error paths) are shown. All informational, decorative, success, warning, and progress output is suppressed.
</objective>

<execution_context>
@./.claude/get-shit-done/workflows/execute-plan.md
@./.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/27-global-flag-infrastructure/27-CONTEXT.md
@.planning/phases/27-global-flag-infrastructure/27-01-SUMMARY.md
@cargo-pmcp/src/main.rs
@cargo-pmcp/src/commands/mod.rs

<interfaces>
<!-- From Plan 01, GlobalFlags is defined in commands/mod.rs -->

From cargo-pmcp/src/commands/mod.rs (after Plan 01):
```rust
#[derive(Clone, Debug)]
pub struct GlobalFlags {
    pub verbose: bool,
    pub no_color: bool,
    pub quiet: bool,
}
```

From cargo-pmcp/src/main.rs (after Plan 01):
```rust
fn execute_command(command: Commands, global_flags: &GlobalFlags) -> Result<()> { ... }
```

All command handlers now receive `&GlobalFlags` (or `_global_flags: &GlobalFlags`).

Output patterns across 25 command files (~780 println!/eprintln! calls):
- `eprintln!("message")` — informational/decorative (SUPPRESS when quiet)
- `println!("result")` — requested output like test results, schema export (KEEP when quiet)
- `eprintln!("Error: ...")` or `anyhow::bail!(...)` — errors (KEEP when quiet)
- `eprintln!("Warning: ...")` — warnings (SUPPRESS when quiet per user decision)
- Banner/header prints like section dividers (SUPPRESS when quiet)
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add quiet-aware output helpers to GlobalFlags and implement verbose-wins-over-quiet</name>
  <files>cargo-pmcp/src/commands/mod.rs, cargo-pmcp/src/main.rs</files>
  <action>
  1. In `cargo-pmcp/src/main.rs`, after constructing `GlobalFlags` but before calling `execute_command()`, apply the verbose-wins-over-quiet precedence rule:

     ```rust
     // Verbose wins over quiet (per user decision)
     let global_flags = GlobalFlags {
         verbose: cli.verbose,
         no_color: effective_no_color,
         quiet: cli.quiet && !cli.verbose,  // quiet disabled when verbose is on
     };
     ```

  2. In `cargo-pmcp/src/commands/mod.rs`, add helper methods to `GlobalFlags`:

     ```rust
     impl GlobalFlags {
         /// Print to stderr if not in quiet mode.
         /// Use for informational, decorative, progress, and success messages.
         /// Error messages should use eprintln! directly (they always show).
         pub fn status(&self, msg: &str) {
             if !self.quiet {
                 eprintln!("{}", msg);
             }
         }

         /// Print to stderr with formatting if not in quiet mode.
         pub fn status_fmt(&self, args: std::fmt::Arguments<'_>) {
             if !self.quiet {
                 eprintln!("{}", args);
             }
         }

         /// Print to stdout if not in quiet mode.
         /// Use for decorative stdout output. Requested output (e.g., schema export,
         /// test results to stdout) should use println! directly.
         pub fn print(&self, msg: &str) {
             if !self.quiet {
                 println!("{}", msg);
             }
         }

         /// Print to stdout with formatting if not in quiet mode.
         pub fn print_fmt(&self, args: std::fmt::Arguments<'_>) {
             if !self.quiet {
                 println!("{}", args);
             }
         }

         /// Returns true if output should be shown (not quiet, or verbose overrode quiet).
         pub fn should_output(&self) -> bool {
             !self.quiet
         }
     }
     ```

     Also add two convenience macros in `commands/mod.rs` for ergonomic use:

     ```rust
     /// Print to stderr if not in quiet mode. Equivalent to eprintln! but respects --quiet.
     #[macro_export]
     macro_rules! status {
         ($flags:expr, $($arg:tt)*) => {
             if !$flags.quiet {
                 eprintln!($($arg)*);
             }
         };
     }

     /// Print to stdout if not in quiet mode. Equivalent to println! but respects --quiet.
     #[macro_export]
     macro_rules! qprintln {
         ($flags:expr, $($arg:tt)*) => {
             if !$flags.quiet {
                 println!($($arg)*);
             }
         };
     }
     ```

     Note: The macro approach vs method approach is at Claude's discretion per CONTEXT.md. Pick whichever results in cleaner code at the call sites. The key requirement is that decorative output is suppressed when quiet=true.

  3. Also set `PMCP_QUIET=1` env var in main.rs when quiet is active (after precedence resolution), so subprocesses can detect quiet mode.
  </action>
  <verify>
    <automated>cd /Users/guy/Development/mcp/sdk/rust-mcp-sdk && cargo check -p cargo-pmcp 2>&1 | tail -5</automated>
  </verify>
  <done>
  - GlobalFlags has quiet-aware output helper methods/macros
  - Verbose-wins-over-quiet precedence applied in main()
  - `PMCP_QUIET=1` env var set when quiet is active
  - cargo check passes
  </done>
</task>

<task type="auto">
  <name>Task 2: Convert decorative output across all commands to quiet-aware output</name>
  <files>cargo-pmcp/src/commands/loadtest/run.rs, cargo-pmcp/src/commands/loadtest/upload.rs, cargo-pmcp/src/commands/loadtest/init.rs, cargo-pmcp/src/commands/test/check.rs, cargo-pmcp/src/commands/test/run.rs, cargo-pmcp/src/commands/test/generate.rs, cargo-pmcp/src/commands/test/list.rs, cargo-pmcp/src/commands/test/download.rs, cargo-pmcp/src/commands/test/upload.rs, cargo-pmcp/src/commands/deploy/mod.rs, cargo-pmcp/src/commands/deploy/deploy.rs, cargo-pmcp/src/commands/deploy/init.rs, cargo-pmcp/src/commands/secret/mod.rs, cargo-pmcp/src/commands/schema.rs, cargo-pmcp/src/commands/validate.rs, cargo-pmcp/src/commands/preview.rs, cargo-pmcp/src/commands/app.rs, cargo-pmcp/src/commands/connect.rs, cargo-pmcp/src/commands/dev.rs, cargo-pmcp/src/commands/new.rs, cargo-pmcp/src/commands/add.rs, cargo-pmcp/src/commands/landing/init.rs, cargo-pmcp/src/commands/landing/dev.rs, cargo-pmcp/src/commands/landing/deploy.rs</files>
  <action>
  Go through every command handler file and classify each `println!`/`eprintln!` call as one of:

  **KEEP as-is (always shown, even in quiet mode):**
  - Error messages: `eprintln!("Error: ...")`, `eprintln!("Failed: ...")`
  - Explicitly requested output: data the user asked for (schema export to stdout, test results, JSON output, secret values)
  - Any output that flows through `anyhow::bail!()` or `anyhow::Error` propagation (these go to stderr via anyhow's error display)

  **CONVERT to quiet-aware (suppressed when --quiet):**
  - Informational messages: "Loading config from...", "Connecting to...", "Discovering tools..."
  - Success messages: "Server created successfully", "Config uploaded", "Done!"
  - Progress indicators: "Building...", "Deploying..."
  - Decorative output: banners, section headers, separators, tips
  - Warnings: "Warning: ..." (per user decision, warnings are suppressed in quiet mode)
  - Next-steps guidance: "Next steps: run cargo pmcp ..."
  - Verbose debug output: already gated by `PMCP_VERBOSE` check — these should ALSO be suppressed by quiet

  For each file, rename `_global_flags` to `global_flags` (remove underscore prefix) and replace decorative `eprintln!(...)` with the quiet-aware helper (e.g., `global_flags.status(&format!(...))` or the macro equivalent). Replace decorative `println!(...)` with the quiet-aware print helper.

  **Important guidelines:**
  - Do NOT suppress `println!` calls that output the primary requested data (e.g., schema export, `--format json` output, secret values to stdout). These are the REASON the user ran the command.
  - DO suppress success confirmations, progress messages, tips, and verbose debug output.
  - For large commands (validate.rs has 48 calls, new.rs has 50, add.rs has 99): most output is scaffolding success messages ("Created file X", "Added tool Y") — these are ALL decorative and should be suppressed in quiet mode. But the final summary or any error must survive.
  - For `commands/test/check.rs` (60 calls): test results to stdout are requested output (KEEP). Progress messages to stderr are decorative (SUPPRESS).
  - For `commands/secret/mod.rs` (44 calls): the secret value itself (when retrieved) is requested output (KEEP). Messages like "Secret stored" are decorative (SUPPRESS).

  The mechanical pattern for each file:
  1. Add `use crate::commands::GlobalFlags;` if not already present (it should be from Plan 01)
  2. Remove underscore from `_global_flags` parameter name
  3. For each decorative eprintln!, wrap with `if global_flags.should_output() { eprintln!(...); }` or use the helper method/macro
  4. Leave error eprintln! and requested-output println! untouched

  Due to the large number of files (25) and calls (780), focus on correctness over perfection. A few decorative messages that survive quiet mode are acceptable; errors or requested output that get suppressed are NOT acceptable.
  </action>
  <verify>
    <automated>cd /Users/guy/Development/mcp/sdk/rust-mcp-sdk && cargo check -p cargo-pmcp 2>&1 | tail -5 && cargo test -p cargo-pmcp 2>&1 | tail -10 && cargo clippy -p cargo-pmcp -- -D warnings 2>&1 | tail -10</automated>
  </verify>
  <done>
  - All decorative output (informational, success, progress, warnings, tips) across all 25 command files is quiet-aware
  - Error messages always show regardless of quiet mode
  - Requested output (schema, test results, secret values, JSON) always shows regardless of quiet mode
  - `cargo check`, `cargo test`, and `cargo clippy` all pass with zero errors/warnings
  - No `_global_flags` prefixes remain (all handlers now use the parameter)
  </done>
</task>

</tasks>

<verification>
1. `cargo check -p cargo-pmcp` passes
2. `cargo test -p cargo-pmcp` passes — no regressions
3. `cargo clippy -p cargo-pmcp -- -D warnings` passes — zero warnings
4. `cargo pmcp --quiet new --help` shows help (help is always shown)
5. `cargo pmcp --quiet --verbose new --help` — verbose wins, quiet is disabled
6. `cargo pmcp --help` shows both `--no-color` and `--quiet` as global options
7. `cargo pmcp loadtest run --help` does NOT show local `--no-color` (removed in Plan 01)
</verification>

<success_criteria>
- `--quiet` suppresses all decorative output across every command
- `--verbose` overrides `--quiet` when both are passed
- No error messages or requested output are accidentally suppressed
- All tests pass, zero clippy warnings
</success_criteria>

<output>
After completion, create `.planning/phases/27-global-flag-infrastructure/27-02-SUMMARY.md`
</output>
