Skip to content

Add hooks to Claude plugin and Gemini extension#11

Merged
hawkeyexl merged 13 commits intomainfrom
hook
Mar 29, 2026
Merged

Add hooks to Claude plugin and Gemini extension#11
hawkeyexl merged 13 commits intomainfrom
hook

Conversation

@hawkeyexl
Copy link
Copy Markdown
Contributor

@hawkeyexl hawkeyexl commented Mar 26, 2026

Add hooks to streamline Doc Detective usage and avoid high-traffic errors.

Summary by CodeRabbit

  • New Features

    • Added automated editor/session hooks: pre-edit blocking, post-edit validate/format/suggest/warn, and session-start install/status checks; hooks are wired into plugin and root artifacts.
  • Tests

    • Added unit & integration tests, test helpers, and a CI workflow to run hook tests.
  • Documentation

    • Documented hooks usage, installation, build integration, and guardrails in README and GEMINI.md.
  • Chores

    • Bumped package/manifests to 1.3.0 and updated build/pre-commit to include hooks artifacts.

Copilot AI review requested due to automatic review settings March 26, 2026 20:39
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

Warning

Ignoring CodeRabbit configuration file changes. For security, only the configuration from the base branch is applied for open source repositories.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 52a81682-13e6-4402-9e4e-d9b34d1223cb

📥 Commits

Reviewing files that changed from the base of the PR and between 0b311b8 and 25ecc4b.

📒 Files selected for processing (1)
  • .coderabbit.yaml
✅ Files skipped from review due to trivial changes (1)
  • .coderabbit.yaml

Walkthrough

Adds a hooks system: new source hooks in src/hooks/, build logic to sync them into hooks/ and plugins/doc-detective/hooks/, hook configs for Claude/Gemini/plugin contexts, pre/post/edit/session hook scripts and tests, docs updates, and metadata version bumps to 1.3.0.

Changes

