← Context/ plans

Augment from DB Β· Phase 3 β€” the search-and-add remote: editable term, provider palette, one-click add

Launched from any πŸ” on the org card: an always-editable term bar, a provider palette, one-click add back to the launching list.

Spec reference

Implements Phase 3 of Augment From DB Flow. Scaffold template: apps/org-workbench (Phase 2). Branch: rebuild/turbo-rsbuild.

One robustness decision beyond the spec (D2 refinement): the augment-it:search-request CustomEvent alone is racy β€” if search-and-add isn't mounted when the πŸ” is clicked (its pairing opens via augment-it:navigate, and the federation import is async), the event is gone before the listener exists. The launch envelope therefore ALSO persists to localStorage['augment-it:search-request'] (the repo's established cross-remount pattern β€” active-flow, active-record-set, session-token all live there); search-and-add reads it on mount and listens for live events thereafter. Same-origin remotes share localStorage, no shared federation memory needed.

Steps

  1. Scaffold apps/search-and-add/ (:3016) β€” same shape as org-workbench; federation name searchAndAdd, saa-* CSS prefix.

  2. Lib β€” types.ts (SearchRequestDetail mirror, ConnectorResult, ConnectorInfo); search-client.ts (wrappers: search.fire, connectors.inventory, and the five add verbs β€” org links/streams/corpus, person links/corpus); search-context.svelte.ts ($state singleton: current request from localStorage-then-events).

  3. Components β€” TermBar.svelte (the standing constraint: term always visible, always editable, Enter/Search re-fires); ProviderPalette.svelte (chips from connectors.inventory: short_label + cost-tier styling, needs-env/disabled rendered dark and unclickable, SearXNG preselected, "auto" chip = registry default); ResultRow.svelte (title/host/snippet/date, one βž• routed by entity+target, per-row "added βœ“" / localized error); ResultsList.svelte; App.svelte (context banner "Adding to: Β· ", auto-fire once when a fresh request arrives β€” searches are reads, the gating thesis governs writes; every add dispatches augment-it:entity-updated).

  4. Verb routing — org: links→organization.links.add, streams→organization.streams.add, corpus→organization.corpus.add; person: links→person.links.add, corpus→person.corpus.add (persons have no streams — target disabled for person entities).

  5. org-workbench πŸ” β€” AdditiveList gains an optional onsearch prop; OrgCard supplies per-target seed terms (links: "<name>" LinkedIn Β· streams: "<name>" blog Β· corpus: "<name>" news β€” hardcoded v1 per spec open question); a shared requestSearch() helper writes localStorage + dispatches augment-it:search-request + augment-it:navigate {remoteId:'searchAndAdd'}.

  6. Shell β€” SEARCH_AND_ADD_REMOTE in EXTRA_REMOTES; PAIRINGS += {key:'orgWorkbench+searchAndAdd', left:'orgWorkbench', right:'searchAndAdd', defaultLeftPct:55}; federation map line (:3016). Appended LAST so PAIRINGS[0] (the default pair) is unchanged.

  7. Verify β€” svelte-check + build both apps + shell build; dev-server smoke :3016/remoteEntry.js; search.fire regression via the Phase 1 proof; verb-routing unit sanity is svelte-check-level (the verbs themselves were proven in Phases 1–2). Browser walk-through (πŸ” β†’ pairing opens β†’ edit term β†’ swap provider β†’ βž• β†’ card refreshes) is the operator's check.

  8. Changelog, commit + push as attempt(augment-from-db, search-and-add, step3):.

Out of scope

People reveal / person-shaped πŸ” dispatch (Phase 4 β€” the person routing in step 4 is wired but nothing dispatches person entities yet), stream scanning (Phase 5), fire-log persistence (spec open question β€” ephemeral v1).