Skip to content

Commit dee1f9f

Browse files
Ashish-dwi99claude
andcommitted
v3.3.0: Native Claude Code hooks — self-evolving sessions without markdown
Add dhee/hooks/claude_code/ — 6 lifecycle hooks that make every Claude Code session learn from its own execution. No CLAUDE.md bloat, no SKILL.md files, no static routing tables. Vector memory with decay + token-budgeted XML context injection (~630 tokens for rich context, constant regardless of memory volume). Hooks: SessionStart (context injection), UserPromptSubmit (per-turn memories), PostToolUse (outcome capture with privacy filter), PreCompact (state survival), Stop/SessionEnd (checkpoint with learnings). CLI: `dhee task "..."` starts Claude Code with hooks pre-configured. `dhee install` / `dhee uninstall-hooks` for manual hook management. 42 tests covering renderer, privacy filter, installer, dispatch handlers. 878 existing tests unaffected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c2b38bb commit dee1f9f

11 files changed

Lines changed: 1274 additions & 3 deletions

File tree

README.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,42 @@ d.context("fixing auth bug")
7878
d.checkpoint("Fixed it", what_worked="git blame first")
7979
```
8080

81+
### Claude Code — Native Hooks (v3.3.0)
82+
83+
One command. Every Claude Code session becomes self-evolving.
84+
85+
```bash
86+
dhee install
87+
```
88+
89+
That's it. Dhee hooks into Claude Code's lifecycle — no CLAUDE.md bloat, no SKILL.md files, no markdown accumulation. Structured XML context injection, budgeted to ~630 tokens regardless of how much memory you have.
90+
91+
**What happens automatically:**
92+
93+
| Hook | When | What Dhee does |
94+
|:-----|:-----|:---------------|
95+
| `SessionStart` | Session opens | Injects last session, insights, performance trends, relevant memories |
96+
| `UserPromptSubmit` | Every prompt | Surfaces memories relevant to what you just asked |
97+
| `PostToolUse` | After Edit/Write/Bash | Captures what Claude did (secrets auto-stripped) |
98+
| `PreCompact` | Before context compaction | Checkpoints state so nothing is lost |
99+
| `Stop` | Session ends | Records outcomes — what worked, what failed, learnings |
100+
101+
Or start Claude Code directly with context:
102+
103+
```bash
104+
dhee task "fix the flaky auth test"
105+
```
106+
107+
**Why not CLAUDE.md?** Markdown files are static. After 6 months of accumulated knowledge, they rot — stale patterns sit at equal weight to current ones, no retrieval ranking, no forgetting. Dhee uses vector memory with strength-based decay. Relevant memories surface. Irrelevant ones fade. The context budget stays constant at ~630 tokens whether you have 50 memories or 50,000.
108+
81109
### CLI
82110

83111
```bash
84112
dhee remember "User prefers Python"
85113
dhee recall "programming language"
86114
dhee checkpoint "Fixed auth bug" --what-worked "checked logs"
115+
dhee install # install Claude Code hooks
116+
dhee uninstall-hooks # remove them
87117
```
88118

89119
### Docker
@@ -219,8 +249,18 @@ These are surfaced through `context()` and `checkpoint()` automatically when ena
219249
## Architecture
220250

221251
```
222-
Agent (Claude, GPT, Cursor, custom)
252+
Claude Code (or any agent)
223253
254+
├── SessionStart hook ──→ dhee.context() ──→ XML renderer ──→ system prompt injection
255+
├── UserPromptSubmit ───→ dhee.recall() ──→ ranked memories ──→ per-turn context
256+
├── PostToolUse ────────→ dhee.remember() ─→ privacy filter ──→ stored (0 LLM)
257+
├── PreCompact ─────────→ dhee.checkpoint() + re-inject context
258+
└── Stop ───────────────→ dhee.checkpoint(what_worked, what_failed, outcome_score)
259+
```
260+
261+
The 4-operation API under the hooks:
262+
263+
```
224264
├── remember(content) → Engram: embed + store (0 LLM)
225265
├── recall(query) → Engram: embed + vector search (0 LLM)
226266
├── context(task) → Buddhi: performance + insights + intentions + memories

dhee/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# Default: CoreMemory (lightest, zero-config)
3333
Memory = CoreMemory
3434

35-
__version__ = "3.2.0"
35+
__version__ = "3.3.0"
3636
__all__ = [
3737
# Memory classes
3838
"Engram",

dhee/cli.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,58 @@ def cmd_uninstall(args: argparse.Namespace) -> None:
318318
print("Cancelled.")
319319

320320

321+
def cmd_task(args: argparse.Namespace) -> None:
322+
"""Start Claude Code with Dhee cognition hooks."""
323+
from dhee.hooks.claude_code.install import ensure_installed
324+
325+
result = ensure_installed()
326+
if result.already_installed:
327+
pass # hooks already in place
328+
elif result.created or result.updated:
329+
print(f" Dhee hooks installed → {result.settings_path}")
330+
331+
# Find claude executable
332+
claude_bin = shutil.which("claude")
333+
if not claude_bin:
334+
print("Error: 'claude' not found in PATH. Install Claude Code first.", file=sys.stderr)
335+
sys.exit(1)
336+
337+
# Build command
338+
cmd = [claude_bin]
339+
if args.print_mode:
340+
cmd.append("--print")
341+
if args.description:
342+
cmd.append(args.description)
343+
344+
# Replace current process with claude
345+
os.execvp(claude_bin, cmd)
346+
347+
348+
def cmd_install_hooks(args: argparse.Namespace) -> None:
349+
"""Install Dhee hooks into Claude Code."""
350+
from dhee.hooks.claude_code.install import install_hooks
351+
352+
result = install_hooks(force=args.force)
353+
if result.already_installed and not args.force:
354+
print(" Dhee hooks already installed.")
355+
else:
356+
action = "Created" if result.created else "Updated"
357+
print(f" {action} {result.settings_path}")
358+
print(f" Hooks: {', '.join(result.events)}")
359+
if result.backed_up:
360+
print(f" Backup: {result.backed_up}")
361+
362+
363+
def cmd_uninstall_hooks(args: argparse.Namespace) -> None:
364+
"""Remove Dhee hooks from Claude Code."""
365+
from dhee.hooks.claude_code.install import uninstall_hooks
366+
367+
if uninstall_hooks():
368+
print(" Dhee hooks removed.")
369+
else:
370+
print(" No Dhee hooks found.")
371+
372+
321373
def cmd_benchmark(args: argparse.Namespace) -> None:
322374
"""Run performance benchmarks."""
323375
import time
@@ -458,6 +510,19 @@ def build_parser() -> argparse.ArgumentParser:
458510
p_status = sub.add_parser("status", help="Show version, config, and agents")
459511
p_status.add_argument("--json", action="store_true", help="JSON output")
460512

513+
# task
514+
p_task = sub.add_parser("task", help="Start Claude Code with Dhee cognition")
515+
p_task.add_argument("description", nargs="?", default="", help="Task description")
516+
p_task.add_argument("--user-id", default="default", help="User ID")
517+
p_task.add_argument("--print", dest="print_mode", action="store_true", help="One-shot mode")
518+
519+
# install (hooks)
520+
p_install = sub.add_parser("install", help="Install Dhee hooks into Claude Code")
521+
p_install.add_argument("--force", action="store_true", help="Overwrite existing hooks")
522+
523+
# uninstall-hooks
524+
sub.add_parser("uninstall-hooks", help="Remove Dhee hooks from Claude Code")
525+
461526
# benchmark
462527
sub.add_parser("benchmark", help="Run performance benchmarks")
463528

@@ -481,6 +546,9 @@ def build_parser() -> argparse.ArgumentParser:
481546
"export": cmd_export,
482547
"import": cmd_import,
483548
"status": cmd_status,
549+
"task": cmd_task,
550+
"install": cmd_install_hooks,
551+
"uninstall-hooks": cmd_uninstall_hooks,
484552
"benchmark": cmd_benchmark,
485553
"uninstall": cmd_uninstall,
486554
}

dhee/hooks/__init__.py

Whitespace-only changes.

dhee/hooks/claude_code/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from dhee.hooks.claude_code.install import ensure_installed, install_hooks, uninstall_hooks
2+
from dhee.hooks.claude_code.renderer import estimate_tokens, render_context

0 commit comments

Comments
 (0)