1. PEP 723 Inline Metadata & Core Imports
Every standalone executable script in modern Python faces a packaging dilemma: how to specify third-party dependencies without forcing the user to create a virtual environment, run pip install, or maintain separate configuration files like requirements.txt or pyproject.toml.
agy-brain-explorer.py solves this cleanly using PEP 723 (Inline Script Metadata). When run with uv (via uv run agy-brain-explorer.py), the tool automatically reads this comment block, constructs an isolated, cached environment with Python ≥ 3.11 and Typer ≥ 0.12.0, and executes instantaneously with zero setup friction.
Key Architectural Points:
# /// scriptBlock: Standardized PEP 723 specification block declaring the Python runtime requirement (>=3.11) and required package dependencies (typer>=0.12.0).from __future__ import annotations: Enables deferred evaluation of type annotations (PEP 563), allowing self-referencing classes in type hints and modern union syntax (Path | None) without runtime import overhead.- Core Library Imports:
dataclasses.dataclass: Used for high-performance, strongly typed data models (SessionDataandTraceSummary).datetime.datetime, timezone: Handles ISO-8601 parsing and local timezone conversion for human-friendly timestamps.pathlib.Path: Cross-platform object-oriented filesystem paths for navigating~/.gemini/**/brain/directories.typing.Annotated, Any: Powers Typer CLI option and argument declarations.typer: Modern CLI library built on top of Click, using Python type annotations to generate CLI flags, help text, and argument validation.
2. SessionData: Core Trajectory Model & Loader
An Antigravity session directory is an organized artifact folder containing execution logs, scratch scripts, user uploads, and trajectory steps. The SessionData dataclass serves as the primary domain model representing a loaded session.
The SessionData.load() classmethod handles filesystem validation, checks for required JSON Lines (JSONL) transcripts, parses them line-by-line, and builds O(1) indexed lookups for trajectory steps.
Understanding Antigravity Transcript Types:
transcript.jsonl) vs. Full (transcript_full.jsonl):Antigravity generates two transcript files under
.system_generated/logs/:
transcript.jsonl: A token-efficient log where large fields (e.g. huge command outputs, repetitive thinking chains) are truncated, with atruncated_fieldsmetadata array indicating truncated properties.transcript_full.jsonl: The complete, untruncated transcript containing full prompts, full thinking chains, and complete tool payloads.
Method Mechanics:
- Verification: Ensures the directory exists and contains at least one transcript file; raises a friendly
typer.BadParametererror if invalid. - Line-by-Line Streaming: Transcripts are written in JSON Lines format (one JSON document per line). The loader parses each line with
json.loads()and appends it to in-memory step lists. - Dual Indexing: Generates
steps_by_indexandfull_steps_by_indexdictionaries mapping integerstep_indexdirectly to the step dictionary. This enables immediateO(1)random access when drilling down into specific steps.
3. Artifact Resolvers & Heuristic Prompt Parsers
During a session, Antigravity records rich contextual cues inside step payloads and directory structures. However, this metadata is often formatted in prompt templates or distributed across tool parameters.
This section provides helper methods on SessionData to resolve step output text files, extract the user's pristine request from XML tags, extract runtime configuration heuristics (such as active model selection, client local time, and mentioned workspace items), and safely format table cells for Markdown.
Inspection & Trajectory Helpers:
get_step_output_file(step_index): Resolves the physical path to.system_generated/steps/<step_index>/output.txt. Tool execution outputs and terminal command logs are preserved in these text files.get_user_request_clean(): Antigravity encapsulates user inputs in<USER_REQUEST>...</USER_REQUEST>XML tags alongside system metadata. This method uses a regex match (withre.DOTALL) to strip prompt boilerplate and isolate the user's actual prompt text.get_user_requests(): Extracts all conversational turns and prompt submissions throughout the entire trajectory, enabling multi-turn audit comparisons.get_last_model_response(): Retrieves the final planner response or terminal outcome of the session to quickly assess whether the agent fulfilled the user's request.get_tool_counts(): Aggregates total invocations per tool across all steps into a frequency dictionary.get_start_and_end_times(): Computes starting timestamp, ending timestamp, and human-readable elapsed wallclock duration (end_time - start_time).get_modified_files(): Scans tool call parameters across the session for file-writing actions (write_to_fileandreplace_file_content) to compile a list of all created or edited targets.get_metadata_info():- Model Detection: Extracts the active AI model name by parsing system notification strings like
The user changed setting `Model Selection` from ... to Gemini 3.8 Flash (Medium). - Client Local Time: Discovers the client timestamp recorded in
The current local time is: .... - Mentions: Detects referenced files or artifacts using
@[...]patterns, automatically filtering out template tokens likeITEM. - Workspace CWD: Scans the session's tool calls (e.g.
run_commandarguments) forCwdparameters to determine which repository or workspace folder the session operated in.
- Model Detection: Extracts the active AI model name by parsing system notification strings like
sanitize_md_cell(): Sanitizes multiline text and unescaped pipe characters (|) so they don't break GitHub Flavored Markdown table row formatting.
4. TraceSummary & Trajectory Search Matchers
Finding past conversations requires structured metadata and robust, multi-modal query matching across heterogeneous step types (user requests, model explanations, chain-of-thought thinking, and tool invocations).
This section defines the enhanced TraceSummary record (storing both preview and untruncated prompt text) and implements two foundational search helper functions: extract_snippet() and step_matches_query().
Search Architecture & Helpers:
TraceSummary.full_user_request:While
user_requestcontains a 90-character truncated snippet for compact table listing,full_user_requestretains the complete, unshortened initial prompt. This guarantees keyword queries never miss matches that happen to occur past the 90th character of a prompt.extract_snippet(text, query, max_length=120):Finds the query substring case-insensitively, computes a surrounding window (up to 35 characters before the match and 55 characters after), and gracefully adds leading or trailing ellipsis (
...) if the text extends past the window boundaries.step_matches_query(step, query):A multi-faceted inspector that checks if a query matches any aspect of a trajectory step:
- Tool Calls: Inspects tool names,
CommandLine,AbsolutePath,TargetFile,toolAction,toolSummary, or any argument in the serialized arguments payload. Returns an informative tag like`run_command`: .... - Content: Checks textual content for user inputs (stripping XML wrapper tags) or assistant responses.
- Thinking: Checks internal model chain-of-thought blocks, prefixing matched excerpts with
[thinking].
- Tool Calls: Inspects tool names,
5. Multi-Brain Directory Discovery
Antigravity can be run in multiple contexts across a developer machine: through the primary GUI application, the command-line interface (agy / antigravity-cli), or specialized agent sidecars (antigravity-acp). Each context stores its conversation brains under subdirectories within ~/.gemini/.
This section implements format_datetime_display() for human-friendly timestamps and find_all_brain_directories() to automatically discover all brain storage directories across the entire system.
Multi-Brain Storage Architecture:
~/.gemini/antigravity/brain/: Main Antigravity IDE sessions and paired pair-programming conversations.~/.gemini/antigravity-cli/brain/: Sessions initiated via terminal CLI commands.~/.gemini/antigravity-acp/brain/: Sessions from agentic companion protocols and headless sidecars.~/.gemini/**/brain/: Any custom or nested brain storage roots.
Discovery Strategy:
- Targeted Globbing: First performs sorted globbing for
antigravity*/brainto prioritize standard root locations. - Recursive Fallback: Recursively scans for any other directory named
brainunder~/.gemini. - Deduplication via Dict Keys: Uses
dict[Path, None]to preserve discovery order while ensuring no brain directory is processed twice. format_datetime_display(): Converts UTC ISO-8601 timestamps into the user's current local timezone (strftime("%Y-%m-%d %H:%M")), providing immediate temporal context.
6. Chronological Trace Discovery & Query Filtering: discover_traces()
Listing conversation histories across dozens or hundreds of sessions requires speed and accuracy. Reading entire transcript_full.jsonl files (which can exceed hundreds of megabytes) would make listing sluggish.
discover_traces() implements a high-performance scanner that inspects every session directory across all discovered brains, reads only the minimal initial lines to extract metadata and user requests, counts steps, filters by initial prompt queries when requested, and sorts all sessions chronologically.
Performance & Resilience Features:
- Compact-First Strategy: Prefers
transcript.jsonlovertranscript_full.jsonlfor indexing, drastically reducing I/O latency. - Prompt-Level Query Filtering (
queryparameter):When a search query is passed,
discover_traceschecksquery.lower() in clean_full_req.lower()directly during iteration. Non-matching sessions are bypassed immediately before computing stat lookups or sorting, delivering instantaneous sub-second search across dozens of sessions. - Streaming Inspection: Iterates over the transcript line-by-line, capturing the first
created_attimestamp, tracking step counts, and parsing the initialUSER_INPUTstep without loading full JSON objects into memory. - Robust Fallbacks: If a transcript lacks valid ISO timestamps or is partially written, the function gracefully falls back to filesystem metadata: directory creation time (
st_ctime) and modification time (st_mtime). - Chronological Sorting: Sorts by creation timestamp (newest first by default, with an optional
--ascflag for oldest first).
7. Flexible Session Resolution: find_session_directory()
Developers and AI agents rarely want to type or memorize a 36-character UUID like 5c074549-b840-4999-8aaf-38657370af9e. Often, they want to provide a short 8-character prefix (5c074549), a relative path (./my_session), or an absolute folder path.
find_session_directory() provides multi-modal resolution, searching direct paths, local workspace folders, and all global brain repositories with unambiguous prefix matching.
Resolution Cascade:
- Direct Filesystem Path: Checks if the argument is an explicit directory (relative or absolute, expanding
~), verifying it contains a transcript. - Current Working Directory: Checks
Path.cwd() / session_argfor local session folders. - Exact Brain Matches: Searches all known
~/.gemini/**/brain/directories for an exact folder name match. If multiple brains contain the same ID, it resolves to the most recently modified. - Prefix / Partial Matches: Matches the leading characters of session folder names (case-insensitive):
- If exactly one session matches, it resolves cleanly.
- If multiple sessions match the prefix, it raises a descriptive
typer.BadParametererror displaying the ambiguous candidates. - If none match, it provides a comprehensive error listing all brain folders searched.
8. Trace Explorer Presentation & Interactive REPL
When an agent or user runs the explorer, results should be clear, visually structured, and immediately actionable. This module contains run_interactive_session_picker() (an interactive terminal browser) and run_explorer() (which formats discovered traces into Markdown tables with clickable links and query badges).
Interactive & Markdown Capabilities:
- Clickable Antigravity Links:
Session IDs are formatted as
[`<short_id>`](conversation://<full_session_uuid>). In Antigravity's chat interface, this renders as a native interactive link that directly opens the past conversation in the workspace UI! - Query-Aware Table Presentation:
When a query filter is active (via
--query), the table header highlights the active search filter, and the prompt column dynamically renders a localized snippet with context around the matched term rather than a static 90-character truncate. - Interactive REPL (
run_interactive_session_picker):Triggered with
--interactiveor-i. Users can enter a numerical index (e.g.1) or partial UUID to select a session, and then jump directly into its summary, timeline, tool calls, or commands in an interactive menu loop without re-running shell commands.
9. Trace Explorer Typer Application
Typer turns standard Python function signatures and type annotations into rich command-line interfaces. This section defines the explorer_app instance and its root callback, which handles discovery-mode CLI flags and prompt query filtering.
CLI Options & Defaults:
--query, -q, --search, -s(string):Instant prompt keyword filter. Narrows discovered traces to sessions where the initial request contains the query string (e.g.
-q "build a unified static HTML").--limit, -n(default: 30): Caps the number of conversation traces displayed to avoid terminal buffer overflow.--all, -a(flag): Bypasses pagination to list every discovered session across all brains.--asc(flag): Inverts chronological sorting to display oldest traces first.--brain, -b(string): Filters discovery to a specific brain subfolder (e.g.antigravityorantigravity-cli).--interactive, -i(flag): Launches the interactive trace explorer loop.invoke_without_command=True: Allows the explorer application to run immediately when no subcommands are supplied.
10. Global Cross-Session & Deep Search: cmd_explorer_search
Locating past work is a critical developer requirement. Sometimes you remember what you asked in the initial prompt; other times you only remember a specific file created, command executed, or tool error encountered deep within a 200-step trajectory.
cmd_explorer_search() implements a dual-mode search command on explorer_app, supporting fast prompt matching and comprehensive deep-transcript inspection across all sessions.
Dual-Mode Search Capabilities:
- Prompt-Only Search (Default,
all_steps=False):Invoked via
agy-brain-explorer.py search <QUERY>. Leverages the fastdiscover_traces(query=...)engine to return sessions matching the initial request, showing clickable conversation links, brain origins, step counts, and formatted prompt excerpts. - Deep Step Search (
--all-steps / -s):Invoked via
agy-brain-explorer.py search <QUERY> --all-steps. Iterates through every discovered session directory, streaming its transcript steps and evaluating each step againststep_matches_query().Renders a unified timeline match table detailing:
- Clickable session identifier (
[`<short_id>`](conversation://<uuid>)) - Originating brain environment
- Exact step index where the match occurred
- Step type (e.g.
PLANNER_RESPONSE,GENERIC,USER_INPUT) - Extracted snippet showing the matching tool call, argument, or content
- Clickable session identifier (
- Cross-Session Comparative & Path Commands:
In addition to search,
explorer_appexposes:cmd_explorer_compare(session1, session2): Compares two sessions side-by-side across timing, user turns, tool frequencies, modified files, and outcomes.cmd_explorer_paths(sessions): Resolves and outputs on-disk filesystem targets (directories, JSONL transcripts, logs, step folders) for one or multiple sessions simultaneously.
11. Single-Session Inspection & Summary Renderer
When focusing on a specific session, developers need a comprehensive high-level summary: when it started, when it finished, how long it took, what model was driving it, which workspace it modified, and what tools were utilized.
show_summary() computes these metrics and formats them into a clean Markdown overview document.
Computed Metrics & Renderers:
show_summary(data): Computes session metrics and renders a Markdown overview table:- Clickable URI Links: Generates
file://links for the session directory, compacttranscript.jsonl, fulltranscript_full.jsonl, and active workspace CWD. - Session Timing & Duration: Calculates exact elapsed time between initial prompt timestamp and final response step (
end_time - start_time). - Artifact Counting: Inspects physical disk directories (
scratch/and.user_uploaded/). - Tool Usage Frequency Table: Aggregates all
tool_callsacross all steps in the session, sorted in descending frequency.
- Clickable URI Links: Generates
show_paths(data)&show_paths_multi(sessions_data): Formats detailed on-disk component locations (session directory, transcript files with sizes and step counts, logs directory, step output folders, scratch directory, and workspace) with clickablefile://links.show_comparison(s1, s2): Renders a comprehensive side-by-side Markdown comparison matrix between two sessions:- Compares metadata, timing, duration, step counts, user turns, total tool calls, files written, and model configuration.
- Identifies identical vs diverged initial user prompts and outlines subsequent follow-up user turns.
- Produces an itemized side-by-side tool call count table across all invoked tools.
- Lists all created or modified files with clickable
file://links. - Previews the closing assistant responses and outcomes for both trajectories.
12. Execution Lineage & Timeline Browser
In Antigravity agent trajectories, an action dispatched by the model (e.g., executing a bash command or writing a file) produces a separate result step of type GENERIC. In raw logs, these result steps lack an explicit forward pointer to why they happened.
This module implements backward provenance resolution via find_triggering_step(), linking results back to their parent tool calls, and powers the chronological timeline browser show_steps().
Backward Lineage Resolution (find_triggering_step):
When encountering a
GENERIC step at index K, the algorithm walks backward through steps (K-1, K-2, ...) until it finds the preceding step containing tool_calls. If it hits an unrelated prompt or response boundary first, it halts. This establishes the causal link: "Step 8 is the tool output of Step 7's run_command call."
Timeline Filtering in show_steps():
--tools-only: Filters timeline to steps where tools were invoked.--user-only: Filters timeline to user prompts.- Offset & Limit: Supports slicing and pagination across long agent conversations.
- Smart Previews: Automatically formats action summaries, user requests, or tool names into a single clean line suitable for table rendering.
13. Audit Views: Tool Invocations & Shell Commands
Security and execution integrity are paramount when working with autonomous AI agents. Developers must be able to audit exactly what tools the agent executed, what files were inspected or altered, and what shell commands were run.
This section provides show_tools() and show_commands(), two specialized audit renderers designed for rapid inspection.
Audit Focus Areas:
show_tools():Iterates through every tool invocation in the trajectory. It extracts the tool name, human-readable action summary (from
toolActionortoolSummary), and target arguments (such asCommandLine,AbsolutePath,TargetFile, orDirectoryPath).show_commands():Exclusively isolates terminal shell executions (
run_command). Displays a table pairing each command's step index with its exact working directory (Cwd) and the full shell command string executed. This makes it effortless to verify what commands were run during a build, test, or deployment task.
14. Session CLI Subcommands: summary & steps
The session_app Typer application handles commands scoped to an individual session. It uses a root callback to resolve the session identifier into loaded SessionData and injects it into Typer's context object (ctx.obj).
This section defines session_callback, cmd_summary, and cmd_steps.
Context Injection & Routing:
session_callback:Takes the positional
SESSIONargument (UUID, prefix, or directory path), callsfind_session_directory(), and loadsSessionDataintoctx.objso all downstream subcommands can access it without reloading transcripts.If no subcommand is supplied (e.g.
agy-brain-explorer.py 4c6b51ee), it automatically delegates toshow_summary().cmd_summary: Explicitly triggers the session overview viaagy-brain-explorer.py <SESSION> summary.cmd_steps: Implements the timeline browser with CLI flags:--tools-only / -t--user-only / -u--limit / -n--offset
15. Deep Step Inspection: cmd_step
When debugging an agent failure, examining a tool error, or reviewing model reasoning, developers need to inspect every facet of a single step. cmd_step() is the diagnostic workhorse of the explorer.
It reconstructs the entire step state: metadata, causal parent tool calls, textual content, model thinking / chain-of-thought, pretty-printed JSON tool arguments, and external execution log files.
Step Forensics Components:
- Triggering Action Provenance: If the inspected step is a tool result, the command displays the parent tool name, action summary, and exact invocation parameters (e.g. command line and directory).
- Model Thinking (Chain-of-Thought): If the step contains model reasoning (
thinkingfield), it prints the model's internal rationale inside a code block. - Pretty-Printed Tool Calls: Formats all tool call argument dictionaries using
json.dumps(args, indent=2). - External Step Output (
output.txt): Reads the associated physical log file from.system_generated/steps/<step_index>/output.txt. Includes a duplicate check (preventing redundant printing if the output is already identical tocontent) and supports truncation via--lines / -l(default: 50 lines).
16. Specialized Subcommands: tools, commands, raw
Continuing the single-session audit suite, this module defines cmd_tools, cmd_commands, and cmd_raw.
Subcommand Overview:
cmd_tools: Invoked viaagy-brain-explorer.py <SESSION> toolsto generate the complete tool call audit table.cmd_commands: Invoked viaagy-brain-explorer.py <SESSION> commandsto list all shell executions.cmd_paths: Invoked viaagy-brain-explorer.py <SESSION> pathsto list all on-disk component locations with clickablefile://links.cmd_compare: Invoked viaagy-brain-explorer.py <SESSION> compare <OTHER_SESSION>to execute a differential comparison against another session.cmd_raw: Dumps the exact raw JSON record of any step index formatted with 2-space indentation. Features a--full / --compactswitch allowing users to compare the truncated record fromtranscript.jsonlwith the untruncated record intranscript_full.jsonl.
17. Intra-Session Search: cmd_session_search
When auditing a long trajectory (e.g. 292 steps), manually paging through timeline steps is time-consuming. Developers often need to know: "In which step did the agent run tests with node --test?" or "Where did the agent modify build-docs-site.js?"
cmd_session_search() implements scoped in-session searching across all conversation turns, model reasoning, and tool calls.
Session Search Mechanics:
- Usage:
uv run agy-brain-explorer.py <SESSION> search <QUERY>. - Transcript Flexibility: Defaults to searching
data.full_steps(via--full), with an optional--compactflag to search compact records. - Structured Excerpt Reporting: Evaluates each step against
step_matches_query(), printing a Markdown table with the exact step number, timestamp, step source (MODEL,USER_EXPLICIT), type, and matching excerpt. - Targeted Forensic Jumping: Once matching step numbers are discovered (e.g. Step 107), developers can immediately drill down with
agy-brain-explorer.py <SESSION> step 107to inspect complete parameters and outputs.
18. Unified CLI Dispatcher & Script Entrypoint
Typer natively expects a single application root. However, agy-brain-explorer.py supports two distinct interaction paradigms:
1) Trace Explorer Mode (discovering all sessions, executing global search, multi-session path listing, or side-by-side comparison via search, compare, paths), and
2) Session Inspection Mode (taking a session argument followed by subcommands like summary, paths, steps, step, tools, commands, compare, raw, or search).
This final section implements a smart CLI router (is_explorer_invocation() and main()) that seamlessly bridges both Typer applications into a unified binary.
Routing Mechanism & Multi-Mode Integration:
is_explorer_invocation(args):Parses command-line arguments, skipping option flags and their values (including
--query,-q,--search,-s). If no positional argument is found, or if the first positional argument matches an explorer keyword (list,explore,traces,search,compare,paths), it routes execution toexplorer_app.- Command & Search Routing Resolution:
- If invoked as
agy-brain-explorer.py compare <S1> <S2>oragy-brain-explorer.py paths <S1>..., it routes toexplorer_app. - If invoked as
agy-brain-explorer.py <SESSION> compare <S2>oragy-brain-explorer.py <SESSION> paths,<SESSION>is detected as the positional target, routing tosession_app. - If invoked as
agy-brain-explorer.py search <QUERY>, the argument is preserved and routed toexplorer_app'scmd_explorer_search(). - If invoked as
agy-brain-explorer.py <SESSION> search <QUERY>,<SESSION>routes tosession_app'scmd_session_search(). - If invoked with
-q <QUERY>or--query <QUERY>, it routes toexplorer_app's callback, executing prompt-filtered discovery.
- If invoked as
- Default Subcommand Injection: If in session mode and the user only specified a session ID (e.g.
agy-brain-explorer.py 4c6b51ee), it automatically injectssummarybefore delegating tosession_app(). - Standard Python Idiom: Guarded by
if __name__ == "__main__": main().