# Cobra-Generated Help Migration ExecPlan

This ExecPlan is a living document. Keep `Progress`, `Surprises & Discoveries`, `Decision Log`, and `Outcomes & Retrospective` up to date as work proceeds.

Reference: `PLANS.md` at repository root; this plan must be maintained according to it.


## Purpose / Big Picture

After this change, `clinic` uses Cobra as the source of truth for command parsing, shell completion, and help output. Users can place global options such as `--env`, `--profile`, and `--verbose` according to normal Cobra persistent-flag behavior, and every help page is generated from command metadata and registered flags rather than duplicated static strings.

The observable behavior is:

    clinic --help
    clinic metrics range --help
    clinic metrics range --env staging --profile blue --cluster-id cluster-1 --query up --start now-5m --end now --output json
    clinic --env staging metrics range --profile blue --cluster-id cluster-1 --query up --start now-5m --end now --output json
    clinic completion bash

Help formatting may change, but the generated output must preserve the important user guidance currently stored in `internal/cmd/help.go`: usage, command summaries, flags, environment/profile fallback notes, time format notes, examples, and command-specific behavior notes such as `metrics range --data-server`.


## Execution Protocol (Mandatory)

Implement this plan sequentially. Do not execute multiple subtasks at the same time.

For every implementation subtask, use a fresh non-inherited subagent session. Give that subagent only this plan path, the current subtask, and the repository context needed for that subtask. The parent agent reviews the result, integrates any needed adjustments, runs the subtask validation commands, commits the subtask changes, and updates the `Progress` section before starting the next subtask.

Each subtask has one commit boundary. Do not start the next subtask until the previous subtask is reviewed, validated, committed, and reflected in `Progress`. If a subtask cannot be completed or committed cleanly, stop and resolve that subtask before moving on.

The operator prompt template for runtimes that require explicit delegation authorization is:

    Implement docs/2026-04-21-cobra-help-generation-plan.md using fresh non-inherited subagents per subtask, sequentially, with parent review/integration, one commit per subtask, and Progress updates after each subtask commit.

If subagents are unavailable in the execution environment, the current agent may execute subtasks directly, but it must preserve the same sequential order, review checkpoint, validation commands, one-commit-per-subtask boundary, and `Progress` updates.


## Progress

- [x] (2026-04-21 Asia/Shanghai) Plan authored for the full Cobra command/help migration.
- [x] (2026-04-21 Asia/Shanghai) Subtask 1: Built the root/helper/template foundation.
- [x] (2026-04-21 Asia/Shanghai) Subtask 2: Migrated `version`, `completion`, `env`, and `switch`.
- [x] (2026-04-21 Asia/Shanghai) Subtask 3: Migrated `auth` and `profile`.
- [x] (2026-04-22 Asia/Shanghai) Subtask 4: Migrated `cluster`, `data`, `events`, and `raw`.
- [x] (2026-04-22 Asia/Shanghai) Subtask 5: Migrated `metrics`, `loki`, and `diagnose`.
- [x] (2026-04-22 Asia/Shanghai) Subtask 6: Removed obsolete static help plumbing, updated docs, and verified the generated-help path.
- [x] (2026-04-22 Asia/Shanghai) Final verification: `make verify` passed and this plan records the outcome.


## Surprises & Discoveries

- Observation: The repository already depends on Cobra and uses it for command dispatch and shell completion.
  Evidence: `go.mod` requires `github.com/spf13/cobra v1.8.1`, and `internal/cmd/root.go` builds a Cobra root command.

- Observation: Help output is intentionally bypassing Cobra generation today.
  Evidence: `internal/cmd/cobra_helpers.go` installs a custom `SetHelpFunc` that writes complete static help strings from `internal/cmd/help.go`.

- Observation: Most command flags are invisible to Cobra today.
  Evidence: leaf commands set `DisableFlagParsing: true`, and handlers parse command flags later with local `flag.FlagSet` values created by `newFlagSet`.

- Observation: `diagnose help` is command input, not a help alias.
  Evidence: `internal/cmd/diagnose_test.go` has `TestDiagnoseAcceptsHelpAsSeed`.

- Observation: During the staged migration, unmigrated family stubs only support persistent global flags before the first command-local positional argument.
  Evidence: after Subtask 1, `TestRootPersistentFlagsWorkAfterCommandFamily` covers `clinic auth --profile blue --env staging show`, while the final `clinic metrics range --env staging ...` contract is deferred until each family is migrated to native Cobra parsing.

- Observation: Migrated families must be registered as native root Cobra commands, not legacy root stubs that call nested command handlers.
  Evidence: an interim Subtask 2 diff made `clinic completion bash --env staging` and `clinic env use staging --env prod` fail with `unknown flag: --env`; the final Subtask 2 diff adds `TestRootPersistentFlagsWorkAfterMigratedCommandArgs` and registers `version`, `completion`, `env`, and `switch` directly on the root command.

