Skip to content

mjacobs/agy-reader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agy-reader

A Unix-style Go CLI that extracts decrypted transcripts from Google Antigravity CLI sessions by talking to the local language-server daemon Antigravity runs while agy is active. Encrypted conversation .pb session files live under ~/.gemini/antigravity-cli/conversations/; agy-reader fetches the decrypted JSON from the daemon, renders Markdown for humans, and writes a <uuid>.trajectory.json sidecar next to each .pb file for downstream tools.

By default, the daemon binds a different ephemeral port each agy session. agy-reader automatically discovers this port on the fly (via the session log files), meaning no manual configuration is required on the happy path.

Why

The sister project agentsview is a local web viewer for AI agent sessions. It can list Antigravity CLI sessions but cannot render assistant turns because they're AES-GCM encrypted at rest. agy-reader fills that gap by producing a plain JSON sidecar that agentsview will detect and parse.

Integration contract is the file format. No imports, no protocol, no coupling — just <uuid>.trajectory.json sitting next to <uuid>.pb.

Features

  • Port auto-discovery: parses cli.log to discover and verify the daemon's ephemeral HTTP port; no manual configuration on the happy path.
  • Rich transcript formatting: renders CodeAction steps as git-style diffs and converts file URI paths into clickable local links so you can jump into your IDE.
  • Sidecar contract with agentsview: every render also writes <uuid>.trajectory.json next to the source .pb for downstream tools to pick up.

Install

go install github.com/mjacobs/agy-reader/cmd/agy-reader@latest

This drops agy-reader into $(go env GOBIN) (or $(go env GOPATH)/bin); make sure that directory is on your PATH.

To build from a local checkout instead:

go build ./cmd/agy-reader

Quick start

List syncable conversation sessions (does not contact the daemon):

agy-reader --list

Antigravity also writes background implicit/ trajectory files. They are not ordinary chat transcripts and are not syncable through the current daemon API, so they are hidden by default. To inspect them while debugging:

agy-reader --list --include-implicit

Pick a cascade id from that list and render it to stdout as Markdown:

agy-reader <cascade-id>

Render and save:

agy-reader --format md  --out transcript.md  <cascade-id>
agy-reader --format json --out trajectory.json <cascade-id>

Sync the sidecar without printing anything (for agentsview consumption):

agy-reader --sync <cascade-id>

Even in the default (Markdown) mode, agy-reader writes the sidecar <uuid>.trajectory.json next to the source .pb whenever it can — that's the point of the contract.

Sidecar contract for agentsview

For every syncable ~/.gemini/antigravity-cli/conversations/<uuid>.pb, agy-reader writes <uuid>.trajectory.json in the same directory. The contents are the raw GetCascadeTrajectory response from the Antigravity daemon — no schema invented on top. agentsview is expected to ignore unknown step types and use metadata.createdAt for timestamps.

Watch mode

agy-reader --watch                       # 30s interval (default)
agy-reader --watch --watch-interval=10s  # custom interval

Polls the session root, fetches a trajectory for any conversations/*.pb whose sidecar is missing or older than the .pb file, and writes the sidecar atomically. Daemon errors are non-fatal — connection-refused logs once per failure streak and the loop retries on the next tick. SIGINT or SIGTERM drains in-flight work and exits cleanly.

Troubleshooting

Auto-discovery failed and ANTIGRAVITY_DAEMON_URL is not set

By default, agy-reader scans cli.log inside the session root directory (~/.gemini/antigravity-cli/ or $ANTIGRAVITY_CLI_ROOT) to locate the active HTTP port.

If the log file is missing, empty, or the server is unresponsive, auto-discovery will fail. You can troubleshoot by:

  1. Ensuring agy is running, as the daemon is only active during an active session.
  2. Manually overriding the port if necessary. Find the port using:
    ss -tlnp 2>/dev/null | grep agy            # Linux
    lsof -iTCP -sTCP:LISTEN -anP | grep agy    # macOS
    The HTTP JSON-RPC endpoint is typically the lower-numbered port. Export it manually:
    export ANTIGRAVITY_DAEMON_URL=http://127.0.0.1:<port>

connection refused

The daemon only listens while agy (Antigravity CLI) is running, and the port changes each time agy restarts. Ensure agy is running. If you are manually specifying ANTIGRAVITY_DAEMON_URL, remember to update the port to match the new session.

daemon error 5xx or unknown cascade id

The daemon only knows about sessions it has loaded. Calling LoadTrajectory first (which agy-reader does automatically) usually solves this, but the daemon will refuse if the session truly doesn't exist or its key is unavailable. The current daemon LoadTrajectory request accepts only a cascade ID and resolves it under conversations/; implicit/ files are hidden by default and are not synced by watch mode. Use --list --include-implicit only when debugging those unsupported background traces.

no sessions found

Set ANTIGRAVITY_CLI_ROOT if your sessions are not at the default ~/.gemini/antigravity-cli.

Configuration

Env var Purpose Default
ANTIGRAVITY_DAEMON_URL Daemon base URL override (optional, auto-detected by default) unset (optional fallback)
ANTIGRAVITY_CLI_ROOT Override session root dir ~/.gemini/antigravity-cli
AGY_READER_LIVE Enable live daemon smoke test unset (test skips)
AGY_READER_TEST_UUID Cascade id to use in the live test unset

Running on a schedule

agy-reader does not ship a daemon installer. --watch is a long-running loop, so use whatever process manager you already use to keep it alive — the examples below are starting points, not installation instructions.

systemd (user service, Linux)

~/.config/systemd/user/agy-reader.service:

[Unit]
Description=agy-reader sync loop
After=default.target

[Service]
Type=simple
ExecStart=%h/.local/bin/agy-reader --watch
Restart=on-failure
RestartSec=30

[Install]
WantedBy=default.target

Enable with systemctl --user enable --now agy-reader.

launchd (macOS)

~/Library/LaunchAgents/dev.mjacobs.agy-reader.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
        "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>dev.mjacobs.agy-reader</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/local/bin/agy-reader</string>
            <string>--watch</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>/tmp/agy-reader.out</string>
        <key>StandardErrorPath</key>
        <string>/tmp/agy-reader.err</string>
    </dict>
</plist>

Load with launchctl load -w ~/Library/LaunchAgents/dev.mjacobs.agy-reader.plist.

Testing

go test ./...

The daemon smoke test is gated. To exercise it against a live agy:

AGY_READER_LIVE=1 AGY_READER_TEST_UUID=<some-cascade-id> go test ./internal/daemon

Status

Active development. Currently supports:

  • Automatic daemon port discovery via cli.log.
  • Single-shot fetch and render.
  • Continuous polling sync via --watch.
  • Interactive formatting (clickable file links, code diffs, clean text layouts).

Offline decryption (direct binary RE) is planned as a future goal.

License

MIT

About

tools for antigravity-cli (agy) transcripts

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors