Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Dependencies
node_modules/
.pnpm-store/

# Build output
dist/
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ Auto-detects your dev server, captures viewport-height JPEG sections of every ro

Ask Claude to help you pick a UI framework. OpenWolf ships a curated knowledge base of 12 frameworks (shadcn/ui, Aceternity, Magic UI, DaisyUI, HeroUI, Chakra, Flowbite, Preline, Park UI, Origin UI, Headless UI, Cult UI) with battle-tested migration prompts. Claude reads `.wolf/reframe-frameworks.md`, asks you a few questions, and executes the migration with the right prompt for your project.

## Git Worktrees

OpenWolf supports git worktrees natively. Tools like [Conductor](https://conductor.app) run multiple Claude agents in parallel worktrees -- OpenWolf automatically shares brain files (cerebrum, buglog, token ledger) across all worktrees via the main repo's `.wolf/`, while keeping session-specific files local. No configuration needed -- `openwolf init` detects worktrees automatically.

## How OpenWolf Compares

OpenWolf is not an AI wrapper. It is 6 hook scripts and a `.wolf/` directory. It doesn't run your AI for you or change your workflow. It gives Claude Code what it lacks: a project map so it reads less, a memory so it learns faster, and a ledger so you see where tokens go.
Expand Down
23 changes: 23 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,29 @@ OpenWolf ships a knowledge file (`.wolf/reframe-frameworks.md`) that Claude read

There is no CLI command for reframe. It works through Claude's normal conversation flow.

## Git Worktrees and Conductor

OpenWolf supports git worktrees natively. If you use tools like [Conductor](https://conductor.app) that run multiple Claude agents in parallel worktrees, the brain (cerebrum, buglog, token ledger) is automatically shared across all worktrees via the main repo's `.wolf/` directory.

```bash
# In a worktree, init detects the setup automatically
cd /path/to/worktree
openwolf init
```

You'll see:

```
Worktree detected — shared brain at: /path/to/main-repo/.wolf
✓ OpenWolf initialized
✓ Worktree mode: shared brain at /path/to/main-repo/.wolf
✓ Local .wolf/ for anatomy, memory, and session data
```

No extra configuration needed. Learnings, bug fixes, and metrics persist in the main repo even when worktrees are cleaned up. Each worktree gets its own anatomy (reflecting the branch's files) and session logs.

See [How It Works: Git Worktree Support](/how-it-works#git-worktree-support) for technical details.

::: tip Windows path separators
If you see path errors on Windows, ensure you're using a recent Node.js 20+ release. OpenWolf normalizes paths internally, but some edge cases require Node 20.10+.
:::
26 changes: 17 additions & 9 deletions docs/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,20 @@ All hooks are **pure Node.js file I/O**. No network calls, no AI, no external de
└──────────────┘ └──────────┘
```

## Shared vs Local Files

In a git worktree, hooks automatically resolve brain files (cerebrum, buglog, token-ledger) from the **main repo's** `.wolf/`, while session-specific files (anatomy, memory, session state) stay in the **worktree's** `.wolf/`. See [Git Worktree Support](/how-it-works#git-worktree-support) for details.

In a normal repo (not a worktree), all files live in the same `.wolf/` directory as before.

## `session-start.js`

**Fires:** When a Claude Code session begins.

**What it does:**
1. Creates a fresh `_session.json` in `.wolf/hooks/` with a unique session ID
2. Appends a session header to `.wolf/memory.md` with a table template
3. Increments the `total_sessions` counter in `token-ledger.json`
1. Creates a fresh `_session.json` in `.wolf/hooks/` with a unique session ID (local)
2. Appends a session header to `.wolf/memory.md` with a table template (local)
3. Increments the `total_sessions` counter in `token-ledger.json` (shared in worktrees)

**Timeout:** 5 seconds

Expand Down Expand Up @@ -76,9 +82,10 @@ All hooks are **pure Node.js file I/O**. No network calls, no AI, no external de
**Stdin:** `{ "tool_name": "Write", "tool_input": { "file_path": "...", "content": "..." } }`

**What it does:**
1. Reads `cerebrum.md` and extracts entries from the `## Do-Not-Repeat` section
1. Reads `cerebrum.md` (shared in worktrees) and extracts entries from the `## Do-Not-Repeat` section
2. For each entry, checks if the content being written contains flagged patterns
3. If matched: writes a warning to stderr. _"⚠️ OpenWolf cerebrum warning: 'never use var', check your code"_
4. Searches `buglog.json` (shared in worktrees) for past bugs in the same file

**Pattern matching:** Simple regex on quoted strings and "never use X" / "avoid X" phrases. No LLM involved.

Expand Down Expand Up @@ -109,9 +116,10 @@ All hooks are **pure Node.js file I/O**. No network calls, no AI, no external de
**Stdin:** `{ "tool_name": "Write", "tool_input": { "file_path": "...", "content": "..." } }`

**What it does:**
1. **Updates `anatomy.md`**: reads the written file, extracts a description, estimates tokens, upserts the entry in the correct directory section. Writes atomically (temp + rename).
2. **Appends to `memory.md`**: logs the action with timestamp, file path, and token estimate.
3. **Records in `_session.json`**: file, action type, tokens, timestamp.
1. **Updates `anatomy.md`** (local): reads the written file, extracts a description, estimates tokens, upserts the entry in the correct directory section. Writes atomically (temp + rename).
2. **Appends to `memory.md`** (local): logs the action with timestamp, file path, and token estimate.
3. **Records in `_session.json`** (local): file, action type, tokens, timestamp.
4. **Auto-detects bug fixes** and logs to `buglog.json` (shared in worktrees).

**Timeout:** 10 seconds (longer because anatomy update involves file parsing)

Expand All @@ -122,10 +130,10 @@ All hooks are **pure Node.js file I/O**. No network calls, no AI, no external de
**Fires:** When Claude finishes a response.

**What it does:**
1. Reads `_session.json` for accumulated session data
1. Reads `_session.json` (local) for accumulated session data
2. If there's been any activity (reads or writes):
- Builds a session entry with read/write totals
- Appends the session to `token-ledger.json`
- Appends the session to `token-ledger.json` (shared in worktrees)
- Updates lifetime counters
- Calculates estimated savings (anatomy hits + blocked repeated reads)

Expand Down
77 changes: 62 additions & 15 deletions docs/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@ OpenWolf operates as invisible middleware between you and Claude Code. It has th

Every OpenWolf project has a `.wolf/` folder containing:

| File | Purpose |
|------|---------|
| `OPENWOLF.md` | Master instructions Claude follows every turn |
| `anatomy.md` | File index with descriptions and token estimates |
| `cerebrum.md` | Learned preferences, conventions, and Do-Not-Repeat list |
| `memory.md` | Chronological action log (append-only per session) |
| `identity.md` | Project name, AI role, constraints |
| `config.json` | OpenWolf configuration |
| `token-ledger.json` | Lifetime token usage statistics |
| `buglog.json` | Bug encounter/resolution memory |
| `cron-manifest.json` | Scheduled task definitions |
| `cron-state.json` | Cron execution state and dead letter queue |
| `suggestions.json` | AI-generated project improvement suggestions |
| `designqc-report.json` | Design QC capture metadata and results |
| `reframe-frameworks.md` | UI framework knowledge base for Reframe |
| File | Purpose | Worktree |
|------|---------|----------|
| `OPENWOLF.md` | Master instructions Claude follows every turn | Shared |
| `anatomy.md` | File index with descriptions and token estimates | Local |
| `cerebrum.md` | Learned preferences, conventions, and Do-Not-Repeat list | Shared |
| `memory.md` | Chronological action log (append-only per session) | Local |
| `identity.md` | Project name, AI role, constraints | Shared |
| `config.json` | OpenWolf configuration | Shared |
| `token-ledger.json` | Lifetime token usage statistics | Shared |
| `buglog.json` | Bug encounter/resolution memory | Shared |
| `cron-manifest.json` | Scheduled task definitions | Shared |
| `cron-state.json` | Cron execution state and dead letter queue | Shared |
| `suggestions.json` | AI-generated project improvement suggestions | Shared |
| `designqc-report.json` | Design QC capture metadata and results | Shared |
| `reframe-frameworks.md` | UI framework knowledge base for Reframe | Shared |

**Markdown is source of truth** for human-readable state. JSON is for machine-readable state only.

The **Worktree** column indicates where the file lives when running in a git worktree. "Shared" files live in the main repo's `.wolf/` and persist across worktrees. "Local" files live in each worktree's own `.wolf/`. In a normal repo, all files are in the same `.wolf/` directory. See [Git Worktree Support](#git-worktree-support) below for details.

## Hooks -- The Enforcement Layer

OpenWolf registers 6 hooks with Claude Code via `.claude/settings.json`. These fire automatically:
Expand Down Expand Up @@ -147,6 +149,51 @@ The daemon's AI tasks (`cerebrum-reflection` and `project-suggestions`) use `cla

If `ANTHROPIC_API_KEY` is set in your environment, OpenWolf automatically strips it when spawning `claude -p` to ensure the subscription OAuth token is used instead.

## Git Worktree Support

OpenWolf works with git worktrees out of the box. This is essential for tools like [Conductor](https://conductor.app) that run multiple Claude agents in parallel, each in its own worktree.

### The problem

Without worktree support, each worktree gets its own isolated `.wolf/` directory. Learnings, bug fixes, and metrics are lost when the worktree is cleaned up, and there is no cross-pollination between concurrent agent sessions.

### Two-tier `.wolf/` directory

When OpenWolf detects that it is running inside a git worktree, it splits `.wolf/` into two tiers:

**Shared brain** (stored in the main repo's `.wolf/`):
| File | Why shared |
|------|-----------|
| `cerebrum.md` | Learnings and preferences apply to the whole project |
| `buglog.json` | Bug fixes are relevant across all branches |
| `token-ledger.json` | Lifetime metrics should accumulate, not fragment |
| `identity.md` | Agent identity is project-wide |
| `config.json` | Configuration applies globally |
| `OPENWOLF.md` | Protocol is the same everywhere |

**Local workspace** (stored in the worktree's `.wolf/`):
| File | Why local |
|------|----------|
| `anatomy.md` | Reflects the branch's file structure, which may differ |
| `memory.md` | Session action log -- concurrent writes from multiple agents would conflict |
| `hooks/_session.json` | Current session state is ephemeral |
| `hooks/*.js` | Hook scripts need to exist locally for Claude Code to run them |

### How worktree detection works

OpenWolf detects worktrees using pure filesystem reads (no git commands, so hooks stay fast):

1. Checks if `.git` is a **file** (worktrees) rather than a **directory** (normal repos)
2. Parses the `gitdir:` pointer from the `.git` file
3. Reads the `commondir` file inside that gitdir to find the main repo's `.git` directory
4. Resolves the parent directory as the main repo root

This detection is cached per process -- hooks only pay the cost once per invocation.

### When not in a worktree

Everything works exactly as before. The shared and local `.wolf/` directories are the same path, so there is no behavior change for normal repos.

## Token Tracking

Every file read/write is estimated using character-to-token ratios:
Expand Down
30 changes: 30 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,36 @@ openwolf scan

Then re-run `openwolf scan --check` to confirm it now exits with code 0. This is useful in CI pipelines to enforce that anatomy is kept current.

## Worktree: brain files not shared

**Symptom:** Running `openwolf status` in a worktree does not show "Worktree: yes" and brain files are being stored locally instead of in the main repo.

**Cause:** OpenWolf detects worktrees by checking if `.git` is a file (not a directory). If `.git` is missing or the `commondir` file inside the gitdir is unreadable, detection fails silently and OpenWolf falls back to local-only mode.

**Fix:** Verify the worktree is properly set up:

```bash
# Should show a file, not a directory
ls -la .git

# Should contain "gitdir: /path/to/main/.git/worktrees/<name>"
cat .git
```

If the `.git` file exists and points to a valid gitdir, re-run `openwolf init` in the worktree.

## Worktree: shared .wolf/ missing

**Symptom:** Hooks warn about missing cerebrum.md or buglog.json in a worktree.

**Cause:** The main repo's `.wolf/` directory was deleted or never initialized.

**Fix:** Run `openwolf init` in either the main repo or the worktree. Init automatically creates the shared `.wolf/` directory in the main repo when it detects a worktree.

```bash
openwolf init
```

## Commands say "OpenWolf not initialized"

**Symptom:** Running commands like `openwolf cron`, `openwolf bug`, or `openwolf daemon` shows "OpenWolf not initialized".
Expand Down
Loading