Cohort / File(s) Summary
Build & CI
build.js, .husky/pre-commit, .github/workflows/test-hooks.yml, package.json
Added syncHooks() to build (produce hooks/ and plugin hook dirs, set script modes), extended pre-commit staged paths, added Mocha devDep & npm scripts, and a GH Actions workflow for hook tests.
Hook Sources & Artifacts
src/hooks/..., hooks/..., plugins/doc-detective/hooks/...
Introduced provider-specific hook JSON and executable scripts under src/hooks/; build mirrors and renames provider JSON into root hooks/ and plugin hook dir.
Hook Configurations
src/hooks/claude-hooks.json, src/hooks/gemini-hooks.json, hooks/hooks.json, plugins/doc-detective/hooks/hooks.json
Defined lifecycle wiring (PreTool/BeforeTool, PostTool/AfterTool, SessionStart) with matchers and timeouts that invoke the new scripts.
Hook Implementations
src/hooks/scripts/*.js, src/hooks/scripts/*.sh
Added pre-edit blocker, post-edit validator, suggester, formatter, inline-test warden, and session-start install-check hook scripts (executable).
Plugin Mirrors
plugins/doc-detective/hooks/scripts/*, plugins/doc-detective/hooks/hooks.json
Plugin-scoped copies of hook configs and scripts for plugin runtime context.
Tests & Helpers
tests/hooks/helpers.js, tests/hooks/*.test.js, tests/hooks/integration.test.js
Comprehensive unit and integration tests plus helpers to execute hooks and CLI runners.
Documentation
README.md, GEMINI.md, .claude/skills/monitor-pr/SKILL.md
Documented hooks system, install/build instructions, guardrails, and a PR-monitoring instruction.
Version / Metadata Bumps
package.json, gemini-extension.json, .claude-plugin/marketplace.json, plugins/.../SKILL.md, src/*, skills/*, agents/*
Bumped package and numerous manifest/skill/agent metadata from 1.2.01.3.0.
Configs & Misc
.coderabbit.yaml, gemini-hook-test.json, test-hook.md, hooks/hooks.json
Added CodeRabbit config, test fixtures, top-level hooks manifest, and example test files.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Editor
participant HookRunner
participant PreHook
participant PostHooks
participant FileSystem
participant ValidatorCLI

Editor->>HookRunner: write/edit file (tool event)
HookRunner->>PreHook: invoke pre-edit handler
PreHook-->>HookRunner: exit 0 or non‑zero (block)
alt not blocked
HookRunner->>PostHooks: invoke post-edit handlers (validate, suggest, format, warn)
PostHooks->>FileSystem: read/write target file
PostHooks->>ValidatorCLI: exec validator
ValidatorCLI-->>PostHooks: stdout/stderr
PostHooks->>HookRunner: emit additionalContext JSON
end
Note right of HookRunner: SessionStart -> session-start install-check script

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • jstjoe

Poem

"🐇 Hoppity-hop, the hooks now sing,

Pre-edits stop the sneaky string,
Post-edits nudge, format, and test,
Session checks tell you what's best,
Little rabbit cheers — hello 1.3.0!"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add hooks to Claude plugin and Gemini extension' clearly and concisely describes the main change across the changeset—the introduction of lifecycle hooks (pre-edit validation, post-edit formatting, session-start checks) integrated into both the Claude plugin and Gemini extension.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hook

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 and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds automatic hook-based guardrails for the Doc Detective Claude plugin and Gemini extension to reduce common spec-format mistakes, validate/format specs, and surface install/test reminders; also bumps the package/plugin version to 1.3.0.

Changes:

  • Add hook scripts (pre-write blocker, post-edit validators/formatters/warnings, session-start install check) and hook config files for Claude + Gemini.
  • Update build pipeline to sync hooks into build artifacts and plugin output.
  • Bump version metadata across skills/agents/plugin/extension and document hook behavior.

Reviewed changes

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

Show a summary per file
File Description
src/skills/doc-detective-validate/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-test/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-project-bootstrap/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-install-github-action/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-inline-test-injection/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-inject/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-init/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-generate/SKILL.md Bump skill metadata version to 1.3.0
src/skills/doc-detective-doc-testing/SKILL.md Bump skill metadata version to 1.3.0
src/hooks/scripts/session-start-check-install.sh Add session-start CLI availability check hook script
src/hooks/scripts/pre-edit-block-action-antipattern.js Add pre-write blocker for {"action":"..."} anti-pattern
src/hooks/scripts/post-edit-warn-inline-tests.js Add warning hook for edits to docs with inline tests
src/hooks/scripts/post-edit-validate-test-spec.js Add post-edit auto-validation hook for JSON test specs
src/hooks/scripts/post-edit-suggest-testing.js Add doc-edit reminder hook when Doc Detective config exists
src/hooks/scripts/post-edit-format-test-spec.js Add post-edit JSON formatting hook for test specs
src/hooks/gemini-hooks.json Add Gemini hook configuration wiring to scripts
src/hooks/claude-hooks.json Add Claude hook configuration wiring to scripts
src/agents/doc-detective-specialist.md Bump agent metadata version to 1.3.0
skills/doc-detective-validate/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-test/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-project-bootstrap/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-install-github-action/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-inline-test-injection/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-inject/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-init/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-generate/SKILL.md Bump artifact skill metadata version to 1.3.0
skills/doc-detective-doc-testing/SKILL.md Bump artifact skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-validate/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-test/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-project-bootstrap/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-install-github-action/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-inline-test-injection/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-inject/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-init/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-generate/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/skills/doc-detective-doc-testing/SKILL.md Bump plugin skill metadata version to 1.3.0
plugins/doc-detective/hooks/scripts/session-start-check-install.sh Add plugin-distributed session-start install check script
plugins/doc-detective/hooks/scripts/pre-edit-block-action-antipattern.js Add plugin-distributed pre-write anti-pattern blocker
plugins/doc-detective/hooks/scripts/post-edit-warn-inline-tests.js Add plugin-distributed inline-test warning hook
plugins/doc-detective/hooks/scripts/post-edit-validate-test-spec.js Add plugin-distributed post-edit spec validator hook
plugins/doc-detective/hooks/scripts/post-edit-suggest-testing.js Add plugin-distributed doc-edit test reminder hook
plugins/doc-detective/hooks/scripts/post-edit-format-test-spec.js Add plugin-distributed post-edit spec formatter hook
plugins/doc-detective/hooks/hooks.json Add Claude plugin hook config (renamed from claude-hooks.json in build)
plugins/doc-detective/agents/doc-detective-specialist.md Bump plugin agent metadata version to 1.3.0
plugins/doc-detective/.claude-plugin/plugin.json Bump plugin.json version to 1.3.0
package.json Bump package version to 1.3.0
hooks/scripts/session-start-check-install.sh Add root artifact session-start install check script
hooks/scripts/pre-edit-block-action-antipattern.js Add root artifact pre-write anti-pattern blocker
hooks/scripts/post-edit-warn-inline-tests.js Add root artifact inline-test warning hook
hooks/scripts/post-edit-validate-test-spec.js Add root artifact post-edit spec validator hook
hooks/scripts/post-edit-suggest-testing.js Add root artifact doc-edit test reminder hook
hooks/scripts/post-edit-format-test-spec.js Add root artifact post-edit spec formatter hook
hooks/gemini-hooks.json Add root artifact Gemini hook config
hooks/claude-hooks.json Add root artifact Claude hook config
gemini-extension.json Add hooksFile reference and bump version to 1.3.0
build.js Add build sync step to copy hooks into artifacts/plugin and set executable bits
agents/doc-detective-specialist.md Bump artifact agent metadata version to 1.3.0
README.md Document hooks usage and add hooks directory to install steps
GEMINI.md Document hooks behavior in Gemini extension context
.husky/pre-commit Include hooks/ in pre-commit build artifacts to stage
.claude-plugin/marketplace.json Bump marketplace metadata version to 1.3.0
Comments suppressed due to low confidence (4)

src/hooks/scripts/session-start-check-install.sh:1

  • The session-start hook invokes timeout and npx. (1) timeout is not guaranteed to exist in all environments (e.g., macOS often lacks GNU timeout), which can produce noisy stderr or break the check; and (2) npx doc-detective --version may trigger a network fetch at session start, which is likely to create the “high-traffic” errors this PR aims to avoid. Prefer a no-network availability check (e.g., npx --no-install ... / npm exec --no -- ...) and guard timeout usage (or implement a portable timeout strategy) so the hook stays quiet and deterministic.
    src/hooks/scripts/pre-edit-block-action-antipattern.js:1
  • This blocker runs for common documentation extensions (e.g., .md) and will also match/abort when writing docs that describe the anti-pattern (like README snippets showing {"action":"goTo"} as an incorrect example). That makes legitimate documentation edits fail. To avoid false positives, narrow the check to actual test spec files (e.g., .json that looks like a Doc Detective spec) and/or only scan inline-test regions rather than the entire doc content.
    src/hooks/scripts/pre-edit-block-action-antipattern.js:1
  • This blocker runs for common documentation extensions (e.g., .md) and will also match/abort when writing docs that describe the anti-pattern (like README snippets showing {"action":"goTo"} as an incorrect example). That makes legitimate documentation edits fail. To avoid false positives, narrow the check to actual test spec files (e.g., .json that looks like a Doc Detective spec) and/or only scan inline-test regions rather than the entire doc content.
    src/hooks/scripts/post-edit-validate-test-spec.js:1
  • The hook ignores stderr and only reports failures when err.code === 1. If the validator crashes, times out, or can’t be executed, the hook becomes silent (no additionalContext) and loses the actionable error details. Consider surfacing unexpected errors (including stderr and timeout cases) in additionalContext so users can distinguish “invalid spec” from “validator failed to run.”

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
hooks/scripts/pre-edit-block-action-antipattern.js (1)

48-60: ⚠️ Potential issue | 🟠 Major

Same false-positive blocker risk as the mirrored plugin script.

This copy has the same over-broad extension gating and can block valid docs edits when anti-pattern text appears as documentation content.

🧹 Nitpick comments (2)
src/hooks/scripts/session-start-check-install.sh (1)

20-26: Double npx invocation adds unnecessary latency.

The version is fetched twice: once to check availability (line 21) and again to capture it (line 22). This doubles the wait time (up to 16s) on the npx path.

♻️ Suggested improvement
 # Check 2: npx
 if [ "$AVAILABLE" = "false" ] && command -v npx &>/dev/null; then
-  if timeout 8 npx doc-detective --version &>/dev/null 2>&1; then
-    VERSION=$(timeout 8 npx doc-detective --version 2>/dev/null || echo "unknown")
+  VERSION=$(timeout 8 npx doc-detective --version 2>/dev/null)
+  if [ $? -eq 0 ] && [ -n "$VERSION" ]; then
     STATUS="doc-detective available via npx (version: ${VERSION})"
     AVAILABLE="true"
   fi
 fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/scripts/session-start-check-install.sh` around lines 20 - 26,
Replace the double npx invocation with a single call that captures the output
and exit status: run timeout 8 npx doc-detective --version once, store its
stdout (or "unknown" on failure) into VERSION and check the command's exit code
to set AVAILABLE="true" and STATUS="doc-detective available via npx (version:
${VERSION})" only when the command succeeded; reference the existing variables
and constructs (AVAILABLE, VERSION, STATUS, timeout, npx doc-detective
--version) so you avoid calling npx twice and eliminate the extra latency.
plugins/doc-detective/hooks/scripts/session-start-check-install.sh (1)

20-26: Minor inefficiency: npx doc-detective --version runs twice.

The condition on line 21 runs the command to check success, then line 22 runs it again to capture the version. This doubles the 8-second potential wait time.

♻️ Suggested optimization to run npx once
 # Check 2: npx
 if [ "$AVAILABLE" = "false" ] && command -v npx &>/dev/null; then
-  if timeout 8 npx doc-detective --version &>/dev/null 2>&1; then
-    VERSION=$(timeout 8 npx doc-detective --version 2>/dev/null || echo "unknown")
+  VERSION=$(timeout 8 npx doc-detective --version 2>/dev/null)
+  if [ $? -eq 0 ] && [ -n "$VERSION" ]; then
     STATUS="doc-detective available via npx (version: ${VERSION})"
     AVAILABLE="true"
+  else
+    VERSION=""
   fi
 fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/doc-detective/hooks/scripts/session-start-check-install.sh` around
lines 20 - 26, Replace the two separate invocations of "timeout 8 npx
doc-detective --version" with a single invocation whose output and exit status
are captured once: run the command into a variable (e.g., capture output into a
temp variable), test that the command succeeded by checking its exit status or
non-empty output, then set VERSION from that captured output (falling back to
"unknown" if empty) and set STATUS and AVAILABLE accordingly; update the block
where AVAILABLE, VERSION, STATUS and the "npx doc-detective --version" calls
appear so the command is executed only once.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.husky/pre-commit:
- Line 2: The pre-commit hook currently stages generated hook outputs but omits
the source directory in the git add command; update the git add invocation (the
line containing "git add agents/ skills/ hooks/ commands/ plugins/doc-detective/
.claude-plugin/marketplace.json gemini-extension.json") to also stage the source
hooks directory (e.g., add src/hooks/ or src/hooks/**) so that source-of-truth
changes are committed alongside generated artifacts.

In `@plugins/doc-detective/hooks/scripts/pre-edit-block-action-antipattern.js`:
- Around line 48-60: The rule is too broad because it inspects text formats and
blocks legitimate docs that contain JSON-like examples; restrict the check so
ACTION_PATTERN matching only runs on actual Doc Detective data files (e.g., JSON
payloads) rather than Markdown/HTML/XML/AsciiDoc. Update the ext filter logic
(the ext variable and the conditional that currently uses DOC_EXTENSIONS) so
that only '.json' (or a narrow filename pattern used for Doc Detective data)
proceeds to extract content and run ACTION_PATTERN.match; do not run the match
on extensions in DOC_EXTENSIONS or other prose formats to avoid false positives
when matching content.

In `@src/hooks/scripts/post-edit-validate-test-spec.js`:
- Around line 62-74: The current handler only logs when err.code === 1 or no
err, silently swallowing timeouts/other failures from execFile; add an explicit
branch for any other err (e.g., timeout, ENOENT, signal termination) to emit a
JSON console.log with additionalContext containing the fileName, output and rich
error details (err.message, err.code, err.signal and/or err.killed) so users see
the failure; update the block around the existing if (err && err.code === 1) /
else if (!err) to include an else if (err) branch that logs these error details
before the existing process.exit(0) call.

In `@src/hooks/scripts/session-start-check-install.sh`:
- Around line 37-41: The JSON output currently interpolates $STATUS directly
which can break JSON if it contains quotes, backslashes, or newlines; replace
the vulnerable printf interpolation in the AVAILABLE=true branch by constructing
the JSON with a proper JSON-escaping tool (e.g., use jq: jq -n --arg status
"$STATUS" '{"additionalContext":("Doc Detective status: \($status). Tests can be
executed directly.")}') and write that to stdout, referencing the existing
AVAILABLE and STATUS variables and replacing the printf call; if jq may not be
available, sanitize/escape $STATUS before interpolation (escape backslashes,
double quotes and newlines) and then produce the JSON string to ensure valid
output.

---

Nitpick comments:
In `@plugins/doc-detective/hooks/scripts/session-start-check-install.sh`:
- Around line 20-26: Replace the two separate invocations of "timeout 8 npx
doc-detective --version" with a single invocation whose output and exit status
are captured once: run the command into a variable (e.g., capture output into a
temp variable), test that the command succeeded by checking its exit status or
non-empty output, then set VERSION from that captured output (falling back to
"unknown" if empty) and set STATUS and AVAILABLE accordingly; update the block
where AVAILABLE, VERSION, STATUS and the "npx doc-detective --version" calls
appear so the command is executed only once.

In `@src/hooks/scripts/session-start-check-install.sh`:
- Around line 20-26: Replace the double npx invocation with a single call that
captures the output and exit status: run timeout 8 npx doc-detective --version
once, store its stdout (or "unknown" on failure) into VERSION and check the
command's exit code to set AVAILABLE="true" and STATUS="doc-detective available
via npx (version: ${VERSION})" only when the command succeeded; reference the
existing variables and constructs (AVAILABLE, VERSION, STATUS, timeout, npx
doc-detective --version) so you avoid calling npx twice and eliminate the extra
latency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 70cfd563-5773-41c3-8276-458be49f1870

📥 Commits

Reviewing files that changed from the base of the PR and between a5258a3 and 16a81c4.

📒 Files selected for processing (61)
  • .claude-plugin/marketplace.json
  • .husky/pre-commit
  • GEMINI.md
  • README.md
  • agents/doc-detective-specialist.md
  • build.js
  • gemini-extension.json
  • hooks/claude-hooks.json
  • hooks/gemini-hooks.json
  • hooks/scripts/post-edit-format-test-spec.js
  • hooks/scripts/post-edit-suggest-testing.js
  • hooks/scripts/post-edit-validate-test-spec.js
  • hooks/scripts/post-edit-warn-inline-tests.js
  • hooks/scripts/pre-edit-block-action-antipattern.js
  • hooks/scripts/session-start-check-install.sh
  • package.json
  • plugins/doc-detective/.claude-plugin/plugin.json
  • plugins/doc-detective/agents/doc-detective-specialist.md
  • plugins/doc-detective/hooks/hooks.json
  • plugins/doc-detective/hooks/scripts/post-edit-format-test-spec.js
  • plugins/doc-detective/hooks/scripts/post-edit-suggest-testing.js
  • plugins/doc-detective/hooks/scripts/post-edit-validate-test-spec.js
  • plugins/doc-detective/hooks/scripts/post-edit-warn-inline-tests.js
  • plugins/doc-detective/hooks/scripts/pre-edit-block-action-antipattern.js
  • plugins/doc-detective/hooks/scripts/session-start-check-install.sh
  • plugins/doc-detective/skills/doc-detective-doc-testing/SKILL.md
  • plugins/doc-detective/skills/doc-detective-generate/SKILL.md
  • plugins/doc-detective/skills/doc-detective-init/SKILL.md
  • plugins/doc-detective/skills/doc-detective-inject/SKILL.md
  • plugins/doc-detective/skills/doc-detective-inline-test-injection/SKILL.md
  • plugins/doc-detective/skills/doc-detective-install-github-action/SKILL.md
  • plugins/doc-detective/skills/doc-detective-project-bootstrap/SKILL.md
  • plugins/doc-detective/skills/doc-detective-test/SKILL.md
  • plugins/doc-detective/skills/doc-detective-validate/SKILL.md
  • skills/doc-detective-doc-testing/SKILL.md
  • skills/doc-detective-generate/SKILL.md
  • skills/doc-detective-init/SKILL.md
  • skills/doc-detective-inject/SKILL.md
  • skills/doc-detective-inline-test-injection/SKILL.md
  • skills/doc-detective-install-github-action/SKILL.md
  • skills/doc-detective-project-bootstrap/SKILL.md
  • skills/doc-detective-test/SKILL.md
  • skills/doc-detective-validate/SKILL.md
  • src/agents/doc-detective-specialist.md
  • src/hooks/claude-hooks.json
  • src/hooks/gemini-hooks.json
  • src/hooks/scripts/post-edit-format-test-spec.js
  • src/hooks/scripts/post-edit-suggest-testing.js
  • src/hooks/scripts/post-edit-validate-test-spec.js
  • src/hooks/scripts/post-edit-warn-inline-tests.js
  • src/hooks/scripts/pre-edit-block-action-antipattern.js
  • src/hooks/scripts/session-start-check-install.sh
  • src/skills/doc-detective-doc-testing/SKILL.md
  • src/skills/doc-detective-generate/SKILL.md
  • src/skills/doc-detective-init/SKILL.md
  • src/skills/doc-detective-inject/SKILL.md
  • src/skills/doc-detective-inline-test-injection/SKILL.md
  • src/skills/doc-detective-install-github-action/SKILL.md
  • src/skills/doc-detective-project-bootstrap/SKILL.md
  • src/skills/doc-detective-test/SKILL.md
  • src/skills/doc-detective-validate/SKILL.md

- Stage src/hooks/ in pre-commit hook to prevent source/artifact drift
- Handle timeout and unexpected errors in post-edit-validate-test-spec.js
- Sanitize version string in session-start-check-install.sh to prevent JSON malformation
@hawkeyexl
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/hooks/scripts/post-edit-validate-test-spec.js (1)

62-78: Include stderr for richer validation failure details.

The validator script outputs detailed validation results (the JSON object with specific errors) to stderr, but the hook only captures and reports stdout. When validation fails, users miss the detailed information about why the spec is invalid.

♻️ Suggested improvement to include stderr in output
   execFile('node', [validatorPath, filePath], { timeout: 25000 }, (err, stdout, stderr) => {
     const fileName = path.basename(filePath);
     const output = (stdout || '').trim();
+    const errOutput = (stderr || '').trim();

     if (err && err.code === 1) {
       // Validation failed
       console.log(JSON.stringify({
-        additionalContext: `Doc Detective test spec validation FAILED for ${fileName}:\n${output}`
+        additionalContext: `Doc Detective test spec validation FAILED for ${fileName}:\n${output}${errOutput ? '\n' + errOutput : ''}`
       }));
     } else if (err) {
       // Timeout or unexpected error
       const reason = err.killed ? 'timed out' : err.message || 'unknown error';
       console.log(JSON.stringify({
-        additionalContext: `Doc Detective test spec validation could not complete for ${fileName}: ${reason}`
+        additionalContext: `Doc Detective test spec validation could not complete for ${fileName}: ${reason}${errOutput ? '\n' + errOutput : ''}`
       }));
     } else {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/scripts/post-edit-validate-test-spec.js` around lines 62 - 78, When
validation fails or errors (the branches checking err && err.code === 1 and the
else if (err) branch), include the validator's stderr along with stdout in the
logged additionalContext so users see the detailed JSON error payload; update
the console.log messages that reference output/fileName to also append or merge
a stderr variable (from the child process callback) and ensure both stderr and
output are presented (e.g., "stdout: ...; stderr: ...") for the failing
branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/hooks/scripts/post-edit-validate-test-spec.js`:
- Around line 62-78: When validation fails or errors (the branches checking err
&& err.code === 1 and the else if (err) branch), include the validator's stderr
along with stdout in the logged additionalContext so users see the detailed JSON
error payload; update the console.log messages that reference output/fileName to
also append or merge a stderr variable (from the child process callback) and
ensure both stderr and output are presented (e.g., "stdout: ...; stderr: ...")
for the failing branches.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1a39a00f-3936-49a9-bee9-0fe2f39ced6d

📥 Commits

Reviewing files that changed from the base of the PR and between 43d6495 and d9c6033.

📒 Files selected for processing (7)
  • .husky/pre-commit
  • hooks/scripts/post-edit-validate-test-spec.js
  • hooks/scripts/session-start-check-install.sh
  • plugins/doc-detective/hooks/scripts/post-edit-validate-test-spec.js
  • plugins/doc-detective/hooks/scripts/session-start-check-install.sh
  • src/hooks/scripts/post-edit-validate-test-spec.js
  • src/hooks/scripts/session-start-check-install.sh
✅ Files skipped from review due to trivial changes (1)
  • .husky/pre-commit
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/hooks/scripts/session-start-check-install.sh
  • plugins/doc-detective/hooks/scripts/post-edit-validate-test-spec.js
  • hooks/scripts/session-start-check-install.sh
  • hooks/scripts/post-edit-validate-test-spec.js
  • plugins/doc-detective/hooks/scripts/session-start-check-install.sh

@hawkeyexl
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
tests/hooks/hook1-validate-test-spec.test.js (1)

60-66: Use fully valid test-spec fixtures in the “valid spec” case.

At Line [62]-Line [65], add description to each test object so this fixture matches the canonical test-spec structure.

🧪 Fixture adjustment
     const spec = {
       tests: [{
         testId: 'test1',
+        description: 'basic navigation test',
         steps: [{ goTo: 'https://example.com' }, { find: 'Welcome' }],
       }],
     };

Based on learnings: Applies to **/*.json : Test specifications must follow the format with tests array containing objects with testId, description, and steps properties.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/hook1-validate-test-spec.test.js` around lines 60 - 66, The
fixture `spec` used in the test case currently has test objects missing the
required `description` field; update the `spec` object (the `tests` array and
its test object with `testId: 'test1'`) to include a `description` string for
each test so the fixture matches the canonical test-spec structure (each test
must have `testId`, `description`, and `steps`).
tests/hooks/integration.test.js (1)

97-114: Good workaround for Gemini's workspace restriction.

Creating temp directories inside the project root is necessary since Gemini CLI restricts writes to the workspace. One minor consideration: if tests fail before after() runs, .tmp-gemini-test-* directories could remain in the repo.

Consider adding these patterns to .gitignore to prevent accidental commits:

+# Gemini integration test artifacts
+.tmp-gemini-test-*
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/integration.test.js` around lines 97 - 114, Tests create
temporary dirs named by tmpDir using prefix ".tmp-gemini-test-" inside the
project (see the before/after hooks in the "Integration: Gemini CLI" describe
block and the tmpDir variable); add a gitignore entry for the pattern
".tmp-gemini-test-*" (and optionally ".tmp-gemini-test-*/") to the repository
.gitignore so leftover temp directories won't be committed if a test fails
before after() cleans them up.
tests/hooks/helpers.js (1)

