{"id":51262533,"url":"https://github.com/daniel-farina/ai-session-manager","last_synced_at":"2026-06-29T13:01:55.042Z","repository":{"id":363858982,"uuid":"1265280126","full_name":"daniel-farina/ai-session-manager","owner":"daniel-farina","description":"Browse, search, and resume your local AI coding CLI sessions — Claude Code, Codex, Grok, opencode, Cursor, Gemini, Copilot, Goose, Droid — in one place. Local-first, nothing leaves your machine.","archived":false,"fork":false,"pushed_at":"2026-06-10T16:21:07.000Z","size":77,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T18:10:38.758Z","etag":null,"topics":["ai-coding","claude-code","cli","codex","developer-tools","local-first"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daniel-farina.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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-06-10T16:20:14.000Z","updated_at":"2026-06-10T17:48:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/daniel-farina/ai-session-manager","commit_stats":null,"previous_names":["daniel-farina/ai-session-manager"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/daniel-farina/ai-session-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel-farina%2Fai-session-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel-farina%2Fai-session-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel-farina%2Fai-session-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel-farina%2Fai-session-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daniel-farina","download_url":"https://codeload.github.com/daniel-farina/ai-session-manager/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniel-farina%2Fai-session-manager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34927687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["ai-coding","claude-code","cli","codex","developer-tools","local-first"],"created_at":"2026-06-29T13:01:54.055Z","updated_at":"2026-06-29T13:01:55.036Z","avatar_url":"https://github.com/daniel-farina.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AI Session Manager\n\nA small Vite + React app that lists your local AI-coding-CLI conversations\nacross **multiple tools**, lets you search/filter them, preview the last 30\nmessages, and copy a ready-to-run command to resume any session.\n\n## Supported tools\n\n| Tool | Storage read | Resume command |\n|------|--------------|----------------|\n| **Claude Code** | `~/.claude/projects/**/*.jsonl` | `claude --resume \u003cid\u003e` |\n| **Codex** | `~/.codex/sessions/**/rollout-*.jsonl` (+ `session_index.jsonl` for titles) | `codex resume \u003cid\u003e` |\n| **Grok** | `~/.grok/sessions/\u003ccwd\u003e/\u003cid\u003e/{summary.json,chat_history.jsonl}` | `grok --resume \u003cid\u003e` |\n| **opencode** | `~/.local/share/opencode/opencode.db` (SQLite) | `opencode --session \u003cid\u003e` |\n| **Cursor** | `~/.cursor/projects/\u003ccwd\u003e/agent-transcripts/\u003cid\u003e/\u003cid\u003e.jsonl` | `cursor-agent --resume \u003cid\u003e` |\n| **Gemini CLI**¹ | `~/.gemini/tmp/\u003chash\u003e/checkpoint*.json` | `gemini` → `/chat resume \u003ctag\u003e` |\n| **GitHub Copilot CLI**¹ | `~/.copilot/history-session-state/*.json` | `copilot --resume \u003cid\u003e` |\n| **Goose**¹ | `~/.local/share/goose/sessions/*.jsonl` | `goose session resume --name \u003cid\u003e` |\n| **Droid**¹ | `~/.factory/sessions/*.json` | `droid --resume \u003cid\u003e` |\n\n¹ Format-based adapter, written to the tool's documented/expected on-disk\nlayout. Each returns nothing until that tool is used (or example data is\npresent); open an issue / tweak the adapter if a real install stores things\ndifferently.\n\nOnly the tools that are actually present on the machine show up; a missing or\nempty data dir is silently skipped.\n\n## Privacy \u0026 security\n\n- **Everything stays local.** The app reads transcripts other CLIs already\n  wrote to your home directory and serves them to your own browser. No\n  telemetry, no network calls, nothing bundled or uploaded.\n- The server binds to **localhost only** (enforced in `vite.config.js`). Don't\n  run it with `--host` — the API would serve your private conversation history\n  to anyone who can reach the port.\n- Every adapter validates its `ref` so the API can only read inside that\n  tool's own data directory (path-traversal and sibling-prefix refs are\n  rejected — covered by the smoke tests). `/api/open` validates paths and\n  spawns the OS opener via `execFile` with an args array, never a shell.\n\n## Platform support\n\n- **macOS** — everything works, including \"Open Terminal\" in the Agents panel.\n- **Linux** — works; folder-open uses `xdg-open`, agent terminals use the\n  first of `x-terminal-emulator`/`gnome-terminal`/`konsole`/`xterm` found.\n- **Windows** — the viewer and adapters work for tools that use the same\n  `~/...` layouts; folder-open uses `explorer`, agent terminals use\n  `start cmd /k`. Less battle-tested than macOS/Linux — reports welcome.\n\n## Run\n\n```bash\nnpm install\nnpm run dev      # opens http://localhost:5191\nnpm test         # smoke-test every adapter + endpoint against your local data\nnpm run build \u0026\u0026 npm run preview   # serve the production build (API included)\n```\n\nThe API runs as a Vite middleware on **both** the dev server and the preview\nserver, so the built `dist/` works end-to-end via `npm run preview` (it still\nreads your local transcripts — nothing is bundled or sent anywhere).\n\nRequires Node 24+ (the opencode adapter uses the built-in `node:sqlite`).\n\n`npm test` (`scripts/smoke-test.mjs`) lists every source, fetches a detail per\nsource, and validates the data contract (unique keys, no missing fields / future\ntimestamps, valid message roles, newest-first ordering), plus the usage and\nopen-path modules. Exits non-zero on any failure. On a machine with no AI-CLI\ndata yet, the data-dependent checks are skipped.\n\n### Run at startup (optional)\n\nWith [pm2](https://pm2.keymetrics.io/):\n\n```bash\npm2 start npm --name ai-session-manager --cwd /path/to/this/repo -- run dev\npm2 save\npm2 startup   # follow the printed instructions for your OS\n```\n\n## How it works\n\n- A tiny dev-server API (in `vite.config.js`) delegates to one **source adapter**\n  per tool under `server/sources/`. Each adapter exports `{ source, list, detail }`\n  and returns a normalised record, so the API contract is identical across tools.\n  `server/sources/index.js` aggregates them — a failing source is skipped rather\n  than taking the whole response down.\n- `GET /api/conversations` returns one entry per top-level session (source, title,\n  project, branch, message count, last activity, ready-to-run resume command),\n  merged across tools and sorted most-recent first. Summaries are cached by\n  file/row mtime so reloads are instant.\n- `GET /api/conversation?source=…\u0026ref=…` returns the last 30 messages for one\n  session. Each adapter validates its own `ref` (path must stay within that\n  tool's data dir; opencode session ids are pattern-checked).\n- `GET /api/sources` returns display metadata (label + accent colour) per tool.\n\n## Adding another tool\n\nDrop a `server/sources/\u003ctool\u003e.js` that exports `source`, `list()`, and\n`detail(ref, lastN)` (return normalised entries via `makeEntry` from\n`_shared.js`), then register it in `server/sources/index.js` and add an entry to\n`SOURCE_META`. No other code needs to change.\n\n## Features\n\n- **Search** across title, project, path, session id, tool name, and first message.\n- **Filter** by tool (chips with per-tool counts) and by project (dropdown,\n  scoped to the active tool).\n- **Sort** by most recent / oldest / most messages / title / tool.\n- **Filters persist** across refresh (search, tool, project, sort, and the stats\n  toggle are saved to `localStorage` under `ccv.filters`).\n- **Expand** any card to read the last 30 messages, color-coded and labelled with\n  the originating assistant (Claude / Codex / Grok / opencode / Cursor / …), with\n  tool calls and results inlined.\n- **Copy resume command** — the exact `cd \"\u003ccwd\u003e\" \u0026\u0026 \u003ctool\u003e resume …` for that tool.\n- **Open** — opens the conversation's project folder in the OS file manager\n  (`GET /api/open` → `open`/`xdg-open`/`explorer`, path-validated, no shell).\n- **Stats panel** (📊 toggle):\n  - *Metrics* (`src/Metrics.jsx`) — conversations per tool, top projects, and a\n    30-day activity sparkline, all hand-rolled inline SVG (no chart lib).\n  - *Usage \u0026 quota* (`server/usage.js` → `GET /api/usage`) — per-tool usage read\n    from local data: Codex rate-limit **quota left**, opencode/Claude/Grok token\n    totals, Cursor edit-tracking; Gemini marked N/A (no local data). Read-only.\n- **PWA** — installable (`public/manifest.webmanifest`, `public/sw.js`,\n  icons; registered via `src/pwa.js`). The service worker is network-first so it\n  never serves stale content and doesn't interfere with dev/HMR; `/api/*` is\n  always network.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniel-farina%2Fai-session-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaniel-farina%2Fai-session-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniel-farina%2Fai-session-manager/lists"}