Skip to content

[Repo Assist] feat(diagnose): add --format json flag with structured DiagnoseReport output#4571

Merged
ksail-bot[bot] merged 8 commits into
mainfrom
repo-assist/feat-diagnose-json-format-b49a9580edaa97d0
May 4, 2026
Merged

[Repo Assist] feat(diagnose): add --format json flag with structured DiagnoseReport output#4571
ksail-bot[bot] merged 8 commits into
mainfrom
repo-assist/feat-diagnose-json-format-b49a9580edaa97d0

Conversation

@github-actions

@github-actions github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

🤖 This is an automated PR from Repo Assist.

Summary

Adds structured JSON output support to ksail cluster diagnose, directly advancing the roadmap "Next" item: "enriched MCP tool output (cluster_read tool surfaces diagnosis data for AI assistants)".

What changed

pkg/k8s/diagnostics.go — new types and function:

  • DiagnoseSeverity (critical / warning)
  • DiagnoseFinding — resource, reason, severity per unhealthy item
  • DiagnoseReport — cluster name, healthScore (0–100), and findings slice
  • DiagnoseClusterReport() — structured equivalent of the existing DiagnoseCluster(); existing text path is unchanged

pkg/cli/cmd/cluster/cluster.go — new --format flag:

  • Default: text — existing behaviour preserved exactly
  • --format json — marshals a DiagnoseReport as indented JSON to stdout

Health scoring: starts at 100, deducts 25 per critical finding (not-ready node, failing pod), deducts 10 per warning, floors at 0.

Example JSON output

{
  "clusterName": "my-cluster",
  "healthScore": 75,
  "findings": [
    {
      "severity": "critical",
      "resource": "pod/crash-demo (default)",
      "reason": "crash-demo: CrashLoopBackOff for myimage:latest (3 restarts)"
    }
  ]
}

Why this matters

The cluster_read MCP tool is auto-generated from ksail cluster diagnose. AI assistants (Claude, Copilot) that call cluster_read currently receive free-form text. With --format json the MCP server can pass a structured report — numeric health score + typed findings — that AI models can reason over without parsing prose.

Type of change

  • 🚀 New feature

Test Status

  • go build ./... — ✅ passes
  • go test ./pkg/k8s/... ./pkg/cli/cmd/cluster/... — ✅ passes
  • go vet ./pkg/k8s/... ./pkg/cli/cmd/cluster/... — ✅ passes
  • 5 new unit tests added for DiagnoseClusterReport covering: healthy cluster (score=100), failing pod (score=75), not-ready node (score=75), score floor at zero, node list error surfaced

Partial fix for #4422.

Generated by 🤖 Repo Assist, see workflow run.

… output

Add DiagnoseReport struct with HealthScore (0-100) and Findings slice
to pkg/k8s/diagnostics.go. Introduce DiagnoseClusterReport() alongside
the existing DiagnoseCluster() so callers can request structured output
without breaking the default text path.

Wire --format flag (text|json) into ksail cluster diagnose. When
--format json is passed, the command marshals a DiagnoseReport to
stdout, making the cluster_read MCP tool useful for AI assistants that
need numeric health signals and structured finding data rather than
free-form text.

Each critical finding (not-ready node, failing pod) deducts 25 points
from the 100-point HealthScore; warnings deduct 10 points; score floors
at 0.

Closes #4422 (partial — structured scoring + JSON output path)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-project-automation github-project-automation Bot moved this to 🫴 Ready in 🌊 Project Board May 4, 2026
@devantler devantler marked this pull request as ready for review May 4, 2026 05:30
@devantler devantler self-requested a review as a code owner May 4, 2026 05:30
@devantler devantler requested review from Copilot May 4, 2026 05:30
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor Author

MegaLinter analysis: Success

✅ Linters with no issues

actionlint, git_diff, hadolint, jscpd, jsonlint, lychee, markdown-table-formatter, markdownlint, prettier, prettier, stylelint, syft, trivy-sbom, trufflehog, v8r, v8r, yamllint

See detailed reports in MegaLinter artifacts

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

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 adds machine-readable JSON output to ksail cluster diagnose so diagnosis data can be consumed by MCP/chat tooling without parsing free-form text. It extends the existing Kubernetes diagnostics flow with a structured report type and exposes it through a new CLI flag on the cluster command.

Changes:

  • Added structured diagnosis types and DiagnoseClusterReport() in pkg/k8s with severity-tagged findings and a computed health score.
  • Added --format to ksail cluster diagnose and wired --format json to emit indented JSON instead of the existing text output.
  • Added unit coverage for the new report builder and a command-construction test for the new flag.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