12-35: Minor: code field can be a string for system errors.

When execFile encounters a system error (e.g., timeout), err.code is a string like 'ETIMEDOUT' rather than a numeric exit code. The current logic would return that string as the code value, which could cause unexpected comparisons if callers assume it's always a number.

For test helper code this is acceptable—callers can check both string and numeric codes as needed. Consider adding a brief JSDoc note if type consistency matters for future maintainers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/helpers.js` around lines 12 - 35, The runHook helper currently
returns err.code directly which can be a string for system errors; update the
execFile callback in runHook to normalize the exit code: set the returned code
to the numeric exit code when typeof err.code === 'number' (or 0 when no err),
otherwise default to 1 for non-numeric/system errors, and preserve the original
err.code/string on a new property (e.g., errCode) alongside stderr/stdout so
callers can still inspect the string error like 'ETIMEDOUT'; adjust the resolved
object shape accordingly and update any callers/tests or add a short JSDoc on
runHook describing the normalized code and the errCode field.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@build.js`:
- Around line 381-406: The build silently continues when expected provider hook
manifests (claude-hooks.json / gemini-hooks.json) are absent, leaving hooks.json
missing; update the renaming logic around rootClaude/rootHooksDest and
pluginClaude/pluginHooksDest so the build fails fast: before attempting to
rename, assert the source file exists and if not, throw an error or call
process.exit(1) with a clear message referencing the missing manifest (e.g.,
"Missing claude-hooks.json in hooks dir"); do the same for the plugin copy case
(pluginClaude -> pluginHooksDest) and for any other expected provider files
(rootGemini/pluginGemini) so the build exits immediately rather than silently
producing broken artifacts.

