feat(ui): author provenance classes, type backfill, and hygiene batch - #325
Merged
Conversation
Author is now a provenance CLASS, not a third taxonomy: 'human' is stamped on UI-created memories (memory + document), everything else displays as Agent — data stays human/agent/null, the UI shows only Human/Agent, and null legacy rows read as Agent. The create chain finally carries metadata (and content_type/importance stop being dropped by the desktop remember command); the Milkdown wrapper fixes silent no-ops (Codeblock→CodeMirror, ListItemBlock→ListItem, top-level placeholder moved into the feature config) per the actual 7.22 typings. Also: type backfill tool in Settings → Maintenance (scans for empty content_type, stamps 'text' via PUT /memory), pinned memories float to the top of the browsed list, explicit New-namespace action (seed placeholder + auto-select), CodeMirror theme follows live theme flips via var() instead of boot-time snapshots, svelte-check baseline fixed to 0 errors (Crepe typings, ConfirmDialog messages, fadeQuick params, namespace: null), and GitHub's standard Dependency Review workflow.
🔍 Cora AI Code Review✅ No issues found. Code looks good! Review powered by cora-code · BYOK · MIT |
Cora (critical): the duplicate pre-check used utekeServer.remember, which INSERTS — every save created a second copy, and editing left a stray copy of the edited content. The create path now dup-checks via read-only recall (0.92 threshold, unchanged) and inserts exactly once; the edit path skips the check entirely. dependency-review is marked continue-on-error until the repo's dependency graph is enabled in settings (owner action).
Cora: the web-routes memory_update handler never mapped p.contentType into the PUT /memory body, so web-mode type backfill would silently no-op while desktop worked.
Cora: the create path discarded the editor's type/importance selections (uteke_remember had no such params; the Rust remember command explicitly ignored them), producing exactly the untyped rows TypeBackfill later repairs. The create chain now carries memory_type + importance end-to-end, the editor select uses uteke's memory_type vocabulary consistently (fact default), and the detail panel shows memory_type.
The compat banner was a thin strip that other content buried. It is now a dismissible dialog on first launch per required-minimum version (persisted), listing each gated feature with its version requirement. Memory cards now show the author badge before the pin badge.
…Type, no null-wipe in web updates - Desktop MemoryEntry mappings now carry metadata (badges read metadata.author; previously always Agent on desktop) - ipc remember sends memoryType (Tauri 2 maps camelCase → snake_case); a snake_case key never matched the Rust arg - web memory_update drops absent fields like the desktop command — explicit nulls were wiping content/tags/metadata server-side during TypeBackfill (data-destroying) - uteke_client UtekeMemory parses metadata
…ming a clean scan
uteke_remember re-checks duplicates server-side and can return
{duplicate: true} without inserting — the create path treated any
resolution as success, so the fallback was skipped and onsave fired on
a phantom save. The verdict now routes into the duplicate warning.
WebKit draws native select text smaller than the surrounding inputs; drop the native chrome (appearance: none + custom caret) so the Type select matches the tags/namespace fields.
…ew docs Clicking Properties used to reveal the fields ABOVE the button. The trigger now sits above the row it expands (chevron flips with state), and new documents always show title/slug/tags + Parent — slug is required, so it never hides behind the toggle.
The standalone Parent row wasted a full-width gutter with the select on the left and dead space to the right. The picker now lives in the top-bar between the breadcrumb and the mode toggle (new docs only), so the editor content shifts up and the whole creation form fits in one compact header stack.
The Rooms hub group was decorative: selectedRoom toggled but never scoped anything (tooltip even admitted it). Clicking a room now loads its memories from the server (GET /room/memories with /room/recall fallback), shows them in the main list with tag filter + pinned-first applied, and toggling off restores the full list. Rooms also display their memory_count, and the pager load-more is suppressed while a room scope is active.
… the toolbar
The hub's Namespaces group and the toolbar NamespaceFilter drove the
same selectedNamespaces state, so switching hub tabs or clicking
namespaces fought with the toolbar ('None' filter + unscoped-looking
list). The hub is now a standalone Rooms | Tags facet browser (global
counts, not influenced by the toolbar), and namespace filtering is
purely the toolbar's job. The toolbar also aligns flush with the cards'
right edge (12px inset + 10px scrollbar).
Per owner UX direction: the hub keeps all three tabs (Namespaces | Rooms | Tags) and every entry drives ONE namespace scope (selectedNamespaces) that the toolbar dropdown renders — clicking a namespace filters to it alone, and clicking a room scopes the list to the room's own namespace. The separate roomItems bypass is gone, so the list, the dropdown, and the sidebar can no longer disagree.
…space The previous iteration scoped the list to the room's whole namespace, which showed more rows than the room contained. Room click now loads the room's own memories (GET /room/memories + fallback), keeps the namespace filter synced to the room's namespace for context, and any manual toolbar filter change drops the room scope so the two controls stay coherent.
… and chips - Namespace counts use the active/deprecated breakdown so the sidebar number matches what clicking shows (6 total vs 2 active was the confusing mismatch) - 'All namespaces' entry on top of the list; clicking the active namespace/room/tag again returns to all - Chips row removed — the sidebar highlight already shows the selection - Toolbar NamespaceFilter removed (namespace scoping is the hub's job)
The group switch + filter input scrolled away with long lists, forcing a scroll back up just to switch facets. The panel is now a fixed header (hub-head) over a scrollable list area (hub-list).
- The memory/isolated/connection legend hugged the canvas edge; give it real padding and wider item gaps. - settle() iterations now scale inversely with node count (80..260) so large graphs stay inside a one-shot sync budget instead of a long freeze, while small graphs keep a thorough layout. All load paths already route through it — no continuous motion remains.
| <div class="meta-row"> | ||
| <span class="meta-label">Type</span> | ||
| <span>{memory.content_type}</span> | ||
| <span>{memory.memory_type ?? memory.content_type ?? '—'}</span> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Batch of UX fixes and features from hands-on testing of develop (web + desktop). Implements a destination-based navigation model for the Memories hub, real namespace/room scoping, provenance classes (Human/Agent), a type backfill tool, platform-aware shortcuts, documents improvements, and overlay/theming fixes. Also bumps the version to 0.4.0 with a full CHANGELOG entry.
Why
Hands-on dogfooding surfaced structural UX problems: the namespace filter existed in two places that fought over one state, room clicks did nothing, the namespace manager rendered an empty table (a Tauri command was never implemented), shortcut labels ignored macOS, and several overlays layered incorrectly.
How
all/namespace: X/room: X/tag: Y) drives the list, chips, and load-more; the sidebar navigates, the content reflects. No parallel filter states left to fight.utils/author.ts: UI-created memories/documents stampauthor: 'human'; everything else renders as Agent. Create chain carries metadata/content_type/importance at every layer (desktop command no longer drops them).uteke_namespaces_breakdowncommand (raw pass-through ofGET /namespaces?with_counts=true).utils/platform.ts(isApple,MOD_LABEL,kbdCombo,hasMod) + tests.Testing
cargo fmt --all -- --checkpassescargo clippy -- -D warningspassescargo testpasses (18/18)npx svelte-check --tsconfig ./tsconfig.json— 0 errors (also fixes the 12 pre-existing baseline errors from develop)npm run test -- --runpasses (95/95, incl. new platform + activity tests)npm run buildsucceeds