- Observation: `auth` can keep its public local `--env` flag while the root also has persistent `--env`.
  Evidence: Subtask 3 adds `TestAuthLocalEnvFlagStillTargetsEnvironment`, which selects root runtime env `prod` while command-local `auth set-key --env staging` mutates the staging auth record.

- Observation: Subtask 4 migrated families need direct root registration, not only native family builders.
  Evidence: review found `cluster`, `data`, `events`, and `raw` initially still flowed through `newRootSubcommand`; Subtask 4 now adds them directly in `newRootCommand` and tests trailing global flags for `data query` and `raw request`.

- Observation: Generated help must carry time-format notes for range-based commands as families migrate.
  Evidence: `events list --help` now documents `now`, `now-<duration>`, local datetimes, and epoch `s/ms/ns`, with assertions in `TestEventsGeneratedHelp` and the subcommand help table.

- Observation: Once `metrics`, `loki`, and `diagnose` moved to native root registration, root tests that intentionally exercise the legacy handler path needed a non-native test family name.
  Evidence: Subtask 5 updates those root tests from `metrics` to `legacy`, while adding `metrics`, `loki`, and `diagnose` to the native root command set.

- Observation: `diagnose help` remains command input after native Cobra parsing.
  Evidence: `TestDiagnoseAcceptsHelpAsSeed` still passes with `diagnose help --cluster-id cluster-42 --since 1h`, and only Cobra `-h`/`--help` renders generated help.

- Observation: Generated help ownership has moved fully into Cobra command builders and the shared template.
  Evidence: `internal/cmd/help.go` was deleted, `rg -n 'HelpText|writeHelp|wantsCommandHelp|wantsSubcommandHelp|setCommandHelpText|newFlagSet|DisableFlagParsing|flag\\.FlagSet' internal/cmd` returns no matches, and the generated-help tests now exercise Cobra command paths.

- Observation: Root and family help now inherit Cobra persistent flag behavior instead of a custom leading-global-options parser.
  Evidence: `make test` and `make verify` both passed after `internal/cmd/root.go` kept `--env`, `--profile`, and `--verbose` as persistent flags and the help template rendered inherited/global flags from command metadata.


## Decision Log

- Decision: Migrate fully to Cobra/pflag parsing for command families.
  Rationale: The user chose option 2 and explicitly said there is no compatibility issue with changing the current help implementation.
  Date/Author: 2026-04-21 / Codex

- Decision: Use a custom Cobra help template, not Cobra's stock template.
  Rationale: Generated help should come from Cobra metadata and flags, but the CLI still needs readable sections for behavior, fallback, time formats, and examples.
  Date/Author: 2026-04-21 / Codex

- Decision: Use Cobra persistent flags for `--env`, `--profile`, and `-v`/`--verbose`.
  Rationale: The user selected persistent global flag behavior, so normal Cobra flag placement is now accepted.
  Date/Author: 2026-04-21 / Codex

- Decision: Migrate by command family stages.
  Rationale: The command surface is broad; family-sized commits keep tests, review, and rollback manageable.
  Date/Author: 2026-04-21 / Codex

- Decision: Do not use Cobra `MarkFlagRequired` for values with env/profile fallbacks.
  Rationale: `--cluster-id`, `--start`, and `--end` may be resolved from `CLINIC_*` variables or selected profile defaults, so Cobra's required-flag validation would reject valid invocations.
  Date/Author: 2026-04-21 / Codex

- Decision: Preserve runtime behavior unless the change is directly caused by Cobra persistent flag placement.
  Rationale: The migration target is generated help and Cobra parsing, not API semantics, config persistence, output schema, or request routing.
  Date/Author: 2026-04-21 / Codex

- Decision: Remove the static help file entirely once the last obsolete help helpers disappeared.
  Rationale: The command builders now own help metadata, and keeping `internal/cmd/help.go` would duplicate the source of truth and confuse future edits.
  Date/Author: 2026-04-22 / Codex


## Outcomes & Retrospective

- Subtask 1 added the shared generated-help template, command metadata helper, root persistent flags, lazy runtime construction from Cobra-parsed globals, and root/global completion wiring. Focused validation passed with:

    go test ./internal/cmd -run 'TestRoot|Test.*Help|TestShellCompletion|TestCompletion' -v

  The migration is intentionally transitional: legacy family handlers still own their static help until later subtasks move each family onto native Cobra commands.

