Skip to content

release: v0.11.4 — pi/codex robustness + README clarity#47

Merged
subinium merged 1 commit into
mainfrom
release/0.11.4
May 29, 2026
Merged

release: v0.11.4 — pi/codex robustness + README clarity#47
subinium merged 1 commit into
mainfrom
release/0.11.4

Conversation

@subinium

Copy link
Copy Markdown
Owner

Surfaced by the v0.11.3 post-ship multi-angle audit (5 review angles, adversarial verification). Two real fixes matching patterns already shipped in v0.11.3 for the cursor scanner, plus two README clarifications and a tiny .gitignore hygiene fix.

Fixed

  • scanner/pi: a single invalid-UTF-8 line no longer drops the rest of the file (or the whole session)parse_session used reader.lines().map_while(Result::ok), which stops at the first Err and silently truncates every prompt summary that follows. Worse, when the bad line lands before the session header (a real failure mode for crash-truncated or rotation-racing writes), the header is never captured and the entire session is dropped from agf list. Same bug class as the extract_first_prompt .ok()? regression we just fixed in v0.11.3 for the Cursor scanner. Replaced with let Ok(line) = line_result else { continue; }; so each bad line is skipped individually. (parse_session_skips_invalid_utf8_lines)
  • scanner/codex: ~/.codex/history.jsonl no longer scales with the user's lifetime codex usageread_history_summaries streamed the entire file, parsed every line into a HistoryEntry, and accumulated (f64, String) tuples for every session_id ever seen — including thousands of sessions with no rollout JSONL on disk. For power users running codex daily the file reaches tens of MB; v0.11.3's CACHE_VERSION=6 bump forces a cold rescan on every upgrader, which would otherwise pay this cost on first launch. The function now takes the same live_session_ids set already collected by collect_live_session_ids and short-circuits any line whose session_id is not in it. The legacy "keep everything" path is preserved when live_session_ids is None (transient I/O on the sessions tree), mirroring scan_sqlite's same-condition fallback so a flaky filesystem read can't wipe summaries from the listing. (read_history_summaries_pre_filters_against_live_session_ids, read_history_summaries_keeps_all_when_live_set_is_none)

Docs

  • README: Kiro row now surfaces "no per-session resume — always opens the latest session for the cwd"kiro-cli ignores session_id, so selecting a specific older Kiro entry in the TUI silently launches a different session. The caveat was previously only in Agent::Kiro::resume_cmd's inline comment; users actually read the top agents table.
  • README: Hermes row now surfaces "cwd-independent — resumes in your current shell directory" — documented in the expanded Full session storage paths section but missing from the discoverable top table.

Internal

  • .gitignore: /.claude/ added — every contributor running Claude Code locally was seeing ~/.claude/ show up as untracked in git status, with the latent risk of an accidental git add . committing a personal agent state directory.

Test plan

  • cargo fmt --all --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test53 passed (50 + 1 pi regression + 2 codex regression)
  • cargo build --release, installed locally, agf --version → 0.11.4
  • End-to-end: agf list --limit 1000 before and after upgrade returns identical counts across all agents (Claude 37, Codex 495, OpenCode 63, Gemini 2, Hermes 2). Codex summary text (Korean + English) preserved for the same sessions.
  • Diff scoped to 7 intended files

Surfaced by the v0.11.3 post-ship multi-angle audit. Two real fixes
matching patterns already shipped in v0.11.3 for the cursor scanner,
plus two README clarifications and a tiny .gitignore hygiene fix.

Fixed:
- scanner/pi: replace reader.lines().map_while(Result::ok) with
  let-Ok-else-continue. The map_while form silently truncates summaries
  on the first invalid-UTF-8 line; if the bad line lands before the
  session header (real crash-truncation / log-rotation race) the entire
  session is dropped from agf list. Same bug class as the cursor
  .ok()? fix shipped in v0.11.3. Regression test added.
- scanner/codex: pre-filter ~/.codex/history.jsonl against the
  live_session_ids set during the read instead of accumulating every
  historical entry. The file is append-only and reaches tens of MB for
  power users; the CACHE_VERSION=6 bump in v0.11.3 forces a cold rescan
  on every upgrader, which would otherwise pay this cost on first
  launch. Legacy 'keep everything' path preserved when the live set is
  None (transient I/O on the sessions tree), mirroring scan_sqlite's
  same-condition fallback. Two regression tests added.

Docs:
- README: Kiro row surfaces 'no per-session resume — always opens the
  latest session for the cwd' (previously buried in a model.rs comment;
  users picking an older Kiro entry silently got a different session).
- README: Hermes row surfaces 'cwd-independent — resumes in your
  current shell directory' (was only in the expanded paths section).

Internal:
- .gitignore: add /.claude/ so Claude Code's local agent state stops
  showing as untracked for every contributor.

Verified end-to-end: 599 sessions across all agents identical before
and after upgrade, codex summaries (Korean + English) preserved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@subinium subinium merged commit a3a58df into main May 29, 2026
5 checks passed
@subinium subinium deleted the release/0.11.4 branch May 29, 2026 02:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant