All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Add
--no-session-persistencetoclaude -panalysis calls so towit's indexing sessions are not saved to disk and do not appear in Claude Code's/resumepicker.
- README Usage section: added missing
doctorsubcommand, correctedexport --formatto showmd|json, fixedsetup --hookwording, reorderedpruneto matchtowit helpoutput.
towit doctorsubcommand: runs 15 health checks across 5 categories and prints a plain-text report with[PASS],[WARN], or[FAIL]per check. Exits 0 when all checks pass or only warnings are present; exits 1 on any failure. Never performs automatic remediation — each failing check includes a remediation hint.- Python: version ≥ 3.11 required for TOML config support
- Claude CLI:
claudebinary present on$PATH - Config file: existence, TOML validity, unknown section/key warnings,
TOWIT_DB_PATHdeprecation warning - Database: file exists, read/write permissions (600), directory permissions (700), required tables present, schema up to date
- Stop hook: Claude Code
settings.jsonexists, hook registered, hook script present on disk
- Color output in
towit doctor:[PASS]in green,[WARN]in bold yellow,[FAIL]in red, remediation hints in dark yellow. Colors are applied only when stdout is a TTY; plain text otherwise.
- Indexing cost controls: new
[indexing]section in~/.towit/config.tomlwith 9 settings to tune Claude API spend:model(default:"haiku") — model passed toclaude -p; use"default"to inherit your Claude Code default, or any alias/full model IDreindex_delta(default:2) — exchanges (user+assistant pairs) that must occur before a resumed session is re-analyzed; prevents re-indexing on every turn of a long conversationmin_topics/max_topics(defaults:1/5) — range of topic tags Claude assigns per conversationmin_keywords/max_keywords(defaults:15/30) — range of keywords Claude extracts per conversationmin_summary_sentences/max_summary_sentences(defaults:3/6) — sentence range for the generated summarytranscript_max_chars(default:8000) — character cap on the transcript excerpt sent to Claude
towit setup --confignow generates a fully commented[indexing]section in the starter config file- README
## Configurationsection documents all settings with a cost-estimates table
- Keywords field: conversations are now indexed with 15–30 specific keywords extracted from the content — identifiers, method/class names, error messages, domain terminology, proper nouns, filenames, plan names, etc. Stored in a normalized
keywordstable with efficient indexed lookups. towit search --topic: new flag to include topics in search scope (topics are no longer searched by default).towit list --keyword <name>: new filter to list conversations by keyword.- Keywords included in all output formats: table (Keywords column), JSON (
keywordsarray), CSV (keywordscolumn). Topics retained in JSON and CSV.
towit searchdefault scope is now keywords instead of topics. Use--topicto include topics,--allto include keywords, topics, summaries, and titles.- Analysis prompt expanded: summary now requests 3–6 sentences with emphasis on capturing context for wide-ranging conversations.
- Table output column renamed from "Topics" to "Keywords" in both
towit searchandtowit list.
- Stop hook no longer blocks Claude Code while waiting for the Claude API to analyze a session. Indexing now runs as a detached background process, so the hook exits immediately after validating the session path.
- Config file support: To Wit now reads
~/.towit/config.toml(TOML format) for persistent configuration. Generate a starter file withtowit setup --configortowit setup --full. towit setup --configflag: generates a commented starter~/.towit/config.tomlwith all options documented; does nothing if the file already exists.
-
TOWIT_DB_PATHenvironment variable is deprecated. Set[database] pathin~/.towit/config.tomlinstead.TOWIT_DB_PATHcontinues to work but emits a deprecation warning. Migration:# ~/.towit/config.toml [database] path = "/your/custom/path/catalog.db"
-
Minimum Python version bumped to 3.11 (required for stdlib
tomllib). -
towit setup --fullnow also generates the config file as its first step.
- Project renamed from claudecat to To Wit; CLI command is now
towit - All
CLAUDECAT_*environment variables renamed toTOWIT_*:TOWIT_DB_PATH,TOWIT_SETTINGS_PATH,TOWIT_INDEXING - Data directory moved from
~/.claudecat/to~/.towit/; existing data must be moved manually:mv ~/.claudecat ~/.towit - Hook path updated; re-run
towit install-hookafter upgrading to update the path in~/.claude/settings.json - GitHub repository renamed from
chrisbloom7/claudecattochrisbloom7/to-wit
search --allflag: searches topics, summaries, and titles simultaneously; mutually exclusive with--summaryand--titlesearch --format json|csvandlist --format json|csv: structured output for agent consumption;--format jsonemits a JSON array withid,title,topics(array),cwd, anddatefields
search --csvandlist --csvflags replaced by--format csvfor consistency withexport --format
opensubcommand renamed toresumeto match Claude Code's--resumeflag terminology;openremains as a deprecated alias with a warning
backfill --dry-runnow applies the sameshould_indexpreflight filter as a live run, so short/trivial sessions are counted as skipped rather than inflating the "would index" totalsetupnow runs schema migrations on existing databases, fixing a "no such column: message_count" error on backfill and indexing for databases created before that column was added
implodesubcommand: full uninstall in one command — removes stop hook, database, and binary symlink, then prints the data directory path (with any remaining files) so nothing is left behind unexpectedlyuninstallscript now delegates toclaudecat implodeinstead of duplicating the teardown + symlink removal logic- Resumed conversations are now re-indexed when new messages are detected, instead of being silently skipped
- Re-indexing passes the previously assigned topics to Claude with a preference hint, reducing topic drift across sessions
message_countcolumn added to theconversationstable; existing databases are migrated automatically on nextsetupor first use
- Moved database default location from
~/.claude/catalog/to~/.claudecat/ - Hook now installs to
~/.claude/settings.json(global) instead ofsettings.local.json - Hook install merges into an existing empty-matcher Stop entry rather than appending a separate one
- Database directory and file are now created with owner-only permissions (
0700/0600) - Hook error logging added: exceptions are written to
~/.claudecat/errors.logwith rotation (100 KB, 2 backups) instead of being silently discarded - Hook path validation:
transcript_pathand derived JSONL paths are verified to be within~/.claude/projects/;session_idis validated against an alphanumeric format before use in path construction - SQL injection guard: added comment and runtime assertion enforcing that dynamic WHERE clause conditions are hardcoded parameterized strings only
- Subprocess environment scoped to an allowlist of prefixes (
HOME,PATH,CLAUDE_*,ANTHROPIC_*, etc.) instead of inheriting the full parent environment - Symlinked JSONL files are excluded from backfill glob traversal
CLAUDECAT_SETTINGS_PATHoverride validated to be within~/.claude/or the system temp directory- JSON fallback regex changed to non-greedy to avoid large-span matches on long output
- CI
actions/checkoutpinned to SHA digest instead of mutablev4tag