ai_session_tools v0.3.0
ai_session_tools v0.3.0 (2026-03-08)
Key changes in v0.3.0 that affect daily use:
- Date filtering on every command:
--since,--until,--whenscope results without grep, and skip files older than the cutoff. On large session directories this cuts search time by roughly 50x. - Unified search across Claude Code, AI Studio, and Gemini CLI: auto-discovered on first run, searched together by default.
AISessionlibrary entry point: zero-config Python API; all methods return typed dataclasses.
Install / Upgrade
uv tool install git+https://github.com/ahundt/ai_session_toolsAlready installed?
uv tool upgrade ai_session_toolsPython 3.12+ required (raised from 3.8 in v0.2.0). orjson is now a required dependency (was optional [fast]); it installs automatically with the package.
Breaking Changes
Python minimum raised from 3.8 to 3.12. Required by orjson, which is now a mandatory dependency (was optional [fast]).
Renamed classes and entry point
| v0.2.0 | v0.3.0 |
|---|---|
SessionBackend |
AISession |
RecoveredFile |
SessionFile |
RecoveryStatistics |
SessionStatistics |
Renamed methods (on AISession)
| v0.2.0 | v0.3.0 |
|---|---|
analyze_session() |
get_session_analysis() |
timeline_session() |
get_session_timeline() |
analyze_planning_usage() |
get_planning_usage() |
cross_reference_session() |
get_file_edits() |
export_session_markdown() |
get_session_markdown() |
search() |
search_files() |
search_messages_with_context() |
search_messages(context=N) |
search_messages(query, context=0) now uses keyword-only arguments after query.
get_statistics() return type
Returns a SessionStatistics dataclass instead of a plain dict:
# v0.2.0
stats = engine.get_statistics()
n = stats["total_sessions"]
# v0.3.0
stats = engine.get_statistics()
n = stats.total_sessionsFilterSpec renames
| v0.2.0 | v0.3.0 |
|---|---|
FilterSpec(after=...) |
FilterSpec(since=...) |
FilterSpec(before=...) |
FilterSpec(until=...) |
.with_session() |
.with_sessions() |
.with_edit_range(min, max) |
.with_edit_range(min_edits=N, max_edits=N) |
FilterSpec is now callable directly. The intermediate SearchFilter class is gone:
# v0.2.0
matching = SearchFilter(spec)(files)
# v0.3.0
matching = spec(files)Removed classes
| v0.2.0 | v0.3.0 |
|---|---|
LocationMatcher |
SearchFilter.by_location_pattern(include=[], exclude=[]) |
ChainedFilter(f1, f2) |
f1 & f2 operator |
CLI flag renames
--sourcerenamed to--provider--afterand--beforestill accepted but hidden; use--sinceand--untilSummarydisplay mode renamed toCompact
What's New
Date filtering
Every command accepts --since, --until, and --when:
aise messages search "auth" --since 14d # messages from the last two weeks
aise messages corrections --since 30d # corrections you gave Claude, by type
aise files history engine.py # version history of a file across sessions
aise stats --since 2026-01 # session stats since January
aise list --since 7d # last 7 days
aise files search "*.py" --when 202X # entire 2020s decade
aise stats --since 2026-02-01 --until 2026-03-01You can write dates in whatever form is natural: exact ISO dates, partial dates like
2026-01, duration shorthands like 7d or 2w, NLP phrases like "yesterday" or
"2 weeks ago", EDTF wildcards like 202X for an entire decade, and EDTF intervals
like 2026-01/2026-03. Run aise dates for the full format reference and spec link.
When --since is set, aise checks each session file's mtime before opening it.
Sessions older than the cutoff are skipped. On directories with hundreds of sessions,
this cuts search time by roughly 50x.
Unified search across Claude Code, AI Studio, and Gemini CLI
All three session sources are auto-discovered on first run and searched together:
aise messages search "authentication" # all sources
aise messages search "authentication" --provider claude # Claude only
aise list --provider aistudio # AI Studio sessions only
aise stats --provider geminiSources are cached for 24 hours and managed with:
aise source list
aise source scan --force # re-discover everything
aise source add name /path # register a custom directory
aise source remove nameAuto-discovery covers macOS CloudStorage, Linux drive mounts, and Windows Google
Drive paths.
AISession: zero-config library entry point
Auto-detects all sources; no paths required:
import ai_session_tools as aise
with aise.AISession() as session:
sessions = session.get_sessions(since="7d")
messages = session.search_messages("authentication")
files = session.search_files("*.py")All methods return typed dataclasses (SessionInfo, SessionMessage, SessionFile,
SessionStatistics).
New CLI commands
aise --version/-Vaise history: session history with--format/--provideraise commands list|context: slash command discovery across sessions; shows working directory and git branch per commandaise messages inspect: single-session message analysis (renamed frommessages analyzeto avoid collision withaise analyze)aise instruction-history: extract system prompt / instruction injection historyaise dates: date format referenceaise config show|init: show or create config file
New CLI flags
--full-uuid: show full 36-char session IDs instead of 8-char prefix--type user|assistant|slash|compactiononmessages searchandmessages timeline--context Nonmessages search: show N surrounding messages per match--context-before/--context-after: asymmetric context windows--fixed-strings/-F: literal string matching instead of regex--skip-injection: filter out SKILL.md/CLAUDE.md injection content--ids-only: output session IDs only (onlist,corrections,planning,commands)--no-compaction: exclude compaction summaries from search results--greponmessages timeline: git-log-style regex filtering--detailonplanningandcommands: show arguments and session IDs--sessiononcorrections: scope to a single session--after-index/--after-timestamp: resume search from a position--format json --output <file>routing on all commands--limit 0means unlimited (previously returned zero results)- Config defaults: set
format,max_chars,providerinconfig.json["defaults"]
Analysis pipeline
aise analyze classifies your sessions by technique, vocabulary, and era, and groups
them by working directory. If you work across multiple projects and want to understand
how your AI usage patterns have changed over time, or which projects saw the most
activity, this is the command. Unchanged sessions are skipped on re-runs:
aise analyze # run full pipeline, skip unchanged sessions
aise analyze --force # re-run all stages
aise analyze --status # dry-run: show what would run
aise analyze --step codebook # run one stage onlyThe pipeline stages: codebook-based technique classification (with word-boundary
markers to avoid partial-word false positives), prose/code splitting for vocabulary
analysis (strips code tokens from n-grams before counting), and era detection from
filename date prefixes, ISO dates in content, and Gemini startTime fields. Output
formats are symlinks (default), JSON, and Markdown. A provenance graph
(SESSION_GRAPH.json) records which sessions belong to which working directories.
Unified config
Config lives at the OS-appropriate path and is auto-created on first use:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/ai_session_tools/config.json |
| Linux | ~/.config/ai_session_tools/config.json |
| Windows | %APPDATA%\ai_session_tools\config.json |
The defaults section sets per-user defaults for format, max_chars, provider,
and correction patterns. Override for a single run with AI_SESSION_TOOLS_CONFIG=/path.
Windows support
aise now runs on macOS, Linux, and Windows:
- Rich Console uses ASCII fallback for box-drawing characters on Windows cp1252 consoles
(previously crashed withUnicodeEncodeError) - All docstrings use only cp1252-safe characters
- pathlib-based path handling throughout
Bug Fixes
Data correctness
get_versions("data[0].py")returned zero results; glob metacharacters in filenames were not escaped. Now usesglob.escape().- Sessions with no JSONL timestamp incorrectly passed date filters; falsy
ts_firstbypassed comparison. Now excluded when a date filter is active. cross_reference_session("cli.py")matchedold-cli.py;endswith()was too broad. Changed to exactPath(fp).namematch.search_messages_with_context(message_type="user")dropped adjacent assistant messages from context windows; filter moved from buffer loop to match loop.source="all"silently excluded Claude sessions; missingClaudeSourceadapter added.aise stats --provider claudereported 0 sessions; was counting from emptyrecovery_dirinstead of_iter_all_jsonl().- Multi-source
list_sessions()returned AI Studio sessions first instead of newest-first; cross-source timestamp sort added. - AI Studio
message_countalways 0; now parses JSON chunk count. - AI Studio
timestamp_firstalways empty; now populated from file mtime.
Display and formatting
aise files searchshowed raw ANSI escape codes instead of a rendered table.aise listcolumn widths collapsed when sessions had missing dates.- Terminal width defaulted to 80 when stdout was piped; now reads from stderr fd.
- Session ID truncation was inconsistent (16 chars vs 8 chars); standardized to 8-char prefix.
- Rich
MarkupErroron special characters in user content; now escaped. - Windows cp1252 console crash on Unicode box-drawing chars; Console factory with
safe_boxdetection added.
Filters and dates
FilterSpec(since="7d")stored the raw string instead of resolving it.Filter.__or__matched everything when one side was an empty filter.--limit 0returned zero results; now means unlimited.parse_date_input(None)crashed; now returns None.FilterSpec.matches_datetime()gave wrong results across sources due to timezone designators and sub-second precision.
Security and PII
session_db.jsonstored absolute home directory paths; changed to~/paths.- Five analysis modules fell back to hardcoded paths; removed. Requires explicit
org_dirin config. - ReDoS protection added to regex entry points;
_check_redos_safe()detects nested quantifiers beforere.compile()and falls back to literal substring matching.
Corrections accuracy
- Skill injection false positives: SKILL.md/CLAUDE.md bodies triggered correction patterns; now detected and excluded via
_is_skill_injection()heuristic. - UUID-era name-based detection skipped; was producing false era labels from UUID-style session names.
Config
- Config files using old
after/beforekeys are auto-migrated tosince/until. - Config cache was wiped on
OSErrorduring write; in-process cache now preserved. AI_SESSION_TOOLS_CONFIGenv var change did not invalidate config cache.- Analysis pipeline ignored
--configCLI flag; unified toconfig.py. aise configandaise sourcewith no subcommand errored; addedinvoke_without_command=True.--format json --outputrouting was broken oncommands listandcommands context.
Claude Code Integration
After installing autorun, use
/ar:ai-session-tools (or /ar:claude-session-tools) inside Claude Code to search
and recover session history without leaving the editor. Especially useful right after
context compaction to restore previous context inline.
