Summary
A cross-project audit against cursor-chat-browser-python found five bugs in this project and three in the reference project. All are now fixed and covered by regression tests.
Bugs fixed in claude-code-chat-browser
Bug 1 — app.py: Missing --exclude-rules / -e flag
cursor-chat-browser-python/app.py accepts --exclude-rules PATH (short: -e) to load a privacy filter file at startup and stores the parsed rules in app.config["EXCLUSION_RULES"] for all API routes. This project had no such flag.
Impact: No way to exclude sensitive sessions from the web UI export endpoint, even though the concept was already implemented in the reference project.
Fix:
- Added
--exclude-rules/-e to app.py's argparse
- Added
exclusion_rules_path parameter to create_app()
- Rules are loaded via the new
utils/exclusion_rules.py and stored in app.config
api/export_api.py bulk export now reads EXCLUSION_RULES from app config and filters sessions
Bug 2 — app.py: use_reloader=False instead of platform-aware reloader
cursor-chat-browser-python uses use_reloader=(sys.platform != "win32") — enabling the stat reloader on Linux/macOS while disabling it on Windows to avoid a Flask socket conflict. This project hardcoded use_reloader=False unconditionally, disabling the reloader even on platforms where it works correctly.
Fix: Changed to use_reloader=(sys.platform != "win32").
Bug 3 — scripts/export.py: Missing --exclude-rules / -e flag
The CLI export had no way to filter out sensitive sessions. cursor-chat-browser-python/scripts/export.py has had this flag since its inception.
Fix:
- Added
--exclude-rules/-e (dest exclude_rules) to both the top-level parser and the explicit export subcommand in build_parser()
cmd_export() loads rules via utils/exclusion_rules.py and applies is_excluded_by_rules() per session, incrementing the skip counter on matches
- Created
utils/exclusion_rules.py — a direct port of the reference project's module, with the default rules path changed to ~/.claude-code-chat-browser/exclusion-rules.txt
Bug 4 — scripts/export.py: Export state file format incompatible with cursor-chat-browser-python
cursor-chat-browser-python writes export_state.json as:
{ "lastExportTime": "2026-02-25T12:00:00", "exportedCount": 42, "exportDir": "/path/to/out" }
This project wrote a flat mapping of session UUIDs to file modification timestamps:
{ "abc123...": 1740000000.123, "def456...": 1740001000.456 }
The three standard keys (lastExportTime, exportedCount, exportDir) were entirely absent, making the --since last state invisible to any tooling or cross-app check that reads from the reference format.
Fix:
_save_state() now writes all four keys: lastExportTime (ISO string), exportedCount (int), exportDir (absolute path), and sessions (the per-session mtime dict, moved to a sub-key to preserve this project's fine-grained incremental export)
_load_state() transparently migrates legacy flat files without modifying them on disk
--since last behaviour is unchanged: per-session mtime comparison is preserved under the sessions key
Summary
A cross-project audit against
cursor-chat-browser-pythonfound five bugs in this project and three in the reference project. All are now fixed and covered by regression tests.Bugs fixed in
claude-code-chat-browserBug 1 —
app.py: Missing--exclude-rules/-eflagcursor-chat-browser-python/app.pyaccepts--exclude-rules PATH(short:-e) to load a privacy filter file at startup and stores the parsed rules inapp.config["EXCLUSION_RULES"]for all API routes. This project had no such flag.Impact: No way to exclude sensitive sessions from the web UI export endpoint, even though the concept was already implemented in the reference project.
Fix:
--exclude-rules/-etoapp.py's argparseexclusion_rules_pathparameter tocreate_app()utils/exclusion_rules.pyand stored inapp.configapi/export_api.pybulk export now readsEXCLUSION_RULESfrom app config and filters sessionsBug 2 —
app.py:use_reloader=Falseinstead of platform-aware reloadercursor-chat-browser-pythonusesuse_reloader=(sys.platform != "win32")— enabling the stat reloader on Linux/macOS while disabling it on Windows to avoid a Flask socket conflict. This project hardcodeduse_reloader=Falseunconditionally, disabling the reloader even on platforms where it works correctly.Fix: Changed to
use_reloader=(sys.platform != "win32").Bug 3 —
scripts/export.py: Missing--exclude-rules/-eflagThe CLI export had no way to filter out sensitive sessions.
cursor-chat-browser-python/scripts/export.pyhas had this flag since its inception.Fix:
--exclude-rules/-e(destexclude_rules) to both the top-level parser and the explicitexportsubcommand inbuild_parser()cmd_export()loads rules viautils/exclusion_rules.pyand appliesis_excluded_by_rules()per session, incrementing the skip counter on matchesutils/exclusion_rules.py— a direct port of the reference project's module, with the default rules path changed to~/.claude-code-chat-browser/exclusion-rules.txtBug 4 —
scripts/export.py: Export state file format incompatible withcursor-chat-browser-pythoncursor-chat-browser-pythonwritesexport_state.jsonas:{ "lastExportTime": "2026-02-25T12:00:00", "exportedCount": 42, "exportDir": "/path/to/out" }This project wrote a flat mapping of session UUIDs to file modification timestamps:
{ "abc123...": 1740000000.123, "def456...": 1740001000.456 }The three standard keys (
lastExportTime,exportedCount,exportDir) were entirely absent, making the--since laststate invisible to any tooling or cross-app check that reads from the reference format.Fix:
_save_state()now writes all four keys:lastExportTime(ISO string),exportedCount(int),exportDir(absolute path), andsessions(the per-session mtime dict, moved to a sub-key to preserve this project's fine-grained incremental export)_load_state()transparently migrates legacy flat files without modifying them on disk--since lastbehaviour is unchanged: per-session mtime comparison is preserved under thesessionskey