Skip to content

Migrate cobra command examples from Long: prose to Example: field#38946

Merged
pelikhan merged 4 commits into
mainfrom
copilot/migrate-command-examples-to-field
Jun 13, 2026
Merged

Migrate cobra command examples from Long: prose to Example: field#38946
pelikhan merged 4 commits into
mainfrom
copilot/migrate-command-examples-to-field

Conversation

Copilot AI commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

None of the ~36 cobra command definitions in pkg/cli/ used the Example: field — all commands with usage examples embedded them as hand-written prose inside Long:. This breaks cobra/doc.GenMarkdownTree() docs generation and makes examples untestable.

Changes

Command files (36 files)

Moved Examples: sections from Long: to the cobra Example: field across all command files. Two source patterns handled:

  • Pattern A — pure backtick Long: string: split at \n\nExamples:\n boundary
  • Pattern BWorkflowIDExplanation concatenation: cleaned up empty-string artifact after split

Before / After:

// Before
Long: `...prose...

Examples:
  ` + string(constants.CLIExtensionPrefix) + ` audit --output ./logs`,

// After
Long: `...prose...`,
Example: `  ` + string(constants.CLIExtensionPrefix) + ` audit --output ./logs`,

Secondary fixes (8 files)

8 files had non-example prose (e.g., Workflow specifications:, Repository modes:, The command will:) that ended up in Example: due to being interleaved after the Examples: section in the original Long:. Moved back to Long: where they belong: add_command.go, add_wizard_command.go, mcp_add.go, mcp_inspect.go, mcp_list.go, mcp_list_tools.go, trial_command.go, pr_command.go.

Test updates (5 files)

Tests asserting cmd.Long contained example strings updated to check cmd.Example instead: cli_consistency_help_test.go, completion_command_test.go, logs_command_test.go, mcp_server_command_test.go, upgrade_command_test.go.

Copilot AI changed the title [WIP] Migrate cobra command examples from Long to Example field Migrate cobra command examples from Long: prose to Example: field Jun 12, 2026
Copilot AI requested a review from pelikhan June 12, 2026 22:35
@pelikhan pelikhan marked this pull request as ready for review June 12, 2026 22:53
Copilot AI review requested due to automatic review settings June 12, 2026 22:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates CLI usage examples across pkg/cli/ from hand-written “Examples:” prose embedded in cobra.Command.Long into Cobra’s dedicated cobra.Command.Example field, improving cobra/doc.GenMarkdownTree() doc generation and making examples easier to validate in tests.

Changes:

  • Moved command examples out of Long: strings into Example: across a broad set of Cobra command definitions.
  • Kept non-example explanatory text (e.g., “Repository modes”, “The command will:”) in Long: where appropriate.
  • Updated help-text consistency tests to assert against cmd.Example instead of cmd.Long.
Show a summary per file
File Description
pkg/cli/view_command.go Moves view examples into Example:.
pkg/cli/validate_command.go Moves validate examples into Example: while keeping WorkflowIDExplanation in Long:.
pkg/cli/upgrade_command.go Moves upgrade examples into Example:.
pkg/cli/upgrade_command_test.go Updates assertions to check cmd.Example.
pkg/cli/update_command.go Moves update examples into Example:.
pkg/cli/trial_command.go Keeps repository-mode prose in Long: and moves runnable examples into Example:.
pkg/cli/tokens_bootstrap.go Moves secrets bootstrap examples into Example:.
pkg/cli/status.go Moves status examples into Example:.
pkg/cli/secrets_command.go Moves secrets examples into Example:.
pkg/cli/secret_set_command.go Moves secrets set examples into Example:.
pkg/cli/project_command.go Moves project and project new examples into Example:.
pkg/cli/pr_command.go Moves pr / pr transfer examples into Example:.
pkg/cli/outcomes_history.go Moves outcomes history examples into Example:.
pkg/cli/outcomes_command.go Moves outcomes examples into Example:.
pkg/cli/mcp.go Moves mcp examples into Example:.
pkg/cli/mcp_server_command.go Moves mcp-server examples into Example:.
pkg/cli/mcp_server_command_test.go Updates assertions to check cmd.Example.
pkg/cli/mcp_list.go Moves mcp list examples into Example:.
pkg/cli/mcp_list_tools.go Moves mcp list-tools examples into Example:.
pkg/cli/mcp_inspect.go Moves mcp inspect examples into Example:.
pkg/cli/mcp_add.go Moves mcp add examples into Example:.
pkg/cli/logs_command.go Moves extensive logs examples into Example:.
pkg/cli/logs_command_test.go Splits expectations: Long section checks vs Example content checks.
pkg/cli/list_workflows_command.go Moves list examples into Example:.
pkg/cli/lint_command.go Moves lint examples into Example:.
pkg/cli/init_command.go Moves init examples into Example:.
pkg/cli/health_command.go Moves health examples into Example:.
pkg/cli/hash_command.go Moves hash-frontmatter examples into Example:.
pkg/cli/forecast_command.go Moves forecast examples into Example:.
pkg/cli/fix_command.go Moves fix examples into Example:.
pkg/cli/experiments_command.go Moves experiments examples into Example: for command + subcommands.
pkg/cli/domains_command.go Moves domains examples into Example:.
pkg/cli/deploy_command.go Moves deploy examples into Example:.
pkg/cli/completion_command.go Moves completion usage examples into Example: for command + subcommands.
pkg/cli/completion_command_test.go Updates assertions to check cmd.Example.
pkg/cli/cli_consistency_help_test.go Updates consistency expectations to reflect Example: usage.
pkg/cli/checks_command.go Moves checks examples into Example:.
pkg/cli/audit.go Moves audit examples into Example:.
pkg/cli/audit_diff_command.go Moves audit diff examples into Example:.
pkg/cli/add_wizard_command.go Moves add-wizard examples into Example:.
pkg/cli/add_command.go Moves add examples into Example:.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 41/41 changed files
  • Comments generated: 0

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer failed during the skills-based review.

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (148 new lines in pkg/cli/, above the 100-line threshold) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/38946-use-cobra-example-field-for-command-examples.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff and description.
  2. Complete the missing sections — confirm the decision rationale, refine the alternatives, and adjust consequences as needed.
  3. Commit the finalized ADR to docs/adr/ on your branch (change Status from Draft to Proposed/Accepted).
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-38946: Use Cobra's Example field for command usage examples

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

