Skip to content

Add native hook review and cleanup - #183

Merged
yourconscience merged 2 commits into
mainfrom
feat/native-hook-management-pr
Sep 22, 2026
Merged

yourconscience merged 2 commits into
mainfrom
feat/native-hook-management-pr

Conversation

@yourconscience

@yourconscience yourconscience commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Native hook review and cleanup

Adds a dotagents hook command group so native hook registrations can be inventoried and removed the same way skills and MCP servers already are. Motivated by leftover Orca and cmux hooks that stayed registered in harness configs after those tools were dropped.

What's new

  • dotagents hook list [--agents ...] [query] inventories native hook registrations across harnesses, marks canonical entries as managed, and flags registrations whose script targets are missing as stale.
  • dotagents hook remove [--dry-run] [--agents ...] <query> previews then removes matching registrations surgically, preserving unrelated hooks.
  • dotagents doctor now reports stale native hooks.
  • dotagents sync reconciles the remaining canonical hooks afterward.

Coverage

Claude Code, Codex, Droid, Hermes, and Qwen hook formats are handled, each with tests. Hermes toolset entries (for example orca-status) are left untouched since they are not hooks.

Docs

README and docs/troubleshooting.md document the review/remove flow and the "removed tool left stale native hooks" recovery path.

Verification

  • go test ./..., go build ./..., and go vet ./cmd/dotagents pass.
  • Used the installed CLI to remove the live Orca and cmux registrations; dotagents hook list orca and dotagents hook list cmux both report 0 native hook registration(s).

Summary by Sourcery

Add native hook inventory and cleanup workflows while improving hook health checks and Claude Code synchronization.

New Features:

  • Add commands to inventory and surgically remove native hook registrations across supported harnesses, with filtering, dry-run previews, managed-status reporting, and stale-target detection.

Bug Fixes:

  • Ensure Claude Code hook registrations include the required command type so synchronization and runtime execution recognize them correctly.
  • Detect and report native hooks whose referenced script targets no longer exist.

Enhancements:

  • Extend doctor checks to report native hook health and have sync reconcile remaining canonical hooks.
  • Preserve unrelated registrations while removing only selected native hooks across supported configuration formats.

Documentation:

  • Document native hook review, cleanup, stale-hook recovery, and follow-up sync and doctor workflows.

Tests:

  • Add coverage for native hook discovery and removal across Claude Code, Codex, Droid, Hermes, and Qwen formats, including stale targets and event-scoped cleanup.
  • Add regression coverage for Claude Code hook type rendering and synchronization.

@sourcery-ai

sourcery-ai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a native hook review/removal workflow spanning Claude Code, Codex, Droid, Hermes, and Qwen, with surgical config editing, stale-hook doctor diagnostics, CLI/help integration, documentation, and a Claude hook reconciliation fix.

Sequence diagram for native hook review and surgical removal

sequenceDiagram
    participant User
    participant CLI as dotagents
    participant Collector as collectNativeHooks
    participant Config as Native hook configs
    participant Writer as removeNativeHookEntries

    User->>CLI: dotagents hook list [query]
    CLI->>Collector: collectNativeHooks(home, cfg, selected)
    Collector->>Config: Read Claude, Codex, Droid, Hermes, Qwen configs
    Config-->>Collector: Hook registrations
    Collector-->>CLI: Managed and stale entries
    CLI-->>User: printNativeHooks(entries, unsupported)

    User->>CLI: dotagents hook remove --dry-run query
    CLI->>Collector: collectNativeHooks(home, cfg, selected)
    Collector-->>CLI: Matching registrations
    CLI-->>User: Preview removals

    User->>CLI: dotagents hook remove query
    CLI->>Writer: removeNativeHookEntries(matches)
    Writer->>Config: Rewrite only matching registrations
    Config-->>Writer: Updated native configs
    Writer-->>CLI: Changed file count
    CLI-->>User: Removal summary
Loading

File-Level Changes

Change Details Files
Introduces native hook inventory and surgical cleanup commands across supported harness configuration formats.
  • Adds hook list with agent filtering, query matching, managed ownership labeling, stale script-target detection, and unsupported-surface reporting.
  • Adds hook remove with dry-run preview and event/command-scoped removal that preserves unrelated registrations.
  • Parses Claude Code, Codex, Droid, Hermes, and Qwen hook configurations, while excluding Hermes toolset entries.
  • Adds cross-format collection, stale-target, and scoped-removal tests.
cmd/dotagents/hook_cli.go
cmd/dotagents/hook_cli_test.go
Integrates stale native hook detection into doctor diagnostics and documents the recovery workflow.
  • Adds a native-hooks doctor check reporting registration, managed/unmanaged, unsupported, and stale-target status.
  • Documents hook review, dry-run removal, cleanup, sync, and doctor verification flows.
cmd/dotagents/doctor.go
README.md
docs/troubleshooting.md
Exposes the new hook command group through the CLI dispatcher and help output.
  • Registers hook as a top-level command.
  • Advertises list/remove syntax in short and full usage output.
  • Updates root help coverage tests.
cmd/dotagents/main.go
cmd/dotagents/cli_launch_test.go
Corrects Claude Code hook reconciliation to require and render the command hook type.
  • Treats type-less grouped Claude hook entries as drift.
  • Writes type: command when updating Claude hook entries.
  • Adds regression coverage for in-place repair without duplication.
cmd/dotagents/hooks.go
cmd/dotagents/hooks_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

@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.

@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: 8251eacd-534b-4abf-b20b-13f432a65dc8


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="cmd/dotagents/hook_cli.go" line_range="463-470" />
<code_context>
+var hookScriptPathPattern = regexp.MustCompile(`(?:~|\$\{HOME-\}|\$HOME|/)[^'"[:space:];]+\.(?:sh|py|cmd|ts)`)
+
+func missingHookTarget(command string, home string) string {
+	paths := hookScriptPathPattern.FindAllString(command, -1)
+	if len(paths) == 0 {
+		return ""
+	}
+	seen := make(map[string]bool)
+	for _, path := range paths {
+		path = strings.ReplaceAll(path, "${HOME-}", home)
+		path = strings.ReplaceAll(path, "$HOME", home)
+		path = expandPath(path, home)
+		if seen[path] {
+			continue
+		}
+		seen[path] = true
+		if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
+			return ""
+		}
+	}
+	for path := range seen {
+		return path
+	}
</code_context>
<issue_to_address>
**issue (bug_risk):** `missingHookTarget` returns an empty result as soon as any extracted script path exists, so a command containing both an existing target and a missing target is reported as non-stale even though one of its script targets is missing.

**Triggers:** When a native hook command references multiple `.sh`, `.py`, `.cmd`, or `.ts` paths and at least one exists.

**Suggested fix:** Check every extracted path and return a missing target if any path does not exist; only return empty when all extracted targets exist.

```suggestion
		if _, err := os.Stat(path); err == nil || !os.IsNotExist(err) {
			continue
		}
		return path
	}
	return ""
```
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 1 finding to address first, and the new remove command permanently rewrites native hook configuration and can disable matching command registrations, including ones selected by a broad query; reverting the code will not restore those removed entries. The impact is bounded and manually repairable from configuration backups or by re-registering the hooks, but it is not undone by reverting the PR.

Blocking findings: cmd/dotagents/hook_cli.go:470


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

Comment thread cmd/dotagents/hook_cli.go Outdated
@yourconscience
yourconscience merged commit aa8bcc0 into main Sep 22, 2026
6 checks passed
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