Skip to content

Commit 6157dc3

Browse files
authored
release: agf v0.14.0 (#77)
* feat: harden session discovery and add Prime Agent * fix: make Windows executable tests portable * test: use Windows-safe temporary paths * test: respect Windows timestamp resolution
1 parent 6f4c43e commit 6157dc3

33 files changed

Lines changed: 4292 additions & 1477 deletions

‎.github/workflows/ci.yml‎

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,24 @@ concurrency:
1212
cancel-in-progress: true
1313

1414
jobs:
15+
msrv:
16+
name: MSRV 1.88
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: dtolnay/rust-toolchain@1.88.0
21+
- uses: Swatinem/rust-cache@v2
22+
- run: cargo check --all-targets --all-features --locked
23+
24+
audit:
25+
name: Security audit
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
- uses: rustsec/audit-check@v2.0.0
30+
with:
31+
token: ${{ secrets.GITHUB_TOKEN }}
32+
1533
clippy:
1634
name: Clippy
1735
runs-on: ubuntu-latest
@@ -23,7 +41,7 @@ jobs:
2341
- uses: Swatinem/rust-cache@v2
2442
# --all-targets matches the local gate (lints tests too); clippy
2543
# subsumes cargo check, so there is no separate check job.
26-
- run: cargo clippy --all-targets --locked -- -D warnings
44+
- run: cargo clippy --all-targets --all-features --locked -- -D warnings
2745

2846
fmt:
2947
name: Format
@@ -42,7 +60,7 @@ jobs:
4260
- uses: actions/checkout@v4
4361
- uses: dtolnay/rust-toolchain@stable
4462
- uses: Swatinem/rust-cache@v2
45-
- run: cargo test --locked
63+
- run: cargo test --all-features --locked
4664

4765
windows:
4866
name: Windows
@@ -54,5 +72,5 @@ jobs:
5472
components: clippy
5573
- uses: Swatinem/rust-cache@v2
5674
# Lint here too so #[cfg(windows)]-gated code is covered.
57-
- run: cargo clippy --all-targets --locked -- -D warnings
58-
- run: cargo test --locked
75+
- run: cargo clippy --all-targets --all-features --locked -- -D warnings
76+
- run: cargo test --all-features --locked

‎.github/workflows/release.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ jobs:
3939
- target: x86_64-unknown-linux-gnu
4040
os: ubuntu-latest
4141
artifact: agf-x86_64-unknown-linux-gnu
42+
- target: aarch64-unknown-linux-gnu
43+
os: ubuntu-24.04-arm
44+
artifact: agf-aarch64-unknown-linux-gnu
4245
- target: x86_64-pc-windows-msvc
4346
os: windows-latest
4447
artifact: agf-x86_64-pc-windows-msvc
@@ -98,8 +101,8 @@ jobs:
98101
shopt -s nullglob
99102
files=(*/*.tar.gz */*.zip)
100103
# Keep in sync with the build matrix size.
101-
if [ "${#files[@]}" -ne 4 ]; then
102-
echo "expected 4 release archives, found ${#files[@]}: ${files[*]}" >&2
104+
if [ "${#files[@]}" -ne 5 ]; then
105+
echo "expected 5 release archives, found ${#files[@]}: ${files[*]}" >&2
103106
exit 1
104107
fi
105108
for f in "${files[@]}"; do

‎CHANGELOG.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,39 @@
22

33
## [Unreleased]
44

5+
## [0.14.0] - 2026-08-15
6+
7+
### Added
8+
9+
- **Prime Agent support** — discovers flat Prime Agent v3 JSONL sessions, resumes exact IDs with `prime-agent --resume`, honors environment/global session-root settings, and sorts by durable user/assistant activity. Named sessions, git state, and current recap metadata are surfaced. Deletion is fail-closed because upstream exposes no public safe delete command for active daemon sessions.
10+
- **Kiro v3 support** — discovers metadata/event pairs under `$KIRO_HOME/sessions/cli` in addition to the v2 SQLite store. Kiro resume now uses the selected conversation ID via `--resume-id`.
11+
- **Codex non-interactive filtering** — subagent and exec threads are hidden by default and can be included with `--include-non-interactive` or the matching setting.
12+
- Linux ARM64 release artifacts, an MSRV 1.88 CI lane, and a RustSec audit gate.
13+
14+
### Fixed
15+
16+
- Codex scans are now strictly read-only. Partial rollout walks can no longer delete valid rows from Codex-owned SQLite databases.
17+
- Cache invalidation uses nanosecond/size/path fingerprints, follows deeper Codex stores, and watches SQLite WAL files plus every secondary scanner input. Stale rows remain visible when a refresh fails and failed scans are never cached as successful emptiness.
18+
- Project View stores stable `(agent, session ID)` identities and rebuilds groups after streamed results, preventing wrong-session actions and out-of-bounds panics. `max_sessions` is now display-only and never truncates persistent cache data.
19+
- Time, name, and agent sorts use deterministic total ordering; timestamps are normalized globally and legacy Codex activity uses rollout mtime.
20+
- Exact quick-resume behavior: summary queries work, agent filters push down to one scanner, invalid permission modes fail clearly, and current Codex approval/sandbox flags replace removed aliases.
21+
- Terminal behavior: non-TTY TUI/watch calls fail cleanly, the session-row mouse offset is correct, shell wrappers preserve agent exit status, cwd-independent Hermes resumes execute, `NO_COLOR`/`TERM=dumb` are honored, and untrusted display metadata cannot emit terminal controls.
22+
- Deletes use collision-safe atomic writes and exact session matching; Claude append-only history is never rewritten while an agent may be writing it, Gemini duplicates are removed across stores, and Hermes prefix siblings survive.
23+
- Stats windows are cumulative and future/invalid timestamps are separate. Watch opens from cache immediately, preserves selection by identity, rejects zero intervals, and avoids repeated missing-`pgrep` probes.
24+
25+
### Performance
26+
27+
- Cursor store databases are indexed once instead of scanned once per transcript.
28+
- Pi, Cursor, Kiro, and Prime Agent JSONL parsing has total and per-line allocation bounds; Kiro v2 previews no longer materialize unlimited conversation blobs.
29+
- CLI commands reuse fresh per-agent cache entries and scan only stale/requested agents.
30+
- Text truncation is grapheme-aware, preserving emoji/ZWJ clusters while maintaining terminal-column alignment.
31+
32+
### Changed
33+
34+
- SuperLightTUI 0.20.1 → 0.22.3, including upstream terminal lifecycle, suspend/resume, bidi, and Unicode fixes.
35+
- Rusqlite is pinned to 0.39.0 so the declared Rust 1.88 MSRV remains buildable; the 0.40 transitive build script currently requires Rust 1.95 without declaring it.
36+
- Cache schema 8 → 9. Pin and summary state now use composite agent/session identities while legacy bare-ID pins remain readable.
37+
538
## [0.13.1] - 2026-07-31
639

740
Post-release audit of 0.13.0. No new features and no CLI changes; everything below is a correctness, durability, or performance fix found by reading the 0.13.0 diff and then the rest of the tree.

‎Cargo.lock‎

Lines changed: 24 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,33 @@
11
[package]
22
name = "agf"
3-
version = "0.13.1"
3+
version = "0.14.0"
44
edition = "2024"
55
# 1.88 = let-chains (edition 2024); also covers usize::is_multiple_of (1.87).
66
rust-version = "1.88"
7-
description = "Find and resume local AI coding-agent sessions across Claude Code, Codex, Gemini, Cursor CLI, OpenCode, Kiro, pi, Hermes, Oh My Pi, and Yolop"
7+
description = "Find and resume local AI coding-agent sessions across Claude Code, Codex, Prime Agent, Gemini, Cursor CLI, OpenCode, Kiro, pi, Hermes, Oh My Pi, and Yolop"
88
license = "MIT"
99
repository = "https://github.com/subinium/agf"
1010
keywords = ["tui", "cli", "agent", "session", "claude"]
1111
categories = ["command-line-utilities"]
1212
readme = "README.md"
1313

1414
[dependencies]
15-
superlighttui = "0.20"
15+
superlighttui = "0.22.3"
1616
serde = { version = "1", features = ["derive"] }
1717
serde_json = "1"
18-
rusqlite = { version = "0.40", features = ["bundled"] }
18+
# 0.40's libsqlite3-sys currently uses std::cfg_select! (Rust 1.95) without
19+
# declaring that MSRV. Keep the crate's tested Rust 1.88 floor honest.
20+
rusqlite = { version = "=0.39.0", features = ["bundled"] }
1921
nucleo = "0.5"
2022
clap = { version = "4", features = ["derive"] }
2123
thiserror = "2"
22-
anyhow = "1"
24+
anyhow = "1.0.103"
2325
dirs = "6"
2426
chrono = { version = "0.4", features = ["serde"] }
2527
walkdir = "2"
2628
rayon = "1"
2729
unicode-width = "0.2"
30+
unicode-segmentation = "1.12"
2831
toml = "1"
2932
sha2 = "0.10"
3033

‎README.md‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
> Find the AI coding session you meant to resume.
99
1010
`agf` is a local-first fuzzy finder for AI coding-agent sessions.
11-
Search local sessions across **Claude Code**, **Codex**, **Gemini CLI**, **Cursor CLI**, **OpenCode**, **Kiro**, **pi**, and **Hermes** — then resume the right one in a keystroke.
11+
Search local sessions across **Claude Code**, **Codex**, **Prime Agent**, **Gemini CLI**, **Cursor CLI**, **OpenCode**, **Kiro**, **pi**, and **Hermes** — then resume the right one in a keystroke.
1212

1313
![agf demo](./assets/demo.gif)
1414

@@ -45,10 +45,11 @@ Then you either dig through history files or start over.
4545
|:---|:---|:---|
4646
| [Claude Code](https://github.com/anthropics/claude-code) | `claude --resume <id>` | `~/.claude/history.jsonl` + `~/.claude/projects/` |
4747
| [Codex](https://github.com/openai/codex) | `codex resume <id>` | `~/.codex/sessions/**/*.jsonl` |
48+
| [Prime Agent](https://github.com/PrimeIntellect-ai/prime-agent) | `prime-agent --resume <id>` | `~/.prime/agent/sessions/<id>.jsonl` |
4849
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini --resume <id>` | `~/.gemini/tmp/<project>/chats/session-*.json` |
4950
| [Cursor CLI](https://cursor.com/docs/cli/overview) | `cursor-agent --resume <id>` | `~/.cursor/projects/*/agent-transcripts/<id>/<id>.jsonl` (Composer 2+)<br>`~/.cursor/projects/*/agent-transcripts/<id>.txt` (legacy) |
5051
| [OpenCode](https://github.com/opencode-ai/opencode) | `opencode -s <id>` | `~/.local/share/opencode/opencode.db` |
51-
| [Kiro](https://kiro.dev) | `kiro-cli chat --resume` *(no per-session resume — always opens the latest session for the cwd)* | `~/Library/Application Support/kiro-cli/data.sqlite3` |
52+
| [Kiro](https://kiro.dev) | `kiro-cli chat --resume-id <id>` | Kiro v2 SQLite + Kiro v3 `~/.kiro/sessions/cli/` |
5253
| [pi](https://github.com/badlogic/pi-mono) | `pi --session <id>` | `~/.pi/agent/sessions/<cwd>/*.jsonl` |
5354
| [Hermes](https://github.com/NousResearch/hermes-agent) | `hermes --resume <id>` *(cwd-independent — resumes in your current shell directory)* | `~/.hermes/state.db` |
5455
| [Oh My Pi](https://github.com/can1357/oh-my-pi) | `omp --resume <id>` | `~/.omp/agent/sessions/<cwd>/*.jsonl` |
@@ -61,10 +62,11 @@ Then you either dig through history files or start over.
6162
|:---|:---|:---|
6263
| Claude Code | JSONL | `~/.claude/history.jsonl` (sessions)<br>`~/.claude/projects/*/` (worktree detection) |
6364
| Codex | JSONL | `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl` |
65+
| Prime Agent | JSONL | `~/.prime/agent/sessions/<id>.jsonl` (also honors Prime Agent environment/global settings overrides) |
6466
| OpenCode | SQLite | `~/.local/share/opencode/opencode.db` |
6567
| pi | JSONL | `~/.pi/agent/sessions/--<encoded-cwd>--/<ts>_<id>.jsonl` |
6668
| Oh My Pi | JSONL | `~/.omp/agent/sessions/<encoded-cwd>/<ts>_<id>.jsonl` |
67-
| Kiro | SQLite | macOS: `~/Library/Application Support/kiro-cli/data.sqlite3`<br>Linux: `~/.local/share/kiro-cli/data.sqlite3` |
69+
| Kiro | SQLite + JSON/JSONL | v2: macOS `~/Library/Application Support/kiro-cli/data.sqlite3`, Linux `~/.local/share/kiro-cli/data.sqlite3`<br>v3: `$KIRO_HOME/sessions/cli/` or `~/.kiro/sessions/cli/` |
6870
| Cursor CLI | SQLite + JSONL/TXT | `~/.cursor/chats/<workspace>/<id>/store.db` (metadata; required for `.jsonl` to be resumable)<br>`~/.cursor/projects/*/agent-transcripts/<id>/<id>.jsonl` (Composer 2+ transcript)<br>`~/.cursor/projects/*/agent-transcripts/<id>.txt` (legacy transcript) |
6971
| Gemini | JSON | `~/.gemini/tmp/<project>/chats/session-<date>-<id>.json`<br>`<project>` is a named dir or SHA-256 hash of the project path<br>Project paths resolved via `~/.gemini/projects.json` |
7072
| Hermes | SQLite | `~/.hermes/state.db` (sessions + messages)<br>JSON dumps in `~/.hermes/sessions/session_<id>.json`<br>Hermes is cwd-independent — resume runs in your current shell directory |
@@ -143,13 +145,14 @@ sort_by = "time" # "time" | "name" | "agent"
143145
max_sessions = 200
144146
search_scope = "name_path" # "name_path" (default) | "all" (include summaries)
145147
summary_search_count = 5 # number of summaries included when search_scope = "all"
148+
include_non_interactive = false # show Codex subagent/exec threads
146149
```
147150

148151
You can also edit `search_scope` and `summary_search_count` interactively by pressing `?` in the TUI.
149152

150153
## Shell integration
151154

152-
`agf setup` auto-detects your shell and installs the wrapper. Supported shells:
155+
`agf setup` auto-detects your shell and installs the wrapper. Use `agf setup --shell powershell` (or another supported shell) when auto-detection is ambiguous.
153156

154157
- **zsh / bash** — appends to `~/.zshrc` or `~/.bashrc`
155158
- **fish** — writes to `~/.config/fish/config.fish`
@@ -170,7 +173,7 @@ See [CHANGELOG.md](CHANGELOG.md) for release notes.
170173
## Requirements
171174

172175
- macOS, Linux, or Windows (PowerShell 5.1+ / PowerShell 7+)
173-
- One or more of: `claude`, `codex`, `opencode`, `pi`, `kiro-cli`, `cursor-agent`, `gemini`, `hermes`, `omp`, `yolop`
176+
- One or more of: `claude`, `codex`, `prime-agent`, `opencode`, `pi`, `kiro-cli`, `cursor-agent`, `gemini`, `hermes`, `omp`, `yolop`
174177

175178
## Install from source
176179

@@ -185,6 +188,8 @@ agf setup
185188

186189
`agf` works best with agents that store resumable sessions locally.
187190

191+
Prime Agent session discovery and resume are supported, but deletion is intentionally disabled: Prime Agent has no public session-delete command and direct file deletion would bypass its active-daemon guard.
192+
188193
**Amp** is not supported yet because its sessions are stored remotely, which makes it hard to reliably resolve local project paths from session metadata. We are monitoring upstream changes and will add support when feasible.
189194

190195
## Built with

‎docs/adding-an-agent.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ Say the new agent is `Foo`, CLI `foo`, sessions under `~/.foo/sessions/`.
4040
- Bound reads on large transcripts with the shared `read_head_tail` / bounded-read
4141
helpers in `scanner/mod.rs`; never slurp multi-MB logs whole.
4242
- Skip malformed lines, don't panic on bad input.
43-
- Register the module in **`src/scanner/mod.rs`**: add `pub mod foo;` **and** a
44-
`thread::spawn(|| foo::scan().unwrap_or_default())` line in `scan_all()`
45-
*(plain `Vec` — the compiler won't remind you)*.
43+
- Register the module in **`src/scanner/mod.rs`**: add `pub mod foo;` and an
44+
`Agent::Foo => foo::scan()` arm in `scan_agent()`. Do not erase errors into
45+
empty success; stale cache rows are retained when a scanner fails.
4646

47-
4. **`src/cache.rs`** — add the `Agent::Foo => scanner::foo::scan().unwrap_or_default()`
48-
arm in `start_stale_scan()`. Bump `CACHE_VERSION` only if the cached payload
47+
4. **`src/cache.rs`** — no agent-specific dispatch is required; workers call the
48+
common `scanner::scan_agent()`. Ensure `Session` cache fields round-trip. Bump `CACHE_VERSION` only if the cached payload
4949
*shape* can change within a single released package version (a new agent key
5050
alone doesn't require it — the `agf_version` stamp forces a rescan on upgrade).
5151

@@ -69,14 +69,14 @@ Say the new agent is `Foo`, CLI `foo`, sessions under `~/.foo/sessions/`.
6969

7070
```bash
7171
cargo test --locked
72-
cargo clippy --locked --all-targets -- -D warnings
72+
cargo clippy --locked --all-targets --all-features -- -D warnings
7373
cargo fmt --all -- --check
7474
# Real-data smoke test (scans all agents regardless of install):
7575
AGF_DEBUG=1 cargo run -- list --agent foo --format json
7676
```
7777

78-
`agf list` runs every scanner unconditionally, so you can verify `foo` against a
79-
fixture `$HOME` without installing the CLI:
78+
An explicit `--agent foo` scans only Foo when its cache entry is stale, so you
79+
can verify it against a fixture `$HOME` without installing the other CLIs:
8080

8181
```bash
8282
HOME=/tmp/agf-fixture cargo run -- list --agent foo --format json

0 commit comments

Comments
 (0)