Conversation
The folder Index button runs a one-shot scan; persistent re-indexing requires registering the path under Sources. PR #575 unified the Index tab modes but left this difference silent — users who wanted automatic re-indexing had no in-panel cue that they should look elsewhere. Add an inline hint at the top of the folder panel ("One-shot scan. For automatic re-indexing, use Sources → Add path."). The link element is split out as a sibling of the help text so the i18n updater (which overwrites textContent on every lang toggle) can't strip the click handler from a nested anchor. The Index success toast also gains a "Register as Source" action button that runs the same Sources-tab navigation helper, so the cue is reachable both before and after the scan. Co-Authored-By: Claude <[email protected]>
Make the Compose mode's `Target file` semantics visible in two places:
- Placeholder: previously the generic `path/to/memories.md`. Now
`~/.memtomem/memories/2026-04-30.md (leave blank for auto)` — the
default location backend code in `add_memory()` already uses, with
today's date computed at load time so the cue stays accurate.
- Add success toast: previously "Saved — N chunks indexed", agnostic to
where the content went. Now "Saved to ~/.memtomem/memories/…/file.md
— N chunks indexed", echoing the actual path returned by the API.
The placeholder is split into i18n prefix + `{date}` runtime + i18n
suffix to dodge the lang-toggle path: i18n.applyDOM rewrites
`data-i18n-placeholder` textContent on every switch and would otherwise
clobber a JS-templated value back to the raw `{date}` token. The input
keeps a static placeholder fallback (`~/.memtomem/memories/`) for the
sub-second window before settings-config.js's helper runs.
The toast path-tildify helper (`tildifyPath`) collapses the
host-specific `$HOME` prefix the server sends back to `~`. The browser
doesn't know `$HOME`, so the helper anchors on the `.memtomem/` segment
that backend write paths consistently use. Reused in #4.5a.
The deprecated `toast.saved_n_indexed` key is removed from both locales
(unused after this commit) and dropped from the i18n required-set test.
Co-Authored-By: Claude <[email protected]>
Upload silently writes to ~/.memtomem/uploads/, then on collision suffixes the destination filename with the existing file's mtime (system.py:862). Until now the success toast only said how many chunks were indexed; users had no way to see where the file actually landed, or that a rename had occurred. Add `path: str | None = None` to UploadFileResult and have the upload route echo the resolved `dest` (post-rename) so the client doesn't have to guess. The toast prefers the new path-aware key (`toast.upload_complete_with_path` — "Indexed N chunks → saved to ~/.memtomem/uploads/foo.md"), falling back to the count-only message if no path is present (e.g., all-error batch). The path-tildify helper introduced in the previous commit collapses $HOME to ~ for display. The schema change is purely additive (new optional field, default None), so existing callers and tests continue to work unchanged. Co-Authored-By: Claude <[email protected]>
The "provider/model · backend" chip in the header is the only place that surfaces the embedding pipeline and storage backend on every tab. Users debugging "why is search slow" or "why are embeddings cleared" have to recall that the matching settings live under Settings → Config and click through manually. Make the chip clickable: cursor changes on hover/focus, click + keyboard activation (Enter/Space) navigate to Settings tab and select the Config section. The tooltip now ends with "Open Embedding & Storage settings" (i18n'd) and an aria-label exposes the same hint to screen readers; both refresh on language toggle alongside the existing detail lines (provider/model/dim, backend). Co-Authored-By: Claude <[email protected]>
5 rows is enough to write a tag list, not enough to write the kind of freeform memo people actually paste into Compose. Lift `min-height` from 120 to 240 px (≈10 rows) so the textarea matches a real writing surface; users can still drag the resize handle in either direction. Co-Authored-By: Claude <[email protected]>
…579) The Extensions/max-chunk hint at the bottom of the folder panel is read as data (current config values), not as a callout that demands the user's attention. Inheriting the shared .config-hint background + border made it look heavier than the surrounding inputs. Override the styling for `#index-config-hint` only (the home and namespace hints — `#home-config-info`, `#ns-config-info` — keep their existing chrome) to a plain muted line, and add the ⓘ marker via CSS `::before` so it's single-source-of-truth in the stylesheet regardless of which writer populates `textContent`. Co-Authored-By: Claude <[email protected]>
"Target file" alone reads as if it could be a path on disk, on the filesystem, or a virtual id — the user has no anchor for what's being asked of them. Append "(save location)" / "(저장 위치)" to the label so the placeholder hint and saved-path toast (introduced earlier in this bundle) reinforce the same idea: this input controls where the memory is stored under ~/.memtomem/memories/. Markup unchanged — just an i18n string update in both locales. Co-Authored-By: Claude <[email protected]>
Several JS-owned dynamic strings populate via listeners — Compose placeholder (settings-config.js _refreshAddFilePlaceholder) and the header-chip aria-label / jump-hint title (_syncHeaderConfig) — read t() at the moment they run. settings-config.js's module-level fetchServerConfig() can race ahead of app.js's `await I18N.init()`, so those listeners can fire before the locale cache is populated and end up writing the raw i18n key (e.g. `index.add_file_placeholder_prefix`) to user-visible UI. Surfaced by the smoke for #579: the Compose placeholder showed `index.add_file_placeholder_prefix2026-04-30 index.add_file_placeholder_suffix` and the header chip's aria-label held `header.sys_info_jump_title` until the user toggled language. Have I18N.init() dispatch a single langchange event after the locale cache is filled. The same listeners then re-read t() with real translations and overwrite their stale raw-key state. The bumped query string on i18n.js (?v=2 → ?v=3) busts browser disk cache so the new init body actually loads. Co-Authored-By: Claude <[email protected]>
Smoke complete (Playwright)Manual smoke now done — found one regression, fixed in 699557f and pushed. Regression: raw i18n keys leaked at first paintAfter
Cause: Fix: have Smoke matrix (all passing after fix)
Note on PR scopeThis adds an 8th commit to a bundle the issue body specifies as 7 commits. The fix is wholly in service of the same 7 surfacing items and is needed for them to actually work as intended at first paint, so it lives here rather than as a separate PR. Squash merge still produces one release-notes line. |
Closes #579.
Summary
Bundles the 7 static-surfacing items from issue #579 into one PR — text/CSS/placeholder/cursor changes only, no policy decisions, no schema breaking. PR #575 unified the Index tab's 3 modes behind a segmented toggle but left several backend behaviors (one-shot vs persistent, where files land, what the Extensions hint means) silent. This bundle fills those gaps.
One commit per item so reviewers can step through; squash merge produces one release-notes line.
Commits
feat(web): Index folder panel — surface one-shot vs persistent— inline hint at the top of the folder panel ("One-shot scan. For automatic re-indexing, use Sources → Add path.") + matching action button on the success toast that navigates to Sources tab and focuses the Add path button.feat(web): Compose — surface target file— placeholder shows the actual default save location with today's date (~/.memtomem/memories/2026-04-30.md (leave blank for auto)); add success toast echoes the saved path. Removes deprecatedtoast.saved_n_indexedkey.feat(web): Upload — echo saved path in success toast— addspath: str | NonetoUploadFileResult(additive, default None — no breaking change), upload route returns the resolveddest(post-collision-rename), toast echoes it.feat(web): header sys-info chip jumps to Settings → Config—provider/model · backendchip becomes clickable (cursor + hover + focus-visible), Enter/Space activates, lands on Settings → Config.style(web): Compose textarea — double the default height—min-height: 120 → 240px.style(web): Index Extensions hint — drop callout chrome, add ⓘ glyph—#index-config-hintID-specific override stripping background/border/padding; ⓘ via CSS::before(single source of truth in stylesheet, regardless of writer). Other.config-hintusers (#home-config-info,#ns-config-info) untouched.copy(web): Compose target file label — clarify "save location"—Target File→Target file (save location)/대상 파일 (저장 위치).Risk handling
These were flagged before coding; addressed in the commits above.
<a>from a singledata-i18nparagraph. Commit 1 splits the hint into sibling<span>+<a>+<span>so the link element survives toggles.{date}token leak in the Compose placeholder. Commit 2 splits the i18n value into..._prefix+..._suffixstrings and removesdata-i18n-placeholderfrom the input — JS now owns the placeholder and refreshes it onlangchange. The{date}token never appears in user-visible text.$HOMEpaths the browser can't resolve). Commit 2 adds atildifyPath()helper that anchors on the well-known.memtomem/segment used by backend write code; commit 3 reuses it.#index-config-hintⓘ prefix SoT — moved to CSS::beforeso the marker is single-source-of-truth regardless of which writer populates the element.Test plan
Automated (passing):
uv run ruff check packages/memtomem/src+ruff format --check— cleanuv run pytest -m "not ollama"— 3259 passedtests/test_i18n.py) — 12/12 passed; 6 new keys present in bothen.json+ko.json(index.folder_oneshot_hint/_link/_suffix,index.add_file_placeholder_prefix/_suffix,toast.action.register_persistent,toast.saved_to_file,toast.upload_complete_with_path,header.sys_info_jump_title); 1 updated (index.add_file_label); 1 removed and dropped from required-set (toast.saved_n_indexed)Manual (Index tab smoke —
uv run mm web):~/.memtomem/memories/{today}.md (leave blank for auto)with today's actual date (e.g.2026-04-30). Add success toast echoes the saved file path under~/.memtomem/memories/….~/.memtomem/uploads/…(or first non-error file's path).{date}token leak; folder hint link element still present and clickable; header chip's tooltip still includes the localized "Open Embedding & Storage settings" line.#index-config-hintis a plain muted line with leading ⓘ (no box/border/background); home/namespace hints unchanged.Out of scope (per #579)
🤖 Generated with Claude Code