Skip to content

feat(tui): add :bookmark/:bookmarks command and Shift+B picker - #5

Merged
Jacobcdsmith merged 1 commit into
mainfrom
claude/kairos-tui-v0.2-bookmarks
Aug 21, 2026
Merged

feat(tui): add :bookmark/:bookmarks command and Shift+B picker#5
Jacobcdsmith merged 1 commit into
mainfrom
claude/kairos-tui-v0.2-bookmarks

Conversation

@Jacobcdsmith

@Jacobcdsmith Jacobcdsmith commented Aug 19, 2026

Copy link
Copy Markdown
Owner

What does this change?

Implements Phase 3.2 ("Bookmarks & Quick Access") of the KAIROS TUI v0.2 improvement plan — a "SHOULD HAVE" deliverable from the original plan, picked up as the next self-contained chunk after Phase 1 (#3) merged.

  • :bookmark <name> saves the last successful command under a name. :bookmark --remove <name> deletes one. :bookmarks lists all of them. New src/kairos/services/bookmarks.py, persisted as a flat JSON array at .kairos/.bookmarks.json (unlike command history's append-only JSONL — bookmarks are a small, named, mutable set, so a whole-file read/write is the right model). Saving/removing a bookmark is a deliberate user action, so — unlike command history, which fails closed since it's passive/background — I/O errors here surface as a normal KairosError through the existing status-line path.
  • Shift+B opens a picker (BookmarkPickerScreen): Enter re-runs the highlighted bookmark's command, d removes it, Escape closes.
  • The tab bar shows the 3 most-recently-saved bookmarks, refreshed on every :bookmark/:bookmarks dispatch and loaded at startup (best-effort — a corrupt .bookmarks.json degrades to "no bookmarks shown" rather than crashing the app before the UI exists to report anything).
  • docs/tli.md and the in-app :help screen updated with the new commands/keybinding — and while I was in there, backfilled a few Phase-1 items that had been missing from docs/tli.md since the last PR (:ingest, :tutorial, Ctrl+G, persisted command history).

Also fixes a real pre-existing bug, found while wiring the picker's result handler: KairosApp.on_list_view_selected called MainScreen.refresh_from_state(None, new_state) on every Explorer selection, and refresh_from_state's old is None branch unconditionally re-appends the last activity entry to the Workspace transcript — so every single Explorer click/Enter was duplicating the previous command's entire result table into the transcript. Confirmed via a manual repro (line count grew by ~9 on each selection) before and after. Fixed by passing the real prior state instead of None; added a regression test.

No new dependencies; no changes to the :-command grammar's existing commands (:bookmark/:bookmarks are additive) or to provenance/layer logic.

Checklist

  • ruff format --check src tests passes
  • ruff check src tests passes
  • pyright passes with zero errors (repo-wide)
  • pytest passes, and I added/updated tests for the behavior change
  • I did not add a dependency on model inference, remote services, or anything in the non-goals list
  • I updated docs/cli.md and/or docs/architecture.md if this changes command behavior, schema, or provenance guarantees — n/a (TUI-only, no CLI/schema/provenance change); updated docs/tli.md (the TUI-specific doc) instead

How was this tested?

  • pytest -q (full suite, base + TUI extras) — 197 passed.
  • New tests/tui/test_bookmarks.py: persistence roundtrip (save/overwrite/remove/corrupt-file), :bookmark/:bookmarks/:bookmark --remove command-grammar dispatch, and Pilot-driven picker flows (open/run, open/cancel, open/remove-and-sync-tab-bar, tab bar caps at 3).
  • New regression test in tests/tui/test_app.py for the Explorer-selection transcript-duplication fix.
  • ruff check/ruff format --check/pyright clean on every touched file and repo-wide.

Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added persistent command history, bookmark saving, removal, listing, and rerunning.
    • Added a bookmark picker with recent-bookmark display, deletion, and keyboard navigation.
    • Added guided tutorial access, fuzzy artifact search, Explorer navigation, and evidence scrolling shortcuts.
    • Improved unknown-command assistance with ghost-text completion and contextual hints.
  • Documentation

    • Updated help content with history, bookmark commands, keybindings, and navigation guidance.
  • Bug Fixes

    • Prevented duplicate workspace transcript entries when selecting multiple Explorer items.

Phase 3.2 of the v0.2 improvement plan — bookmarks & quick access:

- `:bookmark <name>` saves the last successful command under a name;
  `:bookmark --remove <name>` deletes one; `:bookmarks` lists all of
  them. Backed by a new src/kairos/services/bookmarks.py, persisted as
  a flat JSON array at .kairos/.bookmarks.json. Unlike command history
  (which fails closed since it's passive/background), saving/removing
  a bookmark is a deliberate action, so I/O errors here surface as a
  normal KairosError through the existing status-line path.
- Shift+B opens a picker (BookmarkPickerScreen): Enter re-runs the
  highlighted bookmark's command, `d` removes it, Escape closes.
- The tab bar shows the 3 most-recently-saved bookmarks, refreshed on
  every :bookmark/:bookmarks dispatch and loaded at startup (best-effort
  — a corrupt .bookmarks.json degrades to "no bookmarks shown" rather
  than crashing the app before the UI can report anything).
- docs/tli.md and the in-app :help screen updated with the new
  commands/keybinding, and backfilled a few Phase-1 items that were
  missing from docs/tli.md (:ingest, :tutorial, Ctrl+G, persisted
  command history).

Also fixes a real pre-existing bug found while wiring the picker's
result handler: `on_list_view_selected` called
`MainScreen.refresh_from_state(None, new_state)` on every Explorer
selection, and `refresh_from_state`'s `old is None` branch
unconditionally re-appends the last activity entry to the Workspace
transcript — so every single Explorer click/Enter was duplicating the
previous command's entire result table into the transcript. Fixed by
passing the real prior state instead of `None`; added a regression
test (test_selecting_in_explorer_does_not_duplicate_workspace_transcript).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JoRVBGw6Ea7wd8d1ZDFKAx
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2085e4ec-3af1-4044-ac5c-b32b09493785

📥 Commits

Reviewing files that changed from the base of the PR and between e5076a0 and 1237294.

📒 Files selected for processing (14)
  • docs/tli.md
  • src/kairos/domain/errors.py
  • src/kairos/schemas/bookmark.py
  • src/kairos/services/bookmarks.py
  • src/kairos/tui/app.py
  • src/kairos/tui/commands.py
  • src/kairos/tui/controller.py
  • src/kairos/tui/screens/bookmark_picker.py
  • src/kairos/tui/screens/help.py
  • src/kairos/tui/state.py
  • src/kairos/tui/styles/kairos.tcss
  • src/kairos/tui/widgets/tab_bar.py
  • tests/tui/test_app.py
  • tests/tui/test_bookmarks.py

📝 Walkthrough

Walkthrough

The TLI adds JSON-backed bookmarks, bookmark commands, recent-bookmark state, a modal picker, bookmark tabs, expanded help, and regression coverage for persistence and TUI behavior.

Changes

TLI bookmark workflow

Layer / File(s) Summary
Bookmark storage and data contracts
src/kairos/schemas/bookmark.py, src/kairos/domain/errors.py, src/kairos/services/bookmarks.py, tests/tui/test_bookmarks.py
Bookmarks use BookmarkResult values and JSON storage in .kairos/.bookmarks.json. The service supports listing, saving, overwriting, and removing bookmarks with error handling.
Bookmark command handling
src/kairos/tui/state.py, src/kairos/tui/commands.py, src/kairos/tui/controller.py, tests/tui/test_bookmarks.py
The TUI recognizes bookmark and bookmarks, validates arguments, saves the last successful command, removes named bookmarks, lists bookmarks, and limits cached recent bookmarks to three.
Bookmark picker and TUI integration
src/kairos/tui/app.py, src/kairos/tui/screens/bookmark_picker.py, src/kairos/tui/widgets/tab_bar.py, src/kairos/tui/styles/kairos.tcss, tests/tui/test_app.py, tests/tui/test_bookmarks.py
The picker supports selection, cancellation, and deletion. Selected commands are dispatched for replay. Recent bookmarks appear in styled tabs, and selection refreshes avoid duplicate activity entries.
TLI command and keybinding documentation
docs/tli.md, src/kairos/tui/screens/help.py
Documentation covers ingestion, history, bookmarks, picker behavior, keybindings, and pane navigation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant KairosApp
  participant BookmarkPickerScreen
  participant TuiController
  User->>KairosApp: Open bookmark picker
  KairosApp->>BookmarkPickerScreen: Display saved bookmarks
  User->>BookmarkPickerScreen: Select bookmark
  BookmarkPickerScreen-->>KairosApp: Return saved command
  KairosApp->>TuiController: Dispatch command
  TuiController->>TuiController: Update bookmark and activity state
Loading

Suggested reviewers: claude

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/kairos-tui-v0.2-bookmarks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Jacobcdsmith
Jacobcdsmith marked this pull request as ready for review August 21, 2026 18:20
Copilot AI lite review requested due to automatic review settings August 21, 2026 18:20
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Jacobcdsmith
Jacobcdsmith merged commit c80b251 into main Aug 21, 2026
1 of 2 checks passed
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.

3 participants