- Subtask 2 migrated `version`, `completion`, `env`, and `switch` to native Cobra parsing and generated help. These commands are now registered directly under the root so inherited `--env`, `--profile`, and `--verbose` flags appear in help and parse after migrated command arguments. Focused validation passed with:

    go test ./internal/cmd -run 'Test(Version|Completion|Env|Switch|.*Help|ShellCompletion)' -v

  Additional local checks covered `clinic completion bash --env staging`, `clinic env use staging --env prod`, and `clinic switch staging --env prod`.

- Subtask 3 migrated `auth` and `profile` to native Cobra parsing and generated help. `auth` keeps command-local `--env` shadowing for target environment selection, and `profile` now uses Cobra arity validation plus per-command profile-name completions for `open`, `use`, `set`, and `delete`. Focused validation passed with:

    go test ./internal/cmd -run 'Test(Auth|Env|Profile|.*Help|ShellCompletion)' -v

  Critical review focused on local `--env` shadowing, profile parsing/flags, completion behavior, and lazy help/runtime paths and found no blocking issues.

- Subtask 4 migrated `cluster`, `data`, `events`, and `raw` to native Cobra parsing and generated help. The migrated families are registered directly on the root command so inherited `--env`, `--profile`, and `--verbose` flags parse after migrated command arguments. `data query` and `events list` use Cobra changed-flag detection for optional-zero behavior, and `raw request` uses repeatable Cobra string-array flags for `--query` and `--header`. Focused validation passed with:

    go test ./internal/cmd -run 'Test(Cluster|Data|Events|Raw|.*Help)' -count=1 -v

  Critical review fixed two issues before commit: direct root registration for the migrated families, and restored `events list` generated help notes for accepted time formats.

- Subtask 5 migrated `metrics`, `loki`, and `diagnose` to native Cobra parsing and generated help. The migrated observability families are registered directly on the root command so inherited global flags parse through Cobra. `metrics` now uses Cobra shorthands for `-p` and `-o`, keeps `--ds` as an alias to `--data-server`, preserves default ECharts output for `metrics range`, and keeps repeatable `metrics series --match`. `loki query` keeps optional positional LogQL and selector label injection, and `diagnose help` remains a seed. Focused validation passed with:

    go test ./internal/cmd -count=1 -run 'Test(Metrics|Loki|Diagnose|EnvFallback|.*Help)' -v

  Additional root-focused validation passed with:

    go test ./internal/cmd -count=1 -run 'TestRootPersistentFlagsWork|TestRootVersionDoesNotRequireRuntimeConfig|TestMigratedRootCommandHelpIncludesGlobalFlags|TestRootParsesLeadingEnvAndProfileBeforeSubcommand|TestRootFallsBack|TestRootRejects' -v

- Subtask 6 removed the obsolete static help path, updated the command-surface and architecture docs, and switched the help tests to exercise generated Cobra output. `internal/cmd/help.go` was deleted, `docs/COMMAND_SURFACE.md` now points at command builders for help ownership, and `docs/ARCHITECTURE.md` describes Cobra persistent flags plus generated help as the request lifecycle source of truth. Verification passed with:

    rg -n 'HelpText|writeHelp|wantsCommandHelp|wantsSubcommandHelp|setCommandHelpText|newFlagSet|DisableFlagParsing|flag\\.FlagSet' internal/cmd
    make legibility-check
    make test
    make verify

  The `rg` scan returned no matches, and both repository-level verification targets passed.


## Context and Orientation

This repository builds `clinic`, a Go CLI for TiDB Cloud Clinic APIs. The binary entrypoint is `cmd/clinic/main.go`, which delegates to `internal/cmd.Run`. Command routing, flag parsing, help text, shell completion, request shaping, and output rendering live in `internal/cmd`.

Current command routing now uses Cobra for both command dispatch and flag parsing. `internal/cmd/root.go` registers `--env`, `--profile`, and `--verbose` as persistent flags on the root command, then dispatches to family handlers such as `metricsCommandHandler`, `lokiCommandHandler`, and `profileCommandHandler`.

Current help text is no longer centralized in a static file. Cobra command builders in `internal/cmd/*.go` own the `Use`, `Short`, `Long`, `Example`, and flag definitions, while `internal/cmd/cobra_helpers.go` owns the shared help template that renders generated output from that metadata.

The target state is different: every command and subcommand should register its arguments and flags directly on Cobra commands. Generated help should use these command fields:

    Use
    Short
    Long
    Example
    Args
    Flags
    PersistentFlags
    ValidArgsFunction where completion needs dynamic values

The migration must retain the existing command package boundaries. Do not introduce a new CLI framework or a generated-code layer. Cobra and pflag are already in the dependency graph and are sufficient.

Important terms:

