Skip to content

feat: bundle handoff-watchdog Claude Code hooks as SDK installer assets (#135)#158

Merged
Gradata merged 1 commit intomainfrom
feat/bundle-handoff-watchdog-installer
May 1, 2026
Merged

feat: bundle handoff-watchdog Claude Code hooks as SDK installer assets (#135)#158
Gradata merged 1 commit intomainfrom
feat/bundle-handoff-watchdog-installer

Conversation

@Gradata
Copy link
Copy Markdown
Owner

@Gradata Gradata commented May 1, 2026

Closes #135.

Bundles handoff-watchdog.js + handoff-inject.js under src/gradata/hooks/assets/claude_code/{user-prompt,session-start}/.

Changes

  • New install_js_hooks(project_dir) in _installer.py (idempotent, byte-compare diff before write, preserves +x bit)
  • New JS_HOOK_REGISTRY (js_asset variant) at STANDARD profile tier
  • CLI flags: gradata hooks install --project-dir <path> --include-watchdog
  • pyproject.toml package-data + hatch artifacts entries so JS ships in the wheel
  • Self-contained JS hooks: BRAIN_DIR resolved from env vars + ~/.gradata/brain fallback (no require chain)

Tests

  • 7 new tests in test_handoff_js_installer.py — all pass:
    • bundle present, copy correctness, idempotency, drift overwrite, settings registration with/without project_dir, real-node integration
  • Full suite: 4118 passed (+1 fixed flake in fix(test): de-flake test_doctor_runs_on_brain #157)

Bonus

  • Added MagicMock/ to .gitignore (pytest test-artifact pollution from string-cast MagicMock paths)

…135)

Closes #135. Bundles handoff-watchdog.js + handoff-inject.js under src/gradata/hooks/assets/claude_code/. Adds install_js_hooks() + JS_HOOK_REGISTRY at STANDARD profile, --include-watchdog CLI flag, package-data wiring. 7 new unit+integration tests pass; full suite 4118 passed, 1 known flake (now fixed in #157).
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 394c2dcc-6827-4704-916f-c4db55801500

📥 Commits

Reviewing files that changed from the base of the PR and between 23a4857 and c484b65.

📒 Files selected for processing (8)
  • Gradata/.gitignore
  • Gradata/pyproject.toml
  • Gradata/src/gradata/cli.py
  • Gradata/src/gradata/hooks/_installer.py
  • Gradata/src/gradata/hooks/assets/claude_code/session-start/handoff-inject.js
  • Gradata/src/gradata/hooks/assets/claude_code/user-prompt/handoff-watchdog.js
  • Gradata/src/gradata/hooks/claude_code.py
  • Gradata/tests/test_handoff_js_installer.py

📝 Walkthrough

Summary

  • Bundle Claude Code JS hooks: Adds handoff-watchdog.js and handoff-inject.js under src/gradata/hooks/assets/claude_code/ with package data configuration in pyproject.toml to include JS assets in distributions
  • New installer function: install_js_hooks(project_dir) idempotently copies bundled JS hooks into project's .claude/hooks/ subdirectories, preserving executable permissions and using byte-comparison for drift detection
  • CLI enhancements: gradata hooks install now accepts --project-dir and --include-watchdog flags to enable JS hook installation; defaults to current directory if --include-watchdog is specified without explicit path
  • JS hook registry: Hooks registered in settings as command-type entries that invoke Node.js scripts; supports profile-tier filtering with optional override via include_watchdog
  • Self-contained JS assets: Both hooks resolve BRAIN_DIR from environment variables with ~/.gradata/brain fallback; watchdog monitors context usage and injects handoff directives when threshold exceeded; session-start hook injects prior-session handoff context
  • API changes (breaking):
    • generate_settings(profile: str, project_dir: Path | None = None)
    • install(profile: str, project_dir: Path | None = None, include_watchdog: bool = False)
    • install_hook(profile: str, project_dir=None, include_watchdog: bool = False)
    • New public function: install_js_hooks(project_dir: Path) -> Path
  • Comprehensive test coverage: 7 new tests validate asset bundling, idempotent copying, drift correction, settings registration with/without project_dir, and real Node.js integration with environment variable handling
  • Full test suite passes: 4118 tests passed (+1 fixed flake)
  • Minor: Added MagicMock/ to .gitignore to prevent pytest artifact pollution

Closes #135.

Walkthrough

The changes bundle Claude Code JS hook assets (handoff-watchdog.js and handoff-inject.js) into the gradata package, extend the installer to copy these assets into a target project's .claude/hooks/ directory and register them in settings.json, add CLI flags for project directory and watchdog inclusion, and provide comprehensive tests for the installation flow.

Changes

Cohort / File(s) Summary
Package Configuration
Gradata/.gitignore, Gradata/pyproject.toml
Extended .gitignore to exclude MagicMock/ test artifacts; added setuptools package-data and Hatch artifact declarations to include src/gradata/hooks/assets/**/*.js in distributions.
CLI Arguments
Gradata/src/gradata/cli.py
Added --project-dir and --include-watchdog flags to gradata hooks install command; CLI now computes and forwards project directory to installer, defaulting to cwd when watchdog is requested.
Installer Core
Gradata/src/gradata/hooks/_installer.py
Extended generate_settings() and install() signatures to accept project_dir and include_watchdog parameters; added install_js_hooks(project_dir) function to copy bundled JS assets with idempotent, permission-preserving logic; JS hooks registered as command-type entries in settings when project_dir is provided.
Hook Module Wrapper
Gradata/src/gradata/hooks/claude_code.py
Updated install_hook() signature to accept project_dir and include_watchdog; forwards parameters to installer.
JS Hook Assets
Gradata/src/gradata/hooks/assets/claude_code/session-start/handoff-inject.js, Gradata/src/gradata/hooks/assets/claude_code/user-prompt/handoff-watchdog.js
New hook scripts: handoff-inject reads latest unconsumed handoff, formats as XML block, outputs JSON; handoff-watchdog monitors context pressure via bridge file, emits directive when threshold exceeded, with retry logic until handoff consumed.
Test Suite
Gradata/tests/test_handoff_js_installer.py
Comprehensive tests validating packaged asset existence, install_js_hooks() copy behavior with idempotency and drift correction, generate_settings() hook registration, and integration test simulating context-pressure scenario with bridge file and env vars.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as CLI (gradata hooks install)
    participant Installer as _installer.py
    participant FSys as File System
    participant Settings as settings.json
    participant CodeHook as Claude Code Hooks

    User->>CLI: gradata hooks install --include-watchdog --project-dir /path/to/project
    CLI->>Installer: install_hook(project_dir="/path/to/project", include_watchdog=True)
    Installer->>Installer: generate_settings(project_dir="/path/to/project", include_watchdog=True)
    Installer->>Installer: install_js_hooks(project_dir="/path/to/project")
    Installer->>FSys: copy handoff-watchdog.js to .claude/hooks/user-prompt/
    Installer->>FSys: copy handoff-inject.js to .claude/hooks/session-start/
    Installer->>Settings: register JS hooks in ~/.claude/settings.json
    Settings->>CodeHook: Claude Code loads hook entries (UserPromptSubmit, SessionStart)
    CodeHook->>User: Watchdog monitors & injects handoff on context pressure
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

feature

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bundle-handoff-watchdog-installer

Review rate limit: 3/5 reviews remaining, refill in 19 minutes and 6 seconds.

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

@Gradata Gradata merged commit 99c477e into main May 1, 2026
8 of 9 checks passed
@Gradata Gradata deleted the feat/bundle-handoff-watchdog-installer branch May 1, 2026 18:06
@coderabbitai coderabbitai Bot added the feature label May 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: bundle handoff-watchdog Claude Code hooks as SDK installer assets

1 participant