{"id":51016665,"url":"https://github.com/chrisbloom7/to-wit","last_synced_at":"2026-06-21T11:31:24.146Z","repository":{"id":349066935,"uuid":"1196645332","full_name":"chrisbloom7/to-wit","owner":"chrisbloom7","description":"A searchable catalog of your Claude Code conversations, organized by topic.","archived":false,"fork":false,"pushed_at":"2026-05-22T16:12:10.000Z","size":411,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T20:47:07.267Z","etag":null,"topics":["ai","claudecode","developertools","opensource","search"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisbloom7.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-30T22:42:18.000Z","updated_at":"2026-05-22T16:10:48.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/chrisbloom7/to-wit","commit_stats":null,"previous_names":["chrisbloom7/claudecat","chrisbloom7/to-wit"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/chrisbloom7/to-wit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisbloom7%2Fto-wit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisbloom7%2Fto-wit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisbloom7%2Fto-wit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisbloom7%2Fto-wit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisbloom7","download_url":"https://codeload.github.com/chrisbloom7/to-wit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisbloom7%2Fto-wit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34608892,"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-21T02:00:05.568Z","response_time":54,"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","claudecode","developertools","opensource","search"],"created_at":"2026-06-21T11:31:20.635Z","updated_at":"2026-06-21T11:31:24.141Z","avatar_url":"https://github.com/chrisbloom7.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# To Wit\n\n\u003e _to wit: to make clearer or more particular something that you have already said_\n\nTo Wit is a searchable catalog of your [Claude Code](https://claude.ai/code) conversations, organized by topic.\n\nClaude Code conversations are analyzed, filtered for substance, and stored in a local SQLite database. A CLI lets you search, list, and export conversations. A stop hook keeps the catalog up to date automatically after each session.\n\n```shell\ntowit search hook\n/Users/chrisbloom7\n  ID                                    Title                        Keywords      Date\n  ------------------------------------  ---------------------------  ------------  ----------\n  350fa22f-10b7-48ff-ac9d-bd9f1081c23b  Debugging non-firing Stop …  stop-hook     2026-03-31\n\ntowit resume 350fa22f-10b7-48ff-ac9d-bd9f1081c23b\n# =\u003e switch to `/Users/chrisbloom7` and call `claude --resume 350fa22f-10b7-48ff-ac9d-bd9f1081c23b`\n```\n\n\n## Requirements\n\n- [Claude Code](https://www.anthropic.com/claude-code) (`brew install claude-code`)\n- Python 3.11+ (`brew install python`)\n\n## Installation\n\n\u003e Homebrew tap coming soon. For now, clone and run the install script.\n\n```bash\ngit clone https://github.com/chrisbloom7/to-wit.git ~/path/to/to-wit\n~/path/to/to-wit/install\n```\n\nBy default, `install` links into `/usr/local/bin`. Pass a different directory as the first argument if needed:\n\n```bash\n~/path/to/to-wit/install ~/.local/bin\n```\n\n## Quick start\n\n```bash\n# Full setup: generate config, initialize database, install stop hook, and index existing conversations\ntowit setup --full\n\n# Or step by step:\ntowit setup --config  # Generate ~/.towit/config.toml (optional but recommended)\ntowit setup           # Initialize the database\ntowit install-hook    # Add stop hook to Claude Code (auto-indexes future sessions)\ntowit backfill        # Index all existing conversations (~4 sec/session on Apple M4 Pro)\n```\n\n## Usage\n\n```\ntowit \u003csubcommand\u003e [options]\n\nSubcommands:\n  setup [--full | --hook | --config]  Initialize database\n                                  --full    also generates config, installs hook, and runs backfill\n                                  --hook    also installs the stop hook\n                                  --config  generate ~/.towit/config.toml (skips if already exists)\n  search \u003cterms...\u003e             Search conversations by keyword (default), topic, summary, or title\n    [--or]                        Match any term instead of all (default: AND)\n    [--topic]                     Also search conversation topics\n    [--all]                       Search keywords, topics, summaries, and titles\n    [--summary]                   Also search conversation summaries\n    [--title]                     Also search conversation titles\n    [--format json|csv]           Output format (default: table)\n    [--folder \u003cpath\u003e]             Scope to a working directory\n  list                          List all indexed conversations\n    [--format json|csv]           Output format (default: table)\n    [--folder \u003cpath\u003e]             Scope to a working directory\n    [--topic \u003cname\u003e]              Filter by topic\n    [--keyword \u003cname\u003e]            Filter by keyword\n  resume \u003csession-id\u003e           Resume a session in its original working directory\n    [--force]                     Recreate the working directory if it no longer exists\n  prune [--dry-run]             Remove entries whose transcripts no longer exist\n  export \u003csession-id\u003e           Export a conversation\n    [--format md|json]            Output format: md (default) or json\n    [--summarize]                 AI summary instead of full transcript\n  export --topic \u003cname\u003e         Export all conversations matching a topic\n    [--format md|json]            Output format: md (default) or json\n    [--summarize]                 Meta-summary of all matching conversations\n  backfill                      Index all existing conversations\n    [--dry-run]                   Preview without writing\n    [--force]                     Re-index already indexed conversations\n    [--folder \u003cpath\u003e]             Scope to one project folder\n  install-hook                  Add To Wit stop hook to Claude Code settings\n  uninstall-hook                Remove To Wit stop hook from Claude Code settings\n  teardown [--yes]              Remove hook and delete database\n  implode [--yes]               Full uninstall: remove hook, database, and binary symlink\n    [--install-dir \u003cdir\u003e]         Directory where towit was installed (default: /usr/local/bin)\n  stats                         Show catalog statistics\n  doctor                        Verify setup: config, database, and hook\n  help                          Show this message\n```\n\n## How it works\n\n**Indexing:** Each conversation is parsed from Claude Code's JSONL transcript files (`~/.claude/projects/`). Short or purely operational sessions are filtered out. Substantive conversations are analyzed by Claude, which extracts a title, summary, 15–30 specific keywords (identifiers, method names, error messages, domain terms, filenames, etc.), and broad topic tags. Results are stored in `~/.towit/catalog.db` (SQLite, WAL mode).\n\n**What gets indexed:** Deep explorations, research, TIL moments, technical discoveries, documentation writing, theoretical discussions, estimation with depth. Quick one-shots, command execution sessions, and subagent traces are skipped.\n\n**Auto-indexing:** The stop hook (`towit install-hook`) fires after each Claude Code response and indexes the conversation in the background.\n\n## Configuration\n\nTo Wit is configured via `~/.towit/config.toml`. Generate a starter file with all settings commented out:\n\n```bash\ntowit setup --config\n```\n\n### `[indexing]` settings\n\nThese settings control how To Wit calls the Claude API during indexing and directly affect API spend.\n\n| Key | Default | Description |\n|---|---|---|\n| `model` | `\"haiku\"` | Model passed to `claude -p`. Use `\"default\"` to inherit your Claude Code default, or any alias (`\"sonnet\"`, `\"opus\"`) or full model ID (`\"claude-sonnet-4-6\"`). |\n| `reindex_delta` | `2` | Exchanges (user+assistant pairs) that must occur before a resumed session is re-analyzed. The stop hook fires after every response; this prevents re-indexing on every turn. Set to `1` for original behavior. |\n| `min_topics` | `1` | Minimum topic tags Claude should assign per conversation. |\n| `max_topics` | `5` | Maximum topic tags Claude should assign per conversation. |\n| `min_keywords` | `15` | Minimum keywords Claude should extract per conversation. |\n| `max_keywords` | `30` | Maximum keywords Claude should extract per conversation. |\n| `min_summary_sentences` | `3` | Minimum sentences in the generated summary. |\n| `max_summary_sentences` | `6` | Maximum sentences in the generated summary. |\n| `transcript_max_chars` | `8000` | Character cap on the transcript excerpt sent to Claude. When the transcript exceeds this limit, the middle is dropped and replaced with an omission marker; the budget is split 30% from the start and 70% from the end. |\n\n**Example:**\n\n```toml\n[indexing]\nmodel = \"haiku\"\nreindex_delta = 2\nmin_topics = 1\nmax_topics = 5\nmin_keywords = 10\nmax_keywords = 20\nmin_summary_sentences = 2\nmax_summary_sentences = 4\ntranscript_max_chars = 8000\n```\n\n### Cost estimates\n\nEach indexing call sends roughly **2,000–4,000 input tokens** depending on transcript length and content (code-heavy conversations tokenize more densely than prose) plus prompt overhead of ~200 tokens. Output is roughly **300 tokens** (title + summary + keywords + topics JSON). The estimates below use a mid-range of ~2,200 input / 300 output tokens.\n\nThe stop hook fires after every Claude response. With `reindex_delta = 2` (default), a 10-exchange conversation triggers ~5 indexing calls instead of 10.\n\n**Estimated cost — 100 conversations, 10 exchanges each:**\n\n| Model | `reindex_delta = 1` (1,000 calls) | `reindex_delta = 2` (~500 calls) |\n|---|---|---|\n| Haiku 4.5 | ~$2.96 | ~$1.48 |\n| Sonnet 4.6 | ~$11.10 | ~$5.55 |\n| Opus 4.6 | ~$55.50 | ~$27.75 |\n\nPricing based on Anthropic's published rates as of April 2026: Haiku 4.5 at $0.80/$4.00 per million input/output tokens; Sonnet 4.6 at $3.00/$15.00; Opus 4.6 at $15.00/$75.00. Actual costs will vary.\n\n## Uninstalling\n\nTo do a full uninstall in one step — removes the stop hook, database, and binary symlink:\n\n```bash\ntowit implode\n```\n\nOr to remove just the hook and database while leaving the binary in place:\n\n```bash\ntowit teardown\n```\n\nThen remove the binary manually (or `brew uninstall towit` when available).\n\n## Development\n\n```bash\ngit clone https://github.com/chrisbloom7/to-wit.git\ncd to-wit\n\n# Run tests (requires bats-core: brew install bats-core)\n./run-tests\n\n# Run a specific test file\n./run-tests tests/bin/towit.bats\n./run-tests tests/helpers/towit_db_test.py\n./run-tests --filter \"search\"\n```\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisbloom7%2Fto-wit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisbloom7%2Fto-wit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisbloom7%2Fto-wit/lists"}