pkg/k8s/diagnostics.go Introduces structured diagnosis models and JSON-oriented report generation.
pkg/k8s/diagnostics_test.go Adds report-focused tests for scoring and error propagation.
pkg/cli/cmd/cluster/cluster.go Adds the new --format flag and JSON output branch for cluster diagnose.
pkg/cli/cmd/cluster/cluster_test.go Verifies the new diagnose flag is registered with the expected default.

Comment thread pkg/cli/cmd/cluster/cluster.go Outdated
@codecov

codecov Bot commented May 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.70732% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/cli/cmd/cluster/cluster.go 56.66% 13 Missing ⚠️
pkg/k8s/diagnostics.go 96.15% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 2fbcc29 Previous: f3bb082 Ratio
BenchmarkCluster_MarshalJSON/FullProductionCluster (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) 179127 ns/op 20591 B/op 463 allocs/op 66775 ns/op 20581 B/op 463 allocs/op 2.68
BenchmarkCluster_MarshalJSON/FullProductionCluster (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) - ns/op 179127 ns/op 66775 ns/op 2.68
BenchmarkYAMLEncode/Minimal (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) 162826 ns/op 21240 B/op 386 allocs/op 61046 ns/op 21240 B/op 386 allocs/op 2.67
BenchmarkYAMLEncode/Minimal (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) - ns/op 162826 ns/op 61046 ns/op 2.67
BenchmarkYAMLEncode/FullProductionCluster (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) 212015 ns/op 32368 B/op 431 allocs/op 70106 ns/op 32368 B/op 431 allocs/op 3.02
BenchmarkYAMLEncode/FullProductionCluster (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) - ns/op 212015 ns/op 70106 ns/op 3.02
BenchmarkJSONEncode (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) 153337 ns/op 15754 B/op 382 allocs/op 58769 ns/op 15751 B/op 382 allocs/op 2.61
BenchmarkJSONEncode (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) - ns/op 153337 ns/op 58769 ns/op 2.61
BenchmarkPruneClusterDefaults/MostlyDefaults (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) 52036 ns/op 7856 B/op 225 allocs/op 27682 ns/op 7856 B/op 225 allocs/op 1.88
BenchmarkPruneClusterDefaults/MostlyDefaults (github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1) - ns/op 52036 ns/op 27682 ns/op 1.88

This comment was automatically generated by workflow using github-action-benchmark.

Add early validation for the --format flag in runDiagnoseCmd that
normalises the value to lower-case and returns ErrUnsupportedOutputFormat
for any value other than "text" or "json". This prevents typos like
--format jsn from silently falling back to the text path, which would
cause MCP/automation callers to receive prose when they expected JSON.

Reuses the existing ErrUnsupportedOutputFormat sentinel and
outputFormatText/outputFormatJSON constants for consistency with the
--output flag validation pattern already in this package.

Also add:
- TestDiagnoseCmd_InvalidFormatRejectsEarly to cover the new guard
- TestDiagnoseClusterReport_PodListErrorCreatesWarningFinding to cover
  the DiagnoseSeverityWarning path in DiagnoseClusterReport

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Extract score calculation into diagnoseComputeScore to reduce cyclomatic
  complexity of DiagnoseClusterReport from 13 to below the max of 10
- Extract pod-listing loop into appendNamespacePodFindings for the same reason
- Replace magic numbers 100/25/10 with named constants
  (diagnoseMaxHealthScore, diagnoseCriticalPenalty, diagnoseWarningPenalty)
- Wrap json.Encoder.Encode error to satisfy wrapcheck linter

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Split long function signatures (>120 chars) for DiagnoseClusterReport
  and appendNamespacePodFindings across multiple lines (lll)
- Extract runDiagnoseJSONReport helper to keep runDiagnoseCmd within
  the 60-line limit (funlen)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
golangci-lint auto-formats imports on each run; pre-applying this
avoids the git-auto-commit-action conflicting during CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…v5, gofmt)

Fix import ordering in cluster.go to match gci's expected section order
(standard → devantler-tech prefix → external), split enc.Encode assignment
per wsl_v5 requirement, and fix indentation in diagnostics_test.go.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ksail-bot ksail-bot Bot added this pull request to the merge queue May 4, 2026
Merged via the queue into main with commit 2babfca May 4, 2026
71 checks passed
@ksail-bot ksail-bot Bot deleted the repo-assist/feat-diagnose-json-format-b49a9580edaa97d0 branch May 4, 2026 22:02
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants