Bring structure back to long Claude conversations.
Claude Leaf is a Chrome extension for Claude.ai that helps you move through long threads, mark what matters, and revisit edits without losing your place.
If you use Claude for coding, research, writing, or planning, long chats become hard to scan fast. Claude Leaf gives you lightweight controls directly inside the conversation so you can:
- move between messages without hunting through the page
- bookmark important parts of a thread
- tag messages with emoji markers for quick visual scanning
- highlight selected message text and attach local notes
- inspect edited prompts and version branches when a conversation evolves
- schedule a drafted message to send later when timing matters
- keep a subtle read on your Claude session and weekly usage from the composer edge
Move up and down a conversation with floating controls and a live counter so you always know where you are.
Save important messages, organize them, and jump back when you need context again.
Mark messages with lightweight visual tags so key answers stand out during long sessions.
Highlight selected text in Claude or user messages and attach local notes. This module is available in the build, but it starts disabled by default and must be enabled from the popup settings.
See how prompts changed over time, inspect versions, and understand branching paths in edited conversations.
Schedule a drafted message to send later from the composer. This module is available in the build, but it starts disabled by default and must be enabled from the popup settings.
See lightweight session and weekly usage indicators directly on the composer border. This module is enabled by default and stays intentionally low-noise.
These modules exist in the codebase but are not enabled in the current build:
- Compact View for collapsing long responses
- Content Folding for headings and code blocks
- Sidebar Collapse for cleaner sidebar navigation
Install Claude Leaf from the Chrome Web Store:
https://chromewebstore.google.com/detail/claude-leaf/dpodfmfbkdnighbaajagchhbkblememp
-
Clone the repository.
git clone https://github.com/kadirkatirci/claude-leaf.git cd claude-leaf -
Install dependencies and build the extension.
npm install npm run build
-
Open
chrome://extensions. -
Enable
Developer mode. -
Click
Load unpacked. -
Select the project folder.
-
Open claude.ai.
Available in the current build:
- Navigation
- Bookmarks
- Emoji Markers
- Edit History
- Usage Tracker
Available as an opt-in module:
- Scheduled Message (disabled by default)
- Annotations (disabled by default)
Present but dev-disabled:
- Compact View
- Content Folding
- Sidebar Collapse
| Module | Status | Notes |
|---|---|---|
| Navigation | Enabled by default | Floating navigation controls and message counter |
| Bookmarks | Enabled by default | Save and organize important messages |
| Emoji Markers | Enabled by default | Lightweight visual message tagging |
| Edit History | Enabled by default | Prompt edit tracking and branch inspection |
| Usage Tracker | Enabled by default | Passive session and weekly usage edges in the composer |
| Scheduled Message | Optional | Built in, but disabled by default until enabled in popup |
| Annotations | Optional | Highlight selected message text and save local notes |
| Compact View | Dev-disabled | Present in codebase, not active in current build |
| Content Folding | Dev-disabled | Present in codebase, not active in current build |
| Sidebar Collapse | Dev-disabled | Present in codebase, not active in current build |
npm run dev # Watch mode with auto-rebuild
npm run build # Production build
npm test # Node/JSDOM contracts + smoke tests
npm run test:e2e # Playwright fixture E2E suite
npm run live:refresh-profile # Clone the real Chrome Test profile for local live smoke/capture
npm run test:e2e:live # Read-only live Claude smoke against the cloned Test profile
npm run test:e2e:live:modules # Live smoke plus module assertions when Claude Leaf is installed in Test
npm run test:e2e:live:deep # Single-chat deep smoke on the configured live long chat
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint issues
npm run format # Format with PrettierThe Playwright suite runs the real unpacked extension against deterministic claude.ai fixtures.
seedfixtures are mutable interaction hosts for navigation, bookmarks, markers, and edit-history flows.sanitized_htmlfixtures are read-only DOM drift fixtures sourced from live Claude captures.- The browser test harness blocks live
http/httpstraffic by default and only serves committed fixture assets fromhttps://claude.ai/.... - Visual baselines use bundled local IBM Plex fonts so snapshots stay stable across machines and CI.
For the full chat-only operator and developer workflow, see docs/CHAT_TEST_WORKFLOW.md.
Run the full browser suite with:
npm run test:e2eOpen the Playwright UI when iterating locally:
npm run test:e2e:uiFor authenticated local checks, use the real Google Chrome Test profile as the source of truth.
- Chrome must be fully closed before any live command.
- The live pipeline clones the
Testprofile into.auth/chrome-test-liveinstead of automating your daily profile directly. - Live smoke is read-only: it opens the configured short, medium, and long
claude.ai/chat/...targets, validates message/edit counts, writes screenshots, and stores a JSON report under.auth/live-artifacts/.... npm run test:e2e:livealways validates route health.npm run test:e2e:live:modulesadditionally validates Claude Leaf UI surfaces, but that requires one-time manual installation in the ChromeTestprofile.fixtures:captureuses the same cloned live profile workflow before visiting a named chat target.
Configure your private live chat targets locally:
cp scripts/fixtures/live-chat-targets.example.json .auth/live-chat-targets.jsonThen replace the placeholder URLs in .auth/live-chat-targets.json with your real short, medium, and long Claude chat URLs. This file is ignored by git and never committed.
Refresh the clone explicitly:
npm run live:refresh-profileRun the authenticated live smoke suite:
npm run test:e2e:liveTo validate real module attachment in live Chrome, install the repo once in the Test profile:
- Open Google Chrome with the
Testprofile. - Visit
chrome://extensions. - Turn on Developer mode.
- Click Load unpacked and select this repo root.
- Close Chrome completely.
Then run:
npm run test:e2e:live:modulesThis extra setup is required because Chrome 137+ official branded builds no longer honor the --load-extension flag for local automation. Route smoke and capture still work without it.
For a higher-signal live pass on a single real chat, run:
npm run test:e2e:live:deepThis deep smoke stays safe with respect to Claude itself, but it does exercise real Claude Leaf interactions on the configured live long chat:
- navigation next/prev/top and keyboard shortcuts
- bookmark add and panel navigation
- emoji marker add and panel navigation
- edit history panel / modal / branch map
- popup-driven navigation visibility save/sync
The committed fixture set is chat-only and is derived from three live sources:
short→chat-real-shortmedium→chat-real-mediumlong→chat-real-long
Use the fixture pipeline when Claude DOM contracts drift:
-
Log in to
claude.aiin the Google ChromeTestprofile and close Chrome completely. -
Capture the configured chat targets into the ignored source area:
npm run fixtures:capture -- --target short npm run fixtures:capture -- --target medium npm run fixtures:capture -- --target long
-
Sanitize the captures into the committed chat fixtures:
npm run fixtures:sanitize
-
Regenerate all fixture entry pages and validate metadata consistency:
npm run fixtures:refresh
Rules enforced by fixtures:refresh:
- every fixture must have a unique route
seedfixtures must declare aseedProfilesanitized_htmlfixtures must includesanitized-source.htmlsanitized_htmlfixtures are read-only withhelpers.mutable=false- committed chat fixtures are redacted before they are written to the repo, so real conversation text and chat ids stay out of version control
- Add the new release block at the top of
CHANGELOG.md. - For a live release, copy
env.release.exampleto.envand fill in the credentials. - Run
./release.sh --dry-run --yesto validate the changelog, versions, git state, and payloads without external calls. - Run
./release.sh --yesfor the actual release.
To keep the process trustworthy:
npm testnow includes a release-script smoke test.- The script rejects untracked files, records the release commit before external publish steps, packages tracked source files plus fresh build output, and uploads the generated zip to the matching GitHub Release.
This repository also contains a separate unpacked extension at tools/claude-web-guardian/.
- It is not part of the main Claude Leaf build or release zip.
- It watches live
claude.airoutes and selector contracts. - It auto-runs on monitored page changes, keeps a heartbeat fallback, and sends up to three desktop alerts for new failures.
- It ignores
https://claude.ai/code/...routes. - It is the live canary layer for authenticated/manual checks, not a pull-request gate.
- Use it when you need to spot selector drift before refreshing sanitized fixtures.
To use it locally:
- Open
chrome://extensions - Enable
Developer mode - Click
Load unpacked - Select
tools/claude-web-guardian
Recommended canary workflow:
- Keep the fixture suite (
npm run test:e2e) as the fast CI gate. - Use
npm run test:e2e:livefor read-only local smoke against the cloned Google ChromeTestprofile. - Use
Claude Web Guardianmanually or on your own nightly browser profile against a real logged-in Claude session. - If Guardian or live smoke reports drift, refresh the short/medium/long chat captures, sanitize them, and rerun the local Playwright suite before changing production selectors.
src/
├── content.js
├── App.js
├── core/
├── modules/
├── stores/
├── managers/
├── utils/
└── config/
popup/
docs/
icons/
tools/
└── claude-web-guardian/
For architecture and internal development notes, see CLAUDE.md.
If you want to contribute, start here:
- Fork the repository.
- Create a branch:
git checkout -b feature/your-feature - Make your changes.
- Run
npm run lint:fix - Open a pull request.
Please also read CONTRIBUTING.md.
MIT License. See LICENSE.












