{"id":49208900,"url":"https://github.com/emiraksay/keddy","last_synced_at":"2026-04-23T20:00:35.515Z","repository":{"id":346023420,"uuid":"1188198100","full_name":"emiraksay/keddy","owner":"emiraksay","description":"Session intelligence for Claude Code — navigable timelines, plan tracking, and past session search","archived":false,"fork":false,"pushed_at":"2026-04-22T13:24:03.000Z","size":2074,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-22T13:29:49.368Z","etag":null,"topics":["claude","claude-code","cli","developer-tools","mcp","session-intelligence","sqlite","typescript"],"latest_commit_sha":null,"homepage":"https://github.com/emireaksay-8867/keddy","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emiraksay.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-21T18:44:24.000Z","updated_at":"2026-04-22T13:24:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/emiraksay/keddy","commit_stats":null,"previous_names":["emireaksay-8867/keddy","emiraksay/keddy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/emiraksay/keddy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emiraksay%2Fkeddy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emiraksay%2Fkeddy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emiraksay%2Fkeddy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emiraksay%2Fkeddy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emiraksay","download_url":"https://codeload.github.com/emiraksay/keddy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emiraksay%2Fkeddy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32196155,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T15:28:30.493Z","status":"ssl_error","status_checked_at":"2026-04-23T15:28:29.972Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude","claude-code","cli","developer-tools","mcp","session-intelligence","sqlite","typescript"],"created_at":"2026-04-23T20:00:25.960Z","updated_at":"2026-04-23T20:00:35.505Z","avatar_url":"https://github.com/emiraksay.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/assets/wordmark-dark.svg\"\u003e\n    \u003cimg src=\"docs/assets/wordmark-light.svg\" width=\"200\" alt=\"keddy\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003ch3 align=\"center\"\u003eSession Intelligence for your coding agent.\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n  Recall any past session in seconds. Stop losing hours digging through raw JSONL.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/keddy\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/keddy.svg?style=flat-square\" alt=\"npm\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\nEvery agentic session leaves a JSONL trail. Endless possibilities inside each exchange. You *can* dig through it. It costs hours, burns tokens, and the answer usually isn't right. Keddy turns every session into structured history you and your agent can pull from.\n\n- Your agent reaches back in through **MCP tools** — any past session, plan, or file history, pulled on demand without re-explaining.\n- You reach back through a **local dashboard** — timelines, plan versions, and milestones, all in your browser at `localhost:3737`.\n- **Nothing leaves your machine.** No telemetry, no cloud sync; optional AI agents use your own API key.\n\n## How Keddy Works\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/assets/architecture-v3-dark.svg\"\u003e\n  \u003cimg src=\"docs/assets/architecture-v3-light.svg\" alt=\"Keddy architecture\" width=\"100%\"\u003e\n\u003c/picture\u003e\n\nFour Claude Code hooks feed a local session reader that parses the transcript and writes to a SQLite database on your machine. The database serves two surfaces: MCP tools Claude can call to pull context, and a dashboard you open in your browser to review sessions visually. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the technical breakdown and [`docs/DECISIONS.md`](docs/DECISIONS.md) for design rationale.\n\n## MCP tools\n\nKeddy registers as an MCP server during `keddy init`, giving Claude tools to reach back into your history. Together they cover everything an agent needs: **find** something across any session, **read** it in detail, and **understand** any context — a session, an exchange, a plan, a file.\n\n| Tool | Purpose |\n|---|---|\n| `keddy_search_sessions` | full-text search across sessions |\n| `keddy_get_session` | full session payload |\n| `keddy_get_plans` | plan version history |\n| `keddy_recent_activity` | last N days summary |\n| `keddy_get_transcript` | specific exchanges in detail |\n| `keddy_search_by_file` | sessions that touched a file |\n| `keddy_project_status` | current state of a project |\n| `keddy_get_session_skeleton` | session outline (3–5KB) |\n| `keddy_transcript_summary` | conversation outline (5–8KB) |\n| `keddy_get_session_note` | retrieve a session's handoff note |\n| `keddy_get_daily_note` | retrieve a day's synthesis note |\n\nExample prompts:\n\n\u003e \"Read my last session through Keddy and continue where I left off.\"\n\u003e \"Pull the plan history for this project before we start.\"\n\u003e \"Check which approaches I tried for auth last week.\"\n\u003e \"Get the exchange where I decided on the JWT approach.\"\n\n## The dashboard\n\n`keddy open` launches Keddy's local interface at `localhost:3737`. It's a read-only React SPA where every session lives in a searchable list — open any one to see its exchanges, plan history, and notes. Full-text search runs across every prompt and response. Active sessions update live as they run.\n\n## Exchanges\n\nExchanges are the turn-by-turn record of every session — every user prompt, every Claude response, every tool call, rendered as a navigable timeline. Equipped with this timeline, you can walk through any session one turn at a time: the moment you asked a question, the moment Claude pivoted, the exact tool error that triggered a retry. No scrolling a raw transcript.\n\nThe timeline surfaces segments (planning, implementing, debugging, testing), plan transitions, git events, and compaction points inline — so the session's shape is visible, not just its content.\n\n## Plans\n\nPlans are the versioned history of every plan your agent drafted, revised, or rejected — with the exact feedback you gave each time. Equipped with this history, you can see how a plan evolved from draft to implementation: which approach you tried first, why you rejected it, what the next version corrected, which version finally got approved and built. It's the record that would otherwise live only in a scroll-through transcript.\n\nPlans show status transitions (drafted → rejected → revised → approved → implemented), your feedback at each rejection, and the tasks created and completed under each approved plan. Pullable through `keddy_get_plans`.\n\n## Optional AI analysis\n\nKeddy's core — capture, full-text search, plan tracking, git events — runs programmatically. AI is an opt-in layer for session notes, daily notes, and activity analysis. Bring your own Anthropic API key.\n\n```bash\nkeddy config set analysis.enabled true\nkeddy config set analysis.apiKey sk-ant-...\n```\n\nYour key stays in `~/.keddy/config.json`.\n\nEach feature runs on Claude Sonnet by default, and can be swapped to Haiku (faster) or Opus (highest quality) from the dashboard's Settings page or via `keddy config set notes.sessionModel \u003cmodel\u003e`.\n\n| Feature | What it produces |\n|---|---|\n| Session notes | Full per-session write-up |\n| Daily notes | Per-day synthesis across sessions |\n| Activity analysis | Per-section breakdowns within a session |\n\n## Session notes\n\nSession notes are detailed written write-ups of any session, generated on demand by an AI agent with full access to Keddy's MCP tools. Equipped with these notes, you or your agent can understand what happened in a session end-to-end — what got built, what broke, what's still unfinished — without replaying the transcript. They stay useful at any distance from the work: during a session to clarify the plan, after it ends to capture what landed, weeks later when someone (or past-you) has to pick up where it stopped.\n\nThe agent reads through your local database via in-process MCP — pulling plans with feedback, specific transcript ranges, file histories — and lets the session's content decide the shape. A debugging chronology for one session. A plan-decision log for another. A short wrap-up for a three-exchange session. No template.\n\nOpt-in — bring your own API key.\n\n## Daily notes\n\nDaily notes are one written narrative of an entire day's work, synthesized across every session you ran. Equipped with a daily note, you get the complete story of a day — what shipped, what didn't, what's still in flight — without reading session notes individually. You can pull yesterday's, last Tuesday's, or any past day's from the dashboard or through MCP.\n\nBefore synthesizing the day, Keddy backfills any missing session notes for it — in parallel, so it stays fast. The daily note is always complete, even for days you never opened the dashboard.\n\n## Activity analysis\n\nActivity analysis breaks a session into its natural pieces — planning, implementing, testing, debugging, pivots — and writes a detailed summary for each. Equipped with these section summaries, you can scan a long session the way you'd scan chapters of a book, jumping straight to the part that matters: a specific plan iteration, the moment an approach changed, a long debugging detour. They complement session notes — where a session note tells the overall story, activity analysis gives per-phase depth.\n\nThe agent uses the same Agent SDK + MCP pattern as session notes, with Keddy's detected boundaries as context rather than a required grouping. The agent decides how to carve the session and writes each piece freely.\n\n## Quick start\n\n```bash\nnpm install -g keddy\nkeddy init\nkeddy open\n```\n\nOr run once without installing: `npx keddy init`\n\n`keddy init` installs four Claude Code hooks, creates a local database at `~/.keddy/keddy.db`, and registers the MCP server. Every session you run in Claude Code from that point forward is captured automatically.\n\n## CLI reference\n\n| Command | Description |\n|---|---|\n| `keddy init` | First-time setup: install hooks, create DB, register MCP server |\n| `keddy open` | Launch dashboard and open in browser (port 3737) |\n| `keddy status` | Show hook status, session count, database size |\n| `keddy config [get\\|set] [key] [value]` | Read or write configuration keys |\n| `keddy import [--force]` | Import historical sessions from `~/.claude/projects/*.jsonl` |\n| `keddy reimport` | Force re-import of every session (refresh all data) |\n| `keddy backfill` | Migrate old exchanges to latest schema (content blocks) |\n| `keddy version` | Print the installed version |\n| `keddy help` | Print usage |\n\nExamples:\n\n```bash\n# Enable AI analysis with your Anthropic key\nkeddy config set analysis.enabled true\nkeddy config set analysis.apiKey sk-ant-...\n\n# Check what got imported\nkeddy status\n\n# Pull in historical sessions after install\nkeddy import\n```\n\n## Configuration\n\nConfiguration lives at `~/.keddy/config.json` and is managed through `keddy config`. The file is created on first `keddy init`.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eFull configuration reference\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\n```jsonc\n{\n  \"dbPath\": \"~/.keddy/keddy.db\",           // Override the database location\n\n  \"analysis\": {\n    \"enabled\": false,                       // Master switch for all AI features\n    \"provider\": \"anthropic\",                // \"anthropic\" or \"openai-compatible\"\n    \"apiKey\": \"\",                           // Your API key — never committed, never sent anywhere but the provider\n    \"baseUrl\": \"\",                          // Optional override for OpenAI-compatible endpoints\n\n    \"features\": {\n      \"sessionTitles\": {\n        \"enabled\": true,\n        \"model\": \"claude-haiku-4-5-20251001\"\n      },\n      \"segmentSummaries\": {\n        \"enabled\": true,\n        \"model\": \"claude-haiku-4-5-20251001\"\n      },\n      \"decisionExtraction\": {\n        \"enabled\": true,\n        \"model\": \"claude-haiku-4-5-20251001\"\n      }\n    }\n  },\n\n  \"notes\": {\n    \"sessionModel\": \"claude-sonnet-4-6\",    // Model for session notes\n    \"dailyModel\": \"claude-sonnet-4-6\",      // Model for daily notes\n    \"autoSessionNotes\": false,              // Auto-generate on session end\n    \"autoDailyNotes\": false                 // Auto-generate at end of day\n  }\n}\n```\n\nSettings can be changed at runtime through the dashboard's Settings page, or with `keddy config set \u003ckey\u003e \u003cvalue\u003e`.\n\n\u003c/details\u003e\n\n## Privacy and data handling\n\n- **Everything runs locally.** The capture pipeline, database, dashboard, and MCP server all run on your machine. No data ever leaves unless you explicitly enable AI analysis and bring your own API key.\n- **Your database lives at `~/.keddy/keddy.db`.** It's a plain SQLite file — you can inspect it, back it up, or delete it at any time.\n- **No telemetry.** Keddy does not phone home, does not collect usage data, and does not include analytics.\n- **AI analysis is opt-in and uses your own keys.** When enabled, prompts and transcripts are sent to the provider you choose (Anthropic by default). The key is stored in `~/.keddy/config.json` and is only used for the configured features.\n\n## System requirements\n\n- **Node.js 22.x** — Node 24 is not yet supported; stick to Node 22 until the native module mismatch is resolved\n- **macOS and Linux** — Tested on macOS 14+ and recent Ubuntu. Windows support is untested\n- **Claude Code 1.0+** — Keddy uses the Claude Code hooks API and the MCP stdio transport\n- **SQLite via better-sqlite3** — Installed automatically; requires a C++ toolchain on first install\n\n## Upgrade\n\n```bash\nnpm install -g keddy@latest\n```\n\nSchema migrations run automatically on first launch after an upgrade. You don't need to re-run `keddy init` unless the hook format changes (which will be called out in release notes).\n\n## Uninstall\n\n```bash\n# Remove Claude Code hooks, MCP registration, and installed binary\nnpm uninstall -g keddy\n\n# Delete your Keddy data (optional — you may want to keep this for a re-install)\nrm -rf ~/.keddy\n```\n\nIf hooks linger in `~/.claude/settings.json`, remove entries whose `command` contains `keddy` manually.\n\n## Troubleshooting\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eHooks aren't firing\u003c/b\u003e\u003c/summary\u003e\n\nCheck `~/.claude/settings.json` — you should see four hook entries (`SessionStart`, `Stop`, `PostCompact`, `SessionEnd`) with `command` paths pointing to Keddy's handler. Re-run `keddy init` if any are missing.\n\nConfirm with `keddy status` — it reports which hooks are currently registered.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDashboard won't open / port 3737 is in use\u003c/b\u003e\u003c/summary\u003e\n\nSomething else is bound to port 3737. Kill the other process or configure Keddy to use a different port (coming in a future release — track in GitHub issues).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eNative module mismatch after Node upgrade\u003c/b\u003e\u003c/summary\u003e\n\n`better-sqlite3` and other native dependencies are compiled against a specific Node version. If you upgrade Node (especially to an unsupported version like 24), the binary breaks.\n\nFix:\n\n```bash\nnpm uninstall -g keddy\n# Switch back to Node 22\nnpm install -g keddy\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDatabase is locked / WAL issues\u003c/b\u003e\u003c/summary\u003e\n\nKeddy uses SQLite's WAL mode for concurrent reads and writes. If a process crashed mid-write, you may see `.keddy.db-wal` and `.keddy.db-shm` files alongside the main database. They're safe to leave — SQLite will recover on next open.\n\nIf the database is genuinely stuck, close `keddy open` and any running Claude Code sessions, then reopen.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eImported sessions are missing\u003c/b\u003e\u003c/summary\u003e\n\n`keddy import` scans `~/.claude/projects/**/*.jsonl`. If your Claude Code data lives elsewhere, imports won't find it. Check where Claude Code writes its transcripts on your system.\n\nTo force a complete re-import: `keddy reimport`.\n\n\u003c/details\u003e\n\n## Tech stack\n\n| Layer | Technology |\n|---|---|\n| Runtime | Node.js 22.x |\n| Language | TypeScript (strict mode) |\n| Database | SQLite via `better-sqlite3` (WAL mode, FTS5) |\n| CLI build | `tsup` |\n| API server | Hono |\n| Frontend | React 19, Tailwind CSS v4, Vite |\n| MCP | `@modelcontextprotocol/sdk` |\n| Tests | `vitest` |\n\n## Development\n\n```bash\ngit clone https://github.com/emiraksay/keddy.git\ncd keddy\nnpm install\n\nnpm test              # Run the test suite\nnpm run typecheck     # TypeScript strict check\nnpm run build         # Build CLI + dashboard bundles\nnpm run dev           # Watch mode for CLI + dashboard + server\n```\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full development workflow, PR process, and coding standards.\n\n## Acknowledgments\n\nKeddy wouldn't exist without:\n\n- [Claude Code](https://docs.claude.com/en/docs/claude-code/overview) — the hooks and MCP APIs that make every part of this possible.\n- [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) — the TypeScript MCP library Keddy builds on.\n- [better-sqlite3](https://github.com/WiseLibs/better-sqlite3), [Hono](https://hono.dev), [Vite](https://vitejs.dev), and [Tailwind CSS](https://tailwindcss.com) — the fast, boring infrastructure that lets us focus on the interesting parts.\n- [Serena](https://github.com/oraios/serena) — the reference point for what a thoughtful open-source agent tool looks like.\n\n## License\n\n[Apache-2.0](LICENSE) — Emir Enes Aksay\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femiraksay%2Fkeddy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femiraksay%2Fkeddy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femiraksay%2Fkeddy/lists"}