- Cobra command: `*cobra.Command`, the command object used by `github.com/spf13/cobra`.
- pflag: Cobra's flag package, compatible with GNU-style long and short flags. It differs from Go's standard `flag` package and supports shorthand flags such as `-o`.
- Persistent flag: a Cobra flag inherited by child commands, suitable for root-level global options.
- Generated help: help output produced by Cobra from command metadata and registered flags. In this plan, generated help still uses a custom template.
- Runtime context: `internal/cmd.RuntimeContext`, which stores selected environment/profile, config, client, verbose mode, and diagnostics output.


## Target User Contract

Global flags are Cobra persistent flags:

    --env <env>
    --profile <name>
    --verbose
    -v

These flags may appear in normal Cobra-supported positions. These invocations should resolve the same runtime context:

    clinic --env staging --profile blue metrics query --cluster-id c1 --query up
    clinic metrics query --env staging --profile blue --cluster-id c1 --query up

`clinic version` must remain standalone and must not load config or create a runtime client.

Commands that currently accept env/profile/profile-default fallbacks must keep those fallbacks. Examples:

    metrics range --cluster-id may resolve from flag, CLINIC_CLUSTER_ID, or selected profile cluster_id.
    metrics range --start and --end may resolve from flags, CLINIC_RANGE_* variables, or selected profile range defaults.
    loki query and events list follow the same range fallback rules.

Command-specific validation errors should remain as stable as practical, but exact Cobra wording may change when errors come from Cobra argument or flag parsing. Do not preserve old error messages by adding custom parsing layers unless a test documents a specific message as a public contract.

Generated help must include:

    Usage:
    Available Commands or Subcommands when applicable
    Flags for command-local flags
    Global Flags or inherited flags for --env, --profile, --verbose
    Examples when the old help text had examples
    Long-form behavior notes that affect user decisions

Generated help does not need byte-for-byte compatibility with old static help.


## Interfaces and Dependencies

Primary files to modify:

    internal/cmd/cobra_helpers.go
      Own shared Cobra configuration, custom help template, helper constructors, flag helpers, and error normalization.

    internal/cmd/root.go
      Own root command construction, persistent global flags, runtime context construction from Cobra flag values, and command registration.

    internal/cmd/completion.go
      Keep shell completion generation and dynamic env/profile completions aligned with persistent flags.

    internal/cmd/* command family files
      Move each command's local `flag.FlagSet` declarations onto its Cobra command. Convert `run...` functions to accept parsed values through small option structs or command closures.

    internal/cmd/help_test.go
      Change help tests from static help constants to generated-help assertions.

    internal/cmd/root_test.go
      Add persistent-global flag behavior tests and update or remove tests for `parseLeadingGlobalOptions`.

    internal/cmd/completion_test.go
      Update completion tests if command routing changes completion output.

    docs/COMMAND_SURFACE.md
      Say help ownership is Cobra command metadata plus the shared help template.

    docs/ARCHITECTURE.md
      Describe Cobra as the command parsing, help, and completion source of truth.

Files likely to delete or shrink:

    internal/cmd/help.go
      Deleted after all help constants and `wantsSubcommandHelp` usage were removed.

    newFlagSet in internal/cmd/auth.go
      Delete after all standard-library `flag.FlagSet` parsing is removed.

Do not modify `internal/clinic` for this migration. HTTP behavior is out of scope.


## Plan of Work

### Subtask 1: Root, Helper, And Template Foundation

Scope: introduce the new Cobra foundation while keeping command behavior intact enough to migrate families one by one.

Files:

    Modify: internal/cmd/cobra_helpers.go
    Modify: internal/cmd/root.go
    Modify: internal/cmd/root_test.go
    Modify: internal/cmd/help_test.go
    Modify: internal/cmd/completion.go
    Modify: internal/cmd/completion_test.go if needed

Implementation details:

Add a custom help template in `cobra_helpers.go`. It should render `Long` if present, otherwise `Short`; then usage; aliases only if any are added; available subcommands when present; local flags; inherited global flags; examples when present. Keep output plain text and deterministic.

Add helper functions such as:

    configureCobraCommand(command *cobra.Command, stdout io.Writer)
    configureGeneratedHelp(command *cobra.Command)
    newCommand(meta commandMetadata, stdout io.Writer) *cobra.Command
    cobraNoArgs(commandName string) cobra.PositionalArgs

The exact helper names may vary, but the helpers must stop accepting complete help text as their main input. Metadata and registered flags are now the source of truth.

Change root construction so `newRootCommand` registers persistent flags:

    command.PersistentFlags().String("env", "", "Select the runtime environment for this invocation only.")
    command.PersistentFlags().String("profile", "", "Select an env-local profile for this invocation only.")
    command.PersistentFlags().BoolP("verbose", "v", false, "Print runtime resolution diagnostics and executed API requests to stderr.")

Remove root dependency on `parseLeadingGlobalOptions` for normal execution. `runWithStderr` should build the root command with stdout/stderr, set args directly, and let Cobra parse persistent flags.

Make runtime context construction read the parsed flag values from the root command or from captured variables bound by `StringVar` and `BoolVarP`. Runtime construction must remain lazy so help and completion do not load config or create clients.

Keep `version` standalone. Its command must not call the runtime closure.

Update completion setup to register completion functions on persistent flags. `completionSelectedEnv` should read `env` from the persistent root flag, not from the removed leading-args parser.

Tests to write before implementation:

    TestRootPersistentFlagsWorkBeforeCommand
    TestRootPersistentFlagsWorkAfterCommandFamily
    TestRootVersionDoesNotRequireRuntimeConfig
    TestGeneratedRootHelpIncludesGlobalFlags
    TestShellCompletionSuggestsGlobalEnvValues

Acceptance commands:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    go test ./internal/cmd -run 'TestRoot|Test.*Help|TestShellCompletion|TestCompletion' -v

Expected result: focused tests pass. Some family help tests may still rely on old constants until their family is migrated; if so, keep old paths temporarily and document the transition in `Surprises & Discoveries`.

Commit:

    git add internal/cmd/cobra_helpers.go internal/cmd/root.go internal/cmd/root_test.go internal/cmd/help_test.go internal/cmd/completion.go internal/cmd/completion_test.go docs/2026-04-21-cobra-help-generation-plan.md
    git commit -m "refactor(cmd): add cobra help foundation"


### Subtask 2: Migrate Simple Root Families

Scope: migrate `version`, `completion`, `env`, and `switch` to native Cobra parsing and generated help.

Files:

    Modify: internal/cmd/version.go
    Modify: internal/cmd/completion.go
    Modify: internal/cmd/env.go
    Modify: internal/cmd/switch.go
    Modify: internal/cmd/help_test.go
    Modify: internal/cmd/root_test.go
    Modify: internal/cmd/completion_test.go

Implementation details:

`version`:

Use `Use: "version"`, `Short: "Show clinic CLI version information."`, `Args: cobra.NoArgs`, and `RunE` that prints `Version`. Do not load runtime context.

`completion`:

Use `Use: "completion <bash|zsh|fish|powershell>"`, `Args: cobra.ExactArgs(1)`, and keep `ValidArgsFunction` for supported shells. Generate completion scripts from `defaultRootRunner().newRootCommand`.

`env`:

Use a family command with generated subcommand help. Migrate `env use`, `env current`, and `env list` to Cobra commands. `env use` uses `Args: cobra.ExactArgs(1)`. `env current` and `env list` use `Args: cobra.NoArgs`.

`switch`:

Use `Use: "switch <prod|staging|dev> [profile-name]"` and `Args` that accepts one or two positional args. Preserve behavior: one arg changes active env; two args validates and changes active env plus active profile.

Remove old per-command `wantsSubcommandHelp` checks from these migrated commands because Cobra handles `-h`/`--help`.

Tests to write or update:

    TestVersionGeneratedHelp
    TestCompletionGeneratedHelp
    TestEnvGeneratedHelp
    TestSwitchGeneratedHelp
    TestEnvUseRejectsExtraArgsThroughCobra
    TestSwitchRejectsWrongArityThroughCobra

Acceptance commands:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    go test ./internal/cmd -run 'Test(Version|Completion|Env|Switch|.*Help|ShellCompletion)' -v

Expected result: migrated commands render generated help, existing behavior tests still pass, and completion scripts still generate.

Commit:

    git add internal/cmd/version.go internal/cmd/completion.go internal/cmd/env.go internal/cmd/switch.go internal/cmd/help_test.go internal/cmd/root_test.go internal/cmd/completion_test.go docs/2026-04-21-cobra-help-generation-plan.md
    git commit -m "refactor(cmd): migrate simple commands to cobra parsing"


### Subtask 3: Migrate Auth And Profile

Scope: migrate config-mutating command families that use positional args plus a small flag set.

Files:

    Modify: internal/cmd/auth.go
    Modify: internal/cmd/profile.go
    Modify: internal/cmd/auth_env_test.go
    Modify: internal/cmd/profile_test.go
    Modify: internal/cmd/help_test.go
    Modify: internal/cmd/completion.go
    Modify: internal/cmd/completion_test.go

Implementation details:

`auth`:

Create Cobra subcommands for `set-key`, `unset-key`, `set-url`, and `show`. Register command-local `--env` on auth subcommands exactly where it exists today; this is a target environment flag, separate from the root persistent `--env`. Register `--url` on `set-url`.

Because `auth set-key --env staging` has a local `--env` with different meaning from the persistent root `--env`, test this explicitly. If Cobra reports a duplicate inherited/local flag conflict, rename the command-local binding only internally is not acceptable; the public flag remains `--env`. Resolve by keeping the local flag on auth subcommands and relying on Cobra's local flag shadowing behavior.

`profile`:

Create Cobra subcommands for `list`, `current`, `open`, `use`, `set`, and `delete`. Positional rules:

    profile list: no args
    profile current: no args
    profile open: zero or one arg
    profile use: exactly one arg
    profile set: exactly one arg
    profile delete: exactly one arg

Register `profile set` flags:

    --cluster-id <id>
    --start <start>
    --end <end>

Preserve `profile set current` as the reserved alias for the selected env's active profile.

Keep dynamic completion for profile names on `profile open`, `profile use`, `profile set`, and `profile delete`. Prefer per-command `ValidArgsFunction` over maintaining the old static `familySubcommands` map where practical.

Tests to write or update:

    TestAuthGeneratedHelp
    TestAuthLocalEnvFlagStillTargetsEnvironment
    TestProfileGeneratedHelp
    TestProfileSetGeneratedHelpIncludesCurrentAliasNote
    TestProfileSubcommandsRejectUnexpectedArgsThroughCobra
    TestShellCompletionSuggestsProfileOpenSubcommandAndProfileArguments

Acceptance commands:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    go test ./internal/cmd -run 'Test(Auth|Env|Profile|.*Help|ShellCompletion)' -v

Expected result: existing auth/profile behavior remains green, generated help includes flags and behavior notes, and profile completions still respect selected env.

Commit:

    git add internal/cmd/auth.go internal/cmd/profile.go internal/cmd/auth_env_test.go internal/cmd/profile_test.go internal/cmd/help_test.go internal/cmd/completion.go internal/cmd/completion_test.go docs/2026-04-21-cobra-help-generation-plan.md
    git commit -m "refactor(cmd): migrate auth and profile to cobra parsing"


### Subtask 4: Migrate Cluster, Data, Events, And Raw

Scope: migrate API command families with straightforward flags, repeatable flags, and validation that should remain in command code.

Files:

    Modify: internal/cmd/cluster.go
    Modify: internal/cmd/data.go
    Modify: internal/cmd/events.go
    Modify: internal/cmd/raw.go
    Modify: internal/cmd/cluster_test.go
    Modify: internal/cmd/data_test.go
    Modify: internal/cmd/events_test.go
    Modify: internal/cmd/raw_test.go
    Modify: internal/cmd/help_test.go

Implementation details:

`cluster`:

Create Cobra subcommands for `search`, `search-id`, `get`, `get-by-id`, and `topology`. Register all current flags on the relevant subcommands. Keep required-value checks in the run functions so `--cluster-id` can still resolve through `CLINIC_CLUSTER_ID` or selected profile defaults where applicable.

`data`:

Create Cobra subcommands for `query` and `schema`. Register `--cluster-id`, `--sql`, `--timeout`, and `--tables`. Replace `isFlagProvided(*flag.FlagSet, name)` usage with Cobra/pflag detection:

    command.Flags().Changed("timeout")

`events`:

Create `events list` with `--cluster-id`, `--start`, `--end`, `--name`, `--severity`, `--limit`, and `--cursor`. Use `command.Flags().Changed("severity")` and `command.Flags().Changed("limit")` to preserve current optional-zero behavior.

`raw`:

Create `raw request` with `--method`, `--path`, repeatable `--query`, repeatable `--header`, and `--body`. Implement repeatable flags with pflag `StringArrayVar` or a small `pflag.Value`; preserve current behavior where each repeat adds one entry.

Tests to write or update:

    TestClusterGeneratedHelp
    TestDataGeneratedHelp
    TestEventsGeneratedHelp
    TestRawGeneratedHelp
    TestDataTimeoutChangedDetectionWithCobra
    TestEventsSeverityAndLimitChangedDetectionWithCobra
    TestRawRepeatableQueryAndHeaderFlagsWithCobra
    Existing behavior tests for cluster/data/events/raw

Acceptance commands:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    go test ./internal/cmd -run 'Test(Cluster|Data|Events|Raw|.*Help)' -v

Expected result: API request shapes are unchanged in existing tests, repeatable raw flags still work, optional numeric flags still only appear in requests when explicitly provided, and generated help includes command flags.

Commit:

    git add internal/cmd/cluster.go internal/cmd/data.go internal/cmd/events.go internal/cmd/raw.go internal/cmd/cluster_test.go internal/cmd/data_test.go internal/cmd/events_test.go internal/cmd/raw_test.go internal/cmd/help_test.go docs/2026-04-21-cobra-help-generation-plan.md
    git commit -m "refactor(cmd): migrate api commands to cobra parsing"


### Subtask 5: Migrate Metrics, Loki, And Diagnose

Scope: migrate the highest-detail command families, including short aliases, fallback-heavy flags, optional positional args, and command-specific long help.

Files:

    Modify: internal/cmd/metrics.go
    Modify: internal/cmd/loki.go
    Modify: internal/cmd/diagnose.go
    Modify: internal/cmd/metrics_test.go
    Modify: internal/cmd/loki_test.go
    Modify: internal/cmd/diagnose_test.go
    Modify: internal/cmd/env_fallback_test.go
    Modify: internal/cmd/help_test.go
    Modify: internal/cmd/time_parse_test.go only if flag parsing changes expose a time parsing test issue

Implementation details:

`metrics`:

Create Cobra subcommands for `query`, `range`, and `series`.

Register aliases:

    metrics query: --pool and -p
    metrics range: --pool and -p, --data-server and --ds, --output and -o
    metrics series: --pool and -p, repeatable --match

Because pflag supports shorthand directly, use `BoolVarP` for `-p` and `StringVarP` for `-o`. For `--ds`, use an alias flag that writes to the same `dataServer` bool. Keep validation for `--data-server` with `--pool` in command logic.

Preserve default `metrics range` output behavior: no explicit output means ECharts. Help must say `echarts`, `json`, and `tui` are supported and that TUI requires a terminal.

`loki`:

Create Cobra subcommands for `query`, `instance-map`, `labels`, and `label-values`.

Register aliases:

    loki query: --output and -o
    loki instance-map: --output and -o

For `loki query`, preserve the optional positional `<logql>` argument. Use `Args` allowing zero or one positional arg. Missing logql still builds the default selector. Provided logql still receives default selector label injection where applicable.

`diagnose`:

Register flags directly on the single `diagnose <seed>` command:

    --cluster-id
    --start
    --end
    --since
    --around
    --window
    --limit
    --output
    -o

Use a custom `Args` validator or `RunE` guard so `diagnose help --cluster-id cluster-42 --since 1h` continues to treat `help` as the seed. Only Cobra's built-in `-h` and `--help` should show help.

Tests to write or update:

    TestMetricsGeneratedHelp
    TestMetricsDataServerHelpScope
    TestMetricsRangeShortAliasesWithCobra
    TestMetricsSeriesRepeatableMatchWithCobra
    TestLokiGeneratedHelp
    TestLokiQueryOptionalLogQLWithCobra
    TestLokiOutputShortAliasWithCobra
    TestDiagnoseGeneratedHelp
    TestDiagnoseAcceptsHelpAsSeed
    Existing env fallback tests for metrics/loki/events/cluster

Acceptance commands:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    go test ./internal/cmd -run 'Test(Metrics|Loki|Diagnose|EnvFallback|.*Help)' -v

Expected result: metrics/loki/diagnose generated help includes all important notes, aliases parse through Cobra, env/profile fallback behavior remains green, and `diagnose help` remains a seed.

Commit:

    git add internal/cmd/metrics.go internal/cmd/loki.go internal/cmd/diagnose.go internal/cmd/metrics_test.go internal/cmd/loki_test.go internal/cmd/diagnose_test.go internal/cmd/env_fallback_test.go internal/cmd/help_test.go docs/2026-04-21-cobra-help-generation-plan.md
    git commit -m "refactor(cmd): migrate observability commands to cobra parsing"


### Subtask 6: Remove Old Help Path And Update Docs

Scope: delete obsolete static help plumbing, update command-surface documentation, and run full verification.

Files:

    Modify or delete: internal/cmd/help.go
    Modify: internal/cmd/cobra_helpers.go
    Modify: internal/cmd/help_test.go
    Modify: docs/COMMAND_SURFACE.md
    Modify: docs/ARCHITECTURE.md
    Modify: docs/INDEX.md only if the docs map needs a new historical artifact entry
    Modify: docs/2026-04-21-cobra-help-generation-plan.md

Implementation details:

Search for all old help helpers and constants:

    rg -n 'HelpText|writeHelp|wantsCommandHelp|wantsSubcommandHelp|setCommandHelpText|newFlagSet|DisableFlagParsing|flag\\.FlagSet' internal/cmd

Remove or update every stale reference. The only acceptable remaining help-related code should be Cobra metadata, the custom help template, and tests that exercise generated help.

If `internal/cmd/help.go` is empty or only contains obsolete helpers, delete it. If a tiny helper is still useful, rename it so it no longer suggests static complete help ownership.

Update `docs/COMMAND_SURFACE.md`:

    Replace per-family "Help text: internal/cmd/help.go" lines with "Help metadata: the family's Cobra command builder in internal/cmd/<family>.go".
    Update Shared Command Infrastructure to mention the shared Cobra help template in internal/cmd/cobra_helpers.go.
    Update the command-change checklist so help metadata and registered flags are updated with command handlers.

Update `docs/ARCHITECTURE.md`:

    Describe Cobra as the source of truth for command parsing, generated help, and shell completion.
    Replace the leading-global-options request lifecycle step with Cobra persistent flag parsing.
    Keep runtime selection precedence unchanged.

Tests to write or update:

    TestNoStaticHelpConstantsRemain, if practical, may use a focused source scan in Go or can be covered by the shell search in validation.
    Existing generated help tests should no longer call `writeHelp` or reference static constants.

Acceptance commands:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    rg -n 'HelpText|writeHelp|wantsCommandHelp|wantsSubcommandHelp|setCommandHelpText|newFlagSet|DisableFlagParsing|flag\\.FlagSet' internal/cmd
    make legibility-check
    make test
    make verify

Expected result:

    The `rg` command has no matches for obsolete static help/standard flag parsing symbols, except intentionally retained generated-help helper names if any are documented in the plan.
    `make legibility-check`, `make test`, and `make verify` pass.

Commit:

    git add internal/cmd docs README.md scripts docs/2026-04-21-cobra-help-generation-plan.md
    git commit -m "docs(cmd): document cobra-generated help ownership"


## Validation and Acceptance

After all subtasks are complete, run:

    cd /Users/jujiajia/code/tidbcloud/clinic-cli
    go test ./internal/cmd -run 'Test.*Help' -v
    go test ./internal/cmd -run 'TestCompletion|TestShellCompletion|TestRoot' -v
    make verify

Manual smoke checks:

    go run ./cmd/clinic --help
    go run ./cmd/clinic metrics range --help
    go run ./cmd/clinic loki query --help
    go run ./cmd/clinic diagnose --help
    go run ./cmd/clinic completion bash >/tmp/clinic-completion.bash

Expected observations:

    Root help lists command families and global flags.
    `metrics range --help` includes `--data-server`, `--ds`, `--pool`, `-p`, `--output`, `-o`, output format notes, data-server routing notes, and time format notes.
    `metrics query --help` and `metrics series --help` do not mention `--data-server`.
    `loki query --help` documents the optional LogQL positional arg and output alias.
    `diagnose --help` documents `diagnose <seed>` and flags, while command behavior tests prove `diagnose help ...` remains a seed.
    Completion generation still emits a valid shell completion script.

Full acceptance criteria:

- No migrated command uses `DisableFlagParsing`.
- No migrated command parses user flags through Go's standard `flag.FlagSet`.
- Root globals are Cobra persistent flags.
- Help output is generated from Cobra metadata and registered flags.
- Static complete help constants are removed.
- Existing API request shape and JSON output tests remain green.
- Docs describe the new ownership model.
- `make verify` passes.


## Idempotence and Recovery

Each subtask is safe to retry from a clean commit boundary. If a subtask fails, do not start the next one. Fix the current subtask, rerun its focused validation command, and update `Progress`.

If a family migration becomes too large, split that subtask into two commits only after updating this plan's `Progress`, `Decision Log`, and `Plan of Work` sections with the new boundaries. Keep the sequence parent-reviewed and committed before continuing.

If Cobra persistent flags create unexpected shadowing with `auth` command-local `--env`, stop in Subtask 3. Record the exact error in `Surprises & Discoveries`, add a focused failing test, and resolve while preserving the public `auth ... --env` flag.

If generated help loses important notes from the current static help, treat that as a test failure. Move the note into the command's `Long` text or `Example` field rather than reintroducing static complete help strings.

Rollback is normal git rollback at the last good subtask commit. Do not use destructive reset commands unless the human operator explicitly requests them.


## Artifacts and Notes

Initial exploration evidence:

    go.mod includes github.com/spf13/cobra v1.8.1.
    internal/cmd/cobra_helpers.go currently sets SilenceErrors, SilenceUsage, DisableSuggestions, DisableAutoGenTag, and CompletionOptions.DisableDefaultCmd.
    internal/cmd/cobra_helpers.go currently installs static help through SetHelpFunc.
    internal/cmd/root.go currently calls parseLeadingGlobalOptions before executeCobraCommand.
    internal/cmd/completion.go currently registers root completion flags and dynamic env/profile completion.
    internal/cmd/help_test.go currently verifies fragments from static help constants.

Focused baseline command run before authoring this plan:

    go test ./internal/cmd -run 'Test.*Help|TestCompletion|TestRoot' -v

Result:

    PASS
    ok github.com/tidbcloud/clinic-cli/internal/cmd
