Repository navigation
Commit d8b8946
authored
feat(databases)!: lineage walks the whole fork family (#288)
* feat(databases): lineage --tree walks the whole fork family
The lineage endpoint returns one ancestral path plus one generation of
direct forks, so a fork of a fork is invisible from its grandparent.
--tree assembles the full family client-side: walk down from root_id,
one lineage request per database — N+1, acceptable for the small fork
trees the feature targets — and render it with proper rail glyphs
(│/├─/└─), the queried database marked as before.
- the queried database's already-fetched lineage seeds the walk and is
reused, so its endpoint is hit exactly once
- a node whose own lineage can't be fetched (e.g. a deleted generation)
degrades to forks_unknown instead of aborting, and the known descent
toward the queried database is grafted so it always appears
- a visited-set guards against server-side cycles; per-node fork pages
keep the '⋯ N more — see --forks-limit' marker, applied per database
- -o json/yaml return {database_id, root_id, tree} with a recursive
node shape; forks_unknown / unlisted_forks appear only when set
- docs: skill synopsis + lineage bullet cover --tree
* fix(databases): don't show an ancestor's downstream fork edge as its own
Live verification surfaced the server's ancestor-entry semantics: each
ancestors[] entry carries the fork edge BELOW it — the snapshot of that
ancestor the next generation copied, and when — while forks[] entries
carry their own creation edge. The tree walk took the root's entry from
the ancestor chain verbatim, so the root row claimed a fork event it
never had ('— root, forked …, snapshot 0').
Shift the chain metadata one generation down so every tree row carries
its own creation edge (the forks-list convention), and strip it from
the top of the chain: a root has no fork event, and below a truncation
the edge above is unknown. As a bonus the grafted rows on the
deleted-generation path now show their true fork dates too.
Live-verified against production (create → fork → fork → lineage --tree
from every node → delete middle → --tree again → deleted): the walk
renders grandchildren, the server 404s lineage for deleted ids, and the
graft path keeps the queried database visible under the deleted
generation with '⋯ other forks unknown'.
* feat(databases)!: lineage always walks the whole fork family
Drop flat mode and the --tree flag: 'databases lineage' now renders the
full family tree by default. The tree is an informational superset of
the flat view — same ancestors (grafted even past deleted generations),
same direct forks with paging — plus every deeper generation, and it
displays each row's own creation edge instead of the server's
queried-database-relative ancestor annotations, which made the flat
view label the child row with the grandchild's fork date.
BREAKING: the -o json/yaml shape changes from
{ancestors, ancestors_truncated, forks, fork_count} to
{database_id, root_id, tree} with a recursive tree node. The flat shape
shipped in 0.29.0 (today); this is the cheapest moment to change it.
Trade-offs accepted: one request per database instead of one total
(fork families are small in practice), no atomic snapshot, and per-node
degradation ('⋯ forks unknown') instead of one all-or-nothing response.
ancestors_truncated is no longer carried: the walk detects truncation
structurally (the top of the ancestor chain won't match root_id).
Live-verified: create → fork → lineage renders the tree by default;
--tree is rejected; cleanup done.
* fix(databases): graft the descent past a paginated fork page too
The review caught a hole in the walk: descent was grafted only when a
node's lineage fetch FAILED, not when it succeeded with a truncated
fork page. A root with more forks than the page (server clamps to 100,
newest-first) could page out the very generation that leads to the
queried database — the tree then rendered without its '← this database'
row and exited 0, breaking the always-marked contract the skill doc
states.
Now the Ok arm grafts the known descent child whenever the listed page
didn't include it, counting it out of the unlisted tally. Regression
test: fork_count 3, page of 1, queried database off the page.
Also split the Err arm's diagnostics: a 404 stays quiet (the expected
shape of a deleted generation), while any other failure (auth, rate
limit, transport) still renders '⋯ forks unknown' but says why on
stderr, naming the id — so a failed request no longer masquerades as a
deleted-generation artifact.
---------
Co-authored-by: Eddie A Tejeda <669988+eddietejeda@users.noreply.github.com>1 parent 9867597 commit d8b8946
4 files changed
Lines changed: 573 additions & 88 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
149 | | - | |
| 149 | + | |
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
| 124 | + | |
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | | - | |
| 143 | + | |
144 | 144 | | |
145 | 145 | | |
146 | 146 | | |
| |||
0 commit comments