In `@tests/hooks/hook1-validate-test-spec.test.js`:
- Around line 75-84: The test currently treats any non-null
parseOutput(result.stdout) as OK and can false-pass on malformed JSON; change
the check to explicitly assert that result.stdout is either empty (silent exit)
or valid JSON parsed by parseOutput. Concretely, update the conditional around
parseOutput/result.stdout so you first assert that result.stdout.trim() === ''
|| output, e.g. if result.stdout is non-empty assert output is truthy (meaning
parseOutput succeeded) and then assert output.additionalContext includes
'spec.json'; reference parseOutput(result.stdout), result.stdout and
output.additionalContext when making the change.

---

Nitpick comments:
In `@tests/hooks/helpers.js`:
- Around line 12-35: The runHook helper currently returns err.code directly
which can be a string for system errors; update the execFile callback in runHook
to normalize the exit code: set the returned code to the numeric exit code when
typeof err.code === 'number' (or 0 when no err), otherwise default to 1 for
non-numeric/system errors, and preserve the original err.code/string on a new
property (e.g., errCode) alongside stderr/stdout so callers can still inspect
the string error like 'ETIMEDOUT'; adjust the resolved object shape accordingly
and update any callers/tests or add a short JSDoc on runHook describing the
normalized code and the errCode field.

