Skip to content

Add Herdr plugin health check to doctor - #185

Merged
yourconscience merged 2 commits into
mainfrom
feat/doctor-herdr-plugins
Sep 22, 2026
Merged

yourconscience merged 2 commits into
mainfrom
feat/doctor-herdr-plugins

Conversation

@yourconscience

@yourconscience yourconscience commented Sep 22, 2026

Copy link
Copy Markdown
Owner

What this does

Adds a herdr plugins check to dotagents doctor and ports the in-progress doctor_herdr work into the new internal/app layout (it was still sitting in cmd/dotagents with the pre-refactor package main, which no longer compiled after #184).

The check runs only inside a Herdr session (HERDR_ENV=1) and inspects the installed plugin manifests and their command logs:

  • a declared command file missing from the plugin root warns with "reinstall or update the plugin"
  • a non-absolute executable that doctor can resolve but the Herdr server could not start warns with the resolved absolute path, so the manifest can be fixed or Herdr restarted with that directory on PATH
  • the latest log for a declared command being failed warns with the log id and error/stderr detail
  • recovered failures (a later success for the same plugin/command) are ignored
  • outside Herdr, the check passes with "not running inside Herdr, skipped"

Manifest platform names are matched against runtime.GOOS with macos mapped to darwin.

Verification

  • go test ./internal/... passes, including 5 tests for the new logic (server PATH mismatch, recovered failure, platform mapping, inline shell program, missing hook file)
  • go build ./... and go vet ./... are clean
  • golangci-lint v2.12.2 on a cold cache with the Go 1.24.2 toolchain reports 0 issues
  • live run against a real Herdr session: herdr plugins .................. pass (5 installed plugins have valid commands and no current command failures)

No behavior change to existing checks; cmd/dotagents stays a thin entrypoint.

Summary by Sourcery

Add Herdr plugin health diagnostics to dotagents doctor.

New Features:

  • Add a Herdr plugin health check to dotagents doctor that validates installed plugin commands and reports actionable issues.

Bug Fixes:

  • Detect missing plugin command files, Herdr server PATH mismatches, and current failed command logs while ignoring recovered failures.

Enhancements:

  • Run plugin checks only within Herdr sessions and support platform-specific manifests, including mapping macos to Darwin.

Tests:

  • Add coverage for PATH mismatches, recovered failures, platform matching, inline shell programs, missing hook files, and Windows-style paths.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@sourcery-ai

sourcery-ai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a Herdr-aware herdr plugins doctor check that gathers plugin manifests and command logs, validates platform-appropriate commands and executable availability, diagnoses missing files and server PATH failures, and reports only current failures with actionable warnings.

Sequence diagram for Herdr plugin health doctor check

sequenceDiagram
    participant Doctor
    participant HerdrCLI
    participant PluginInventory
    participant CommandLogs
    participant HealthAssessment

    Doctor->>Doctor: checkHerdrPluginHealth()
    alt HERDR_ENV is not 1
        Doctor-->>Doctor: pass: not running inside Herdr, skipped
    else Herdr session
        Doctor->>HerdrCLI: plugin list --json
        HerdrCLI-->>PluginInventory: installed plugin manifests
        Doctor->>HerdrCLI: plugin log list
        HerdrCLI-->>CommandLogs: command execution logs
        Doctor->>HealthAssessment: assessHerdrPluginHealth(plugins, logs, lookup)
        HealthAssessment->>HealthAssessment: herdrCommandApplies()
        HealthAssessment->>HealthAssessment: missingHerdrCommandPath()
        HealthAssessment-->>Doctor: pass or actionable warning
    end
Loading

Flow diagram for Herdr plugin health assessment

flowchart TD
    A["Herdr plugin health check"] --> B{HERDR_ENV = 1?}
    B -- No --> C["Pass: skipped outside Herdr"]
    B -- Yes --> D["Read plugin manifests and command logs"]
    D --> E["Select latest log per plugin and command"]
    E --> F{"Platform applies?"}
    F -- No --> G["Ignore command"]
    F -- Yes --> H{"Declared command file missing?"}
    H -- Yes --> I["Warn: reinstall or update plugin"]
    H -- No --> J{"Latest command log failed?"}
    J -- No --> K["Command is healthy"]
    J -- Yes --> L{"Herdr server PATH failure?"}
    L -- Yes --> M["Warn with resolved path or PATH guidance"]
    L -- No --> N["Warn with log ID and error/stderr detail"]
Loading

File-Level Changes

Change Details Files
Registers a new Herdr plugin health check in the doctor workflow.
  • Runs the check alongside existing doctor checks without changing the entrypoint structure.
  • Skips cleanly when not running inside a Herdr session and warns when the Herdr CLI or inspection commands are unavailable.
  • Reports a pass summary when installed plugins have no detected issues.
internal/app/doctor.go
internal/app/doctor_herdr.go
Inspects plugin manifests and command logs to diagnose current plugin health problems.
  • Loads plugin inventory and logs through the Herdr CLI's JSON interfaces.
  • Validates platform-specific commands, including macOS-to-darwin mapping, and detects missing command files.
  • Checks executable resolution and identifies Herdr server PATH mismatches for non-absolute commands.
  • Selects the latest log per plugin and command, ignoring failures superseded by later successes.
  • Produces sorted warnings with remediation guidance and relevant log details.
internal/app/doctor_herdr.go
Adds focused unit coverage for the new health assessment logic.
  • Covers server PATH mismatch diagnosis, recovered failures, platform filtering, inline shell commands, and missing hook files.
  • Uses injected executable lookup and temporary plugin roots to keep assessment tests deterministic.
internal/app/doctor_herdr_test.go

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

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fe48061e-a4f2-4055-a60d-8b18d65705ce


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="internal/app/doctor_herdr.go" line_range="163-177" />
<code_context>
+}
+
+func missingHerdrCommandPath(pluginRoot string, command []string) string {
+	for i, token := range command {
+		if i == 0 && !strings.ContainsRune(token, filepath.Separator) {
+			continue
+		}
+		if strings.HasPrefix(token, "-") || strings.ContainsAny(token, " \t\n\r$\"'`") || (!strings.HasPrefix(token, ".") && !strings.ContainsRune(token, filepath.Separator)) {
+			continue
+		}
+		candidate := token
+		if !filepath.IsAbs(candidate) {
+			candidate = filepath.Join(pluginRoot, candidate)
+		}
+		if _, err := os.Stat(candidate); os.IsNotExist(err) {
+			return candidate
+		}
</code_context>
<issue_to_address>
**issue (bug_risk):** On Windows, a command path using forward slashes, such as `C:/plugin/bin/hook.exe` or `bin/hook.exe`, is not recognized as a path because the code searches only for `filepath.Separator` (`\\`). The first token is skipped and missing files are therefore reported as healthy.

**Triggers:** When a Windows manifest uses `/` as the path separator.

**Suggested fix:** Use path-aware checks such as `filepath.IsAbs` and `filepath.Clean`, or recognize both slash forms when identifying command paths.

```suggestion
	for i, token := range command {
		if i == 0 && !strings.ContainsAny(token, `/\`) {
			continue
		}
		if strings.HasPrefix(token, "-") || strings.ContainsAny(token, " \t\n\r$\"'`") || (!strings.HasPrefix(token, ".") && !strings.ContainsAny(token, `/\`)) {
			continue
		}
		candidate := token
		if !filepath.IsAbs(candidate) {
			candidate = filepath.Join(pluginRoot, candidate)
		}
		if _, err := os.Stat(candidate); os.IsNotExist(err) {
			return candidate
		}
	}
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: internal/app/doctor_herdr.go:177


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread internal/app/doctor_herdr.go

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sourcery assessment

Approved.

@yourconscience
yourconscience merged commit 1c92376 into main Sep 22, 2026
7 checks passed
@yourconscience
yourconscience deleted the feat/doctor-herdr-plugins branch September 22, 2026 14:23
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