Skip to content

feat(cli): show view hierarchy and hide empty views in view list - #194

Merged
geekgonecrazy merged 3 commits into
devfrom
feat/view-list-hierarchy
Sep 17, 2026
Merged

geekgonecrazy merged 3 commits into
devfrom
feat/view-list-hierarchy

Conversation

@geekgonecrazy

Copy link
Copy Markdown
Contributor

What

atomic view list now renders views as an indented hierarchy following parent chains, and hides views with no changes of their own to keep the listing focused on active work.

$ atomic view list
dev            [shared]    (0 changes)  state: AAAAAAAAAAAA
  - main           [draft]     (2 changes, 0 inherited)  state: UO3DIU5T2YST  parent: main
    - * baby-bird-123  [draft]     (1 change, 2 inherited)  state: LIFWWSNAYWAX

2 views not shown because contained no changes. -a to view them.

Details

  • Hierarchy: a view with a parent renders as - name indented two spaces per level beneath its parent; roots at column 0; roots/siblings sorted alphabetically. The * current-view marker is preserved on its line.
  • Empty-view filter: a view is hidden iff it has zero own changes (own_change_count) and no shown descendant and it is not the current view. Ancestors of shown views are pulled in so the hierarchy stays connected; the current view is always shown.
  • Summary line: hidden views are counted in a trailing N view(s) not shown because contained no changes. -a to view them. line.
  • -a/--all: disables the filter; hierarchy layout applies in both default and --short modes.
  • Rendering lives in pure helpers (compute_visibility, tree_order, render_line, summary_line) with cycle-safe parent walking (visited set + leftover sweep, covered by tests).
  • --remote listing is intentionally unchanged (server-composed inventory, different change-count semantics).
  • Vault records for this work (intent + attested memories) are included per repo practice.

Testing

  • cargo test -p atomic-cli: 1863 passed, 0 failed (13 new tests covering tree layout, filtering, summary counts, -a, current-view exemption, missing-parent and parent-cycle safety).
  • cargo clippy -p atomic-cli clean; cargo fmt applied.
  • Verified end-to-end against a real repo with a 4-deep chain.

@geekgonecrazy
geekgonecrazy merged commit 58617a6 into dev Sep 17, 2026
8 checks passed
@geekgonecrazy
geekgonecrazy deleted the feat/view-list-hierarchy branch September 17, 2026 18:06
geekgonecrazy added a commit that referenced this pull request Oct 8, 2026
The #194 tree renderer only covered the local path; when a service
session is active, view list went through the RPC path's flat renderer
(no hierarchy, no counts, no state, no empty-view hiding). Map the wire
ViewInfo into ViewEntry and reuse compute_visibility/tree_order/
render_line so both paths render identically. -s and -a are now
honored over RPC too.
geekgonecrazy added a commit that referenced this pull request Oct 8, 2026
* fix(cli): render view list hierarchy over RPC

The #194 tree renderer only covered the local path; when a service
session is active, view list went through the RPC path's flat renderer
(no hierarchy, no counts, no state, no empty-view hiding). Map the wire
ViewInfo into ViewEntry and reuse compute_visibility/tree_order/
render_line so both paths render identically. -s and -a are now
honored over RPC too.

* fix(cli): restore pre-libatomic rendering for diff and log over RPC

Since #239 every command routes through the service area (local
in-process by default), and several bridges rendered thinner output
than the local code they replaced: diff printed bare patch text with
no headers/colors/stat-graph/name-status, and log dropped the styled
hash/author/date, the (tag) marker, entry separators, and the versioned
JSON document.

DiffChunk now carries the file status and the recorded/working-copy
contents (add-only wire fields, populated by both the working-copy and
view-pair arms), so the CLI rebuilds the same FileDiffs the local path
built and renders through the SAME formatters — print_unified,
print_stat (graph bars + summary), print_name_only, print_name_status,
the word-diff pairing, and the versioned JSON document. /dev/null sides
keep their bare form in headers. log maps the wire entries onto
JsonLogEntry and reuses format_hash_with_length/format_timestamp and
the output styles, including the (tag) marker and blank-line entry
separators.

* fix(daemon): give every redb open the cross-process grace period

The #230 merged-database discipline opens the store per operation, but
the provenance journal's opens (DirectJournalSink::store, the hook
path) and the daemon's change_store/repository accessors called redb
directly with no wait — a short-lived CLI/agent process holding
atomic.redb failed the hook's journal write on the first contested
open while repository opens rode out the hold.

- RedbChangeStore::open_existing_wait: bounded retry on
  DatabaseAlreadyOpen, other errors immediate — the same policy
  Repository::wait_for_database applies
- The open budget is now one shared, env-overridable knob:
  atomic_repository::database_lock_wait() (ATOMIC_DB_LOCK_WAIT_MS,
  30s default) — the hook-side budget wait_budget::database_wait()
  already used; libatomic's daemon opens delegate to it too
- RepoHandle::{repository,repository_readonly,change_store} and
  DirectJournalSink::store all wait; compact keeps its own retry loop
- Tests: held-handle-then-release succeeds; held-past-deadline returns
  busy in bounded time

* fix(test): format daemon/cli sources and pin contention budgets in tests

- cargo fmt over the rendering/grace-period changes (CI Format check)
- ordinary_read_timeout pins ATOMIC_DB_LOCK_WAIT_MS so the test
  measures the bound rather than the 30s default budget
- corruption-failure deadline raised for slow process startup on
  loaded machines (a contention wait would be 30s, so 20s still
  proves no wait happened)

* fix(identity): resolve the default store under ATOMIC_CONFIG_DIR

The intent-attest external-signer tests redirect the config area via
ATOMIC_CONFIG_DIR and fail on Windows with 'identity not found' —
dirs::home_dir() there resolves the profile known-folder, not HOME, so
env redirection never applied. Resolve the identity store the same way
atomic-config resolves config.toml (ATOMIC_CONFIG_DIR wins, then
~/.atomic), making the documented knob cover the whole config area.
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.

2 participants