In `@tests/hooks/hook1-validate-test-spec.test.js`:
- Around line 60-66: The fixture `spec` used in the test case currently has test
objects missing the required `description` field; update the `spec` object (the
`tests` array and its test object with `testId: 'test1'`) to include a
`description` string for each test so the fixture matches the canonical
test-spec structure (each test must have `testId`, `description`, and `steps`).

In `@tests/hooks/integration.test.js`:
- Around line 97-114: Tests create temporary dirs named by tmpDir using prefix
".tmp-gemini-test-" inside the project (see the before/after hooks in the
"Integration: Gemini CLI" describe block and the tmpDir variable); add a
gitignore entry for the pattern ".tmp-gemini-test-*" (and optionally
".tmp-gemini-test-*/") to the repository .gitignore so leftover temp directories
won't be committed if a test fails before after() cleans them up.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: be452961-62a3-4f1f-935d-9d2ef59fe804

📥 Commits

Reviewing files that changed from the base of the PR and between 6865771 and 73a4c8c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (18)
  • build.js
  • gemini-extension.json
  • gemini-hook-test.json
  • hooks/hooks.json
  • package.json
  • plugins/doc-detective/skills/doc-detective-doc-testing/scripts/doc-detective-validate-test.js
  • skills/doc-detective-doc-testing/scripts/doc-detective-validate-test.js
  • src/hooks/gemini-hooks.json
  • src/skills/doc-detective-doc-testing/scripts/doc-detective-validate-test.js
  • test-hook.md
  • tests/hooks/helpers.js
  • tests/hooks/hook1-validate-test-spec.test.js
  • tests/hooks/hook2-block-action-antipattern.test.js
  • tests/hooks/hook3-suggest-testing.test.js
  • tests/hooks/hook4-session-start-check-install.test.js
  • tests/hooks/hook5-format-test-spec.test.js
  • tests/hooks/hook6-warn-inline-tests.test.js
  • tests/hooks/integration.test.js
