feat(tui): add search via capture bar and absorb flow

Search uses existing parse grammar ?prefix — type `?query #tag` in
capture bar to filter entities client-side. Substring match on
body+title+description with AND tag filtering. Esc clears search.

Absorb via m key on fluid entities — opens source picker showing all
other entities, enter merges source into target. Uses existing
store.Absorb() backend.
This commit is contained in:
2026-05-17 21:35:44 -04:00
parent ce335cabd6
commit 1066c0bc7d
10 changed files with 387 additions and 17 deletions
+28
View File
@@ -40,6 +40,15 @@ type entityDemotedMsg struct {
type entityCopiedMsg struct{}
type entityAbsorbedMsg struct {
targetID string
}
type absorbSourcesLoadedMsg struct {
targetID string
entities []*db.Entity
}
type tagsLoadedMsg struct {
tags []db.TagCount
}
@@ -207,3 +216,22 @@ func editInEditor(store *db.Store, e *db.Entity) tea.Cmd {
return editorFinishedMsg{nil}
})
}
func loadAbsorbSources(store *db.Store, targetID string) tea.Cmd {
return func() tea.Msg {
entities, err := store.List(db.DefaultListParams())
if err != nil {
return errMsg{err}
}
return absorbSourcesLoadedMsg{targetID, entities}
}
}
func absorbEntity(store *db.Store, targetID, sourceID string) tea.Cmd {
return func() tea.Msg {
if err := store.Absorb(targetID, sourceID); err != nil {
return errMsg{err}
}
return entityAbsorbedMsg{targetID}
}
}