ADRs create a searchable, permanent record of why the codebase looks the way it does. Adopting cobra's native Example: field as the standard convention across all ~36 commands is exactly the kind of API-convention decision future contributors will want documented.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number.

🔒 This gate is blocking: link the ADR in the PR body to unblock merge.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · 107 AIC · ⌖ 9.59 AIC · ⊞ 13.8K ·

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 70/100 — Acceptable

Analyzed 6 test function(s): 6 design, 0 implementation, 0 guideline violation(s). All modifications track the PR refactoring — moving example assertions from cmd.Long to cmd.Example.

📊 Metrics & Test Classification (6 tests analyzed)
Metric Value
New/modified tests analyzed 6
✅ Design tests (behavioral contracts) 6 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 0 (0%)
Duplicate test clusters 0
Test inflation detected No
🚨 Coding-guideline violations 0

Test Classification Details

Test File Classification Notes
TestTrialCommandUsesStandardExamplesHeading pkg/cli/cli_consistency_help_test.go:23 ✅ Design Verifies cmd.Example is not empty; asserts examples not duplicated in cmd.Long
TestCompletionCommand_Examples pkg/cli/completion_command_test.go:129 ✅ Design Verifies all 5 shell examples present in cmd.Example; ⚠️ 5 assertions lack message args (pre-existing)
TestNewLogsCommand pkg/cli/logs_command_test.go:18 ✅ Design Verifies cache-before example migrated to cmd.Example
TestLogsCommandHelpText pkg/cli/logs_command_test.go:260 ✅ Design Refactored to check cmd.Long for prose, cmd.Example for commands
TestNewMCPServerCommand_PortExampleMentionsSSE pkg/cli/mcp_server_command_test.go:13 ✅ Design Verifies SSE transport example is in cmd.Example
TestUpgradeCommandHelpTextConsistency pkg/cli/upgrade_command_test.go:23 ✅ Design Verifies stable-release note migrated to cmd.Example

Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 6 tests — unit (//go:build !integration)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests
⚠️ Flagged Tests — Minor Issues (1)

⚠️ TestCompletionCommand_Examples (pkg/cli/completion_command_test.go:129)

Classification: Design test (no change to verdict)
Issue: 5 assert.Contains calls have no message argument (pre-existing, not introduced by this PR). E.g., assert.Contains(t, cmd.Example, "gh aw completion bash") should be assert.Contains(t, cmd.Example, "gh aw completion bash", "completion bash example should be in Example field").
What design invariant does this test enforce? That the cobra Example field contains working shell examples for all supported shells — an observable contract for users running gh aw completion --help.
What would break if deleted? A future refactoring could remove shell examples from cmd.Example undetected.
Suggested improvement: Add a descriptive message to each assert.Contains call so failures are immediately actionable without reading the source code.

Verdict

Check passed. 0% of modified tests are implementation tests (threshold: 30%). No coding-guideline violations detected.

Note on edge-case score: Edge-case coverage scores 0/30 because this is a structural refactoring PR — there are no error paths to exercise when verifying cobra field assignments. This is expected and not a concern.

📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §27447688241

🧪 Test quality analysis by Test Quality Sentinel · 276 AIC · ⌖ 28.4 AIC · ⊞ 27.2K ·

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 70/100. Test quality is acceptable — 0% of modified tests are implementation tests (threshold: 30%). All 6 test modifications are design tests verifying observable cobra command fields. No coding-guideline violations detected.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 600.7 AIC · ⌖ 13.8 AIC · ⊞ 27.8K

Comment thread pkg/cli/add_command.go
` + string(constants.CLIExtensionPrefix) + ` add ./my-workflow.md # Add local workflow
` + string(constants.CLIExtensionPrefix) + ` add ./*.md # Add all local workflows
` + string(constants.CLIExtensionPrefix) + ` add githubnext/agentics/ci-doctor --dir .github/workflows/shared # Add to .github/workflows/shared/
`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/zoom-out] Trailing \n inconsistency: this Example field ends with a blank line before the closing backtick, but the majority of the 36 migrated commands do not. Seven files share this pattern (add_command.go, add_wizard_command.go, mcp_add.go, mcp_inspect.go, mcp_list.go, mcp_list_tools.go, trial_command.go). Cobra normalises trailing whitespace in help output so this is invisible at runtime, but the source inconsistency will make future diffs noisier.

💡 Suggested fix

Remove the blank line before the closing backtick in all seven files:

// Before
		Example: `  gh aw add ...
  gh aw add ./*.md
`,
// After
		Example: `  gh aw add ...
  gh aw add ./*.md`,

This makes the style consistent with the other 29 migrated commands.

assert.Contains(t, preReleasesFlag.Usage, "Include pre-release versions", "--pre-releases description should mention pre-release upgrades")
assert.Contains(t, preReleasesFlag.Usage, "installed by exact tag", "--pre-releases description should explain prerelease pinning")
assert.Contains(t, cmd.Long, "stable releases are the default", "help text should distinguish stable releases from prereleases")
assert.Contains(t, cmd.Example, "stable releases are the default", "help text should distinguish stable releases from prereleases")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] This assertion now pins a behavioural claim ("stable releases are the default") to the Example: field rather than Long:. The text passes because it happens to appear as an inline comment in an example line, but the test intent — verifying that the help text explains the stable/pre-release distinction as a concept — is no longer matched to the right field.

💡 Suggested improvement

Add a dedicated sentence to Long: in upgrade_command.go that explicitly mentions the stable/prerelease default, then assert cmd.Long for that prose and keep a separate cmd.Example assertion for the example line:

// upgrade_command.go – add to Long:
assert.Contains(t, cmd.Long, "stable releases are the default", ...)
// and keep the existing example test separate
assert.Contains(t, cmd.Example, "--pre-releases", ...)

This way the test message "help text should distinguish stable releases from prereleases" accurately reflects what is being verified.

cmd := NewTrialCommand(func(string) error { return nil })

assert.Contains(t, cmd.Long, "Examples:", "trial long help should use the standard examples heading")
assert.NotEmpty(t, cmd.Example, "trial command should use cobra's Example field for examples")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] assert.NotEmpty checks only the trial command; a new command added without an Example: field would silently regress. Since this PR just established the contract across 36 commands, now is a natural time to add a table-driven guard.

💡 Suggested extension
func TestAllCommandsHaveExampleField(t *testing.T) {
    root := NewRootCommand()
    for _, cmd := range root.Commands() {
        if cmd.Runnable() {
            assert.NotEmpty(t, cmd.Example, "%s should define cobra Example: field", cmd.Name())
        }
        for _, sub := range cmd.Commands() {
            if sub.Runnable() {
                assert.NotEmpty(t, sub.Example, "%s %s should define cobra Example: field", cmd.Name(), sub.Name())
            }
        }
    }
}

This acts as a lint guard preventing future regressions without any per-command boilerplate.

Comment thread pkg/cli/add_command.go
`,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("missing workflow specification\n\nUsage:\n %s <workflow>...\n\nExamples:\n %[1]s githubnext/agentics/daily-repo-status Add from repository\n %[1]s ./my-workflow.md Add local workflow\n\nRun '%[1]s --help' for more information", cmd.CommandPath())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/zoom-out] The Args validation error string still contains "Examples:" (plural, old style) as an embedded heading. This is unrelated to cobra.Command.Example: but is a user-facing string that now looks inconsistent post-migration. The same pattern exists in deploy_command.go (line 83).

💡 Optional cleanup

Update the error format string to use "Example:" (singular, matching cobra convention):

return fmt.Errorf(
    "missing workflow specification\n\nUsage:\n  %s <workflow>...\n\nExample:\n  ...",
    cmd.CommandPath(),
)

This is non-blocking but keeps user-visible text consistent.

@pelikhan pelikhan merged commit 9cf637b into main Jun 13, 2026
29 checks passed
@pelikhan pelikhan deleted the copilot/migrate-command-examples-to-field branch June 13, 2026 03:00
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.

3 participants