feat: add absorb command — merge source entity into target

DB: Absorb() merges body (newline-separated), unions tags, demotes
crystallized sources, soft-deletes source. Rejects crystallized targets.

API: POST /api/entities/:id/absorb { source_id }

CLI: nib absorb <target> <source> with prefix ID resolution

Web: absorb button on fluid entities, 'a' keyboard shortcut,
source picker modal
This commit is contained in:
2026-05-14 13:47:08 -04:00
parent 702caae1af
commit 7711240d68
9 changed files with 341 additions and 9 deletions
+4 -3
View File
@@ -10,9 +10,10 @@ import (
)
var (
ErrNotFound = errors.New("not_found")
ErrAlreadyPromoted = errors.New("invalid_promote")
ErrAlreadyFluid = errors.New("invalid_demote")
ErrNotFound = errors.New("not_found")
ErrAlreadyPromoted = errors.New("invalid_promote")
ErrAlreadyFluid = errors.New("invalid_demote")
ErrTargetCrystallized = errors.New("invalid_absorb")
)
type Store struct {