✅ Files skipped from review due to trivial changes (4)
  • gemini-hook-test.json
  • gemini-extension.json
  • src/hooks/gemini-hooks.json
  • test-hook.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

…en test assertion

- build.js: throw error instead of silently continuing when claude-hooks.json
  or gemini-hooks.json are missing from the hooks output directory
- hook1 test: assert stdout is either empty or valid JSON, preventing false
  passes on malformed output
- session-start-check-install.sh: use npx --yes to suppress install prompts,
  pipe through tail -1 to ignore progress output that contaminates stdout
- hook4 test: increase timeout to 30s for slow CI npx, add stdout diagnostic
  to assertion message for easier debugging
@hawkeyexl
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/hooks/hook2-block-action-antipattern.test.js (1)

67-72: Avoid another hard-coded copy of the action list.

The same action set already exists in src/hooks/scripts/pre-edit-block-action-antipattern.js. Keeping a separate copy here makes future action additions easy to miss in either the hook or the test. Consider sharing one exported constant instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/hook2-block-action-antipattern.test.js` around lines 67 - 72, The
test duplicates the action list that's already defined in
pre-edit-block-action-antipattern.js; refactor by exposing the single source of
truth from that module (create/export a constant like ACTION_NAMES or
KNOWN_ACTIONS in pre-edit-block-action-antipattern.js if it doesn't exist) and
update the test to import and use that exported constant instead of the
hard-coded array in the it('should detect all known action names', ...) block;
ensure the exported symbol name you choose matches the import in the test and
keep the array content unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@build.js`:
- Around line 369-371: The check that currently returns when srcHooksDir is
missing should instead fail the build: inside the same function where
srcHooksDir is checked (after cleanOutputDirs() runs) replace the early return
with throwing an Error that includes the missing path (srcHooksDir) and a clear
message so the build fails fast; ensure callers of this routine will surface the
thrown error rather than treating it as success.

In `@tests/hooks/integration.test.js`:
- Around line 60-69: The test 'should report Doc Detective CLI availability via
Hook 4' currently only checks for a forced YES/NO and can pass without the
session-start hook; update the assertion to verify a deterministic marker that
Hook 4 injects at session start (e.g., a specific string like the hook payload's
marker) rather than relying on result.stdout including 'YES' or 'NO'. Locate the
test case using the test title and the runClaude call, and replace or augment
the assert.ok that checks result.stdout with an assertion that
result.stdout.includes('<HOOK4_SESSION_MARKER>') (or the actual marker string
the hook sends). Apply the same change to the parallel test at lines 153-164 so
both tests verify the hook-injected marker instead of only the constrained
YES/NO response.
- Around line 83-93: The current assertion in tests/hooks/integration.test.js
uses broad substring checks on result.stdout which can false-positive; update
the assertion that follows runClaude to assert that result.stdout (or combined
stdout+stderr) includes the exact hook warning text emitted by the hook (e.g.,
the literal "contains inline Doc Detective test comments" from
src/hooks/scripts/post-edit-warn-inline-tests.js) or another stable sentinel
string produced by Hook 6, and remove the fallback to generic
toLowerCase('warn'|'inline') checks; apply the same replacement for the other
occurrence of this assertion in the file (the block at the later test around
lines 177-192) so both tests verify the hook's specific warning message rather
than broad keywords.

---

Nitpick comments:
In `@tests/hooks/hook2-block-action-antipattern.test.js`:
- Around line 67-72: The test duplicates the action list that's already defined
in pre-edit-block-action-antipattern.js; refactor by exposing the single source
of truth from that module (create/export a constant like ACTION_NAMES or
KNOWN_ACTIONS in pre-edit-block-action-antipattern.js if it doesn't exist) and
update the test to import and use that exported constant instead of the
hard-coded array in the it('should detect all known action names', ...) block;
ensure the exported symbol name you choose matches the import in the test and
keep the array content unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5732e8cb-5a6d-4bd4-99ec-35b713b85a54

📥 Commits

Reviewing files that changed from the base of the PR and between 6865771 and d589040.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (22)
  • .github/workflows/test-hooks.yml
  • build.js
  • gemini-extension.json
  • gemini-hook-test.json
  • hooks/hooks.json
  • hooks/scripts/session-start-check-install.sh
  • package.json
  • plugins/doc-detective/hooks/scripts/session-start-check-install.sh
  • plugins/doc-detective/skills/doc-detective-doc-testing/scripts/doc-detective-validate-test.js
  • skills/doc-detective-doc-testing/scripts/doc-detective-validate-test.js
  • src/hooks/gemini-hooks.json
  • src/hooks/scripts/session-start-check-install.sh
  • src/skills/doc-detective-doc-testing/scripts/doc-detective-validate-test.js
  • test-hook.md
  • tests/hooks/helpers.js
  • tests/hooks/hook1-validate-test-spec.test.js
  • tests/hooks/hook2-block-action-antipattern.test.js
  • tests/hooks/hook3-suggest-testing.test.js
  • tests/hooks/hook4-session-start-check-install.test.js
  • tests/hooks/hook5-format-test-spec.test.js
  • tests/hooks/hook6-warn-inline-tests.test.js
  • tests/hooks/integration.test.js
✅ Files skipped from review due to trivial changes (8)
  • package.json
  • gemini-extension.json
  • test-hook.md
  • .github/workflows/test-hooks.yml
  • src/hooks/gemini-hooks.json
  • hooks/hooks.json
  • tests/hooks/hook5-format-test-spec.test.js
  • tests/hooks/helpers.js
🚧 Files skipped from review as they are similar to previous changes (7)
  • gemini-hook-test.json
  • src/hooks/scripts/session-start-check-install.sh
  • hooks/scripts/session-start-check-install.sh
  • tests/hooks/hook1-validate-test-spec.test.js
  • plugins/doc-detective/hooks/scripts/session-start-check-install.sh
  • tests/hooks/hook4-session-start-check-install.test.js
  • tests/hooks/hook3-suggest-testing.test.js

…st assertions

- build.js: Throw error instead of silently returning when src/hooks/ is missing
- integration tests: Check for hook marker text in SessionStart assertions
- integration tests: Check for exact hook warning text in inline-test assertions
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
tests/hooks/integration.test.js (2)

65-70: ⚠️ Potential issue | 🟠 Major

Make SessionStart assertions hook-specific (remove YES/NO fallback).

Line 69 and Line 170 let this test pass from prompt-constrained model output even when the SessionStart hook context is absent.

Suggested diff
-    assert.ok(
-      combined.includes('Doc Detective status:') || combined.includes('Doc Detective CLI is not installed') ||
-      result.stdout.includes('YES') || result.stdout.includes('NO'),
-      `Expected hook marker or YES/NO. Got: ${result.stdout.slice(0, 200)}`
-    );
+    assert.ok(
+      combined.includes('Doc Detective status:') || combined.includes('Doc Detective CLI is not installed'),
+      `Expected SessionStart hook marker. Got: ${(result.stdout + result.stderr).slice(0, 200)}`
+    );

Also applies to: 167-170

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/integration.test.js` around lines 65 - 70, The current assertion
in the test uses a fallback on result.stdout including 'YES'/'NO', which lets
prompt-constrained model output pass even when the SessionStart hook context is
missing; update the assertions in the test (the assertion that constructs
combined from result.stdout + result.stderr and the duplicate at the later
location) to only assert for the hook-specific markers (e.g.,
combined.includes('Doc Detective status:') || combined.includes('Doc Detective
CLI is not installed')) and remove the
result.stdout.includes('YES')/includes('NO') alternatives so the test fails when
the SessionStart hook marker is absent.

95-97: ⚠️ Potential issue | 🟠 Major

Use only the hook’s warning marker in inline-warning assertions.

Line 96 and Line 198 still allow prompt-driven/generic “warn” matches, so these tests can pass without Hook 6 / AfterTool output.

Suggested diff
-    assert.ok(
-      combined.includes('contains inline Doc Detective test comments') ||
-      result.stdout.includes('WARNED') || result.stdout.toLowerCase().includes('warn'),
-      `Expected hook warning about inline tests. Got: ${result.stdout.slice(0, 300)}`
-    );
+    assert.ok(
+      combined.includes('contains inline Doc Detective test comments'),
+      `Expected inline-test hook warning marker. Got: ${(result.stdout + result.stderr).slice(0, 300)}`
+    );
-    assert.ok(
-      combined.includes('contains inline Doc Detective test comments') ||
-      combined.includes('WARNED') || combined.toLowerCase().includes('warn'),
-      `Expected hook warning about inline tests. Got stdout: ${result.stdout.slice(0, 200)}`
-    );
+    assert.ok(
+      combined.includes('contains inline Doc Detective test comments'),
+      `Expected inline-test hook warning marker. Got: ${(result.stdout + result.stderr).slice(0, 200)}`
+    );

Also applies to: 197-199

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/integration.test.js` around lines 95 - 97, The assertion is too
permissive because it allows generic "WARNED" or any "warn" substrings; update
the check around combined and result.stdout so it only looks for the Hook
6/AfterTool specific warning marker (the exact string used by the hook, e.g.
"contains inline Doc Detective test comments") instead of
result.stdout.includes('WARNED') or
result.stdout.toLowerCase().includes('warn'). Concretely, modify the assertion
that references combined and result.stdout to remove the generic checks and only
use combined.includes('contains inline Doc Detective test comments') ||
result.stdout.includes('contains inline Doc Detective test comments') (or the
exact AfterTool marker string your hook emits) so the test only passes when the
hook's warning is present.
🧹 Nitpick comments (1)
tests/hooks/integration.test.js (1)

164-164: Harden auth/rate-limit skip detection to reduce flaky failures.

These checks are case-sensitive and stdout-only; auth/rate-limit messages can surface in stderr or with different casing.

Suggested diff
-    if (!result.stdout.trim() || result.stdout.includes('authentication')) this.skip();
+    const output = `${result.stdout}\n${result.stderr}`.toLowerCase();
+    if (!result.stdout.trim() || output.includes('authentication')) this.skip();
-    if (!result.stdout.trim() || result.stdout.includes('authentication')) this.skip();
+    const output = `${result.stdout}\n${result.stderr}`.toLowerCase();
+    if (!result.stdout.trim() || output.includes('authentication')) this.skip();

Also applies to: 192-192

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/hooks/integration.test.js` at line 164, The flaky skip logic only
checks result.stdout case-sensitively; update the checks around the test result
(the variable result used at the skip points) to inspect both result.stdout and
result.stderr and perform case-insensitive matching (e.g., normalize to
lower-case) for keywords like "authentication" and "rate-limit" so skips fire
reliably regardless of casing or stream; replace the two existing lines that
call this.skip() based on result.stdout with a shared predicate that
concatenates or checks both streams in lower-case before deciding to
this.skip().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/hooks/integration.test.js`:
- Around line 65-70: The current assertion in the test uses a fallback on
result.stdout including 'YES'/'NO', which lets prompt-constrained model output
pass even when the SessionStart hook context is missing; update the assertions
in the test (the assertion that constructs combined from result.stdout +
result.stderr and the duplicate at the later location) to only assert for the
hook-specific markers (e.g., combined.includes('Doc Detective status:') ||
combined.includes('Doc Detective CLI is not installed')) and remove the
result.stdout.includes('YES')/includes('NO') alternatives so the test fails when
the SessionStart hook marker is absent.
- Around line 95-97: The assertion is too permissive because it allows generic
"WARNED" or any "warn" substrings; update the check around combined and
result.stdout so it only looks for the Hook 6/AfterTool specific warning marker
(the exact string used by the hook, e.g. "contains inline Doc Detective test
comments") instead of result.stdout.includes('WARNED') or
result.stdout.toLowerCase().includes('warn'). Concretely, modify the assertion
that references combined and result.stdout to remove the generic checks and only
use combined.includes('contains inline Doc Detective test comments') ||
result.stdout.includes('contains inline Doc Detective test comments') (or the
exact AfterTool marker string your hook emits) so the test only passes when the
hook's warning is present.

---

Nitpick comments:
In `@tests/hooks/integration.test.js`:
- Line 164: The flaky skip logic only checks result.stdout case-sensitively;
update the checks around the test result (the variable result used at the skip
points) to inspect both result.stdout and result.stderr and perform
case-insensitive matching (e.g., normalize to lower-case) for keywords like
"authentication" and "rate-limit" so skips fire reliably regardless of casing or
stream; replace the two existing lines that call this.skip() based on
result.stdout with a shared predicate that concatenates or checks both streams
in lower-case before deciding to this.skip().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1a5e871f-c01f-4666-ad66-9e88cac5cefc

📥 Commits

Reviewing files that changed from the base of the PR and between d589040 and f971a47.

📒 Files selected for processing (2)
  • build.js
  • tests/hooks/integration.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • build.js

@hawkeyexl
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hawkeyexl
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hawkeyexl hawkeyexl merged commit 114c196 into main Mar 29, 2026
3 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.

2 participants