Skip to content

fix(memory-workspace): toast + Reveal Folder fallback for View Vault (#2281)#2289

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
obchain:fix/2281-view-vault-no-feedback
May 20, 2026
Merged

fix(memory-workspace): toast + Reveal Folder fallback for View Vault (#2281)#2289
senamakel merged 2 commits into
tinyhumansai:mainfrom
obchain:fix/2281-view-vault-no-feedback

Conversation

@obchain
Copy link
Copy Markdown
Contributor

@obchain obchain commented May 20, 2026

Summary

  • Wire a toast on every click of View Vault so users always see a result; surface the vault path in the toast.
  • Add a Reveal Folder fallback action so users without Obsidian still have an OS-native escape hatch to inspect the vault.
  • Add a revealPath helper (wraps tauri-plugin-opener's revealItemInDir) + opener:allow-reveal-item-in-dir capability so the renderer can drive a Finder/Explorer reveal.
  • 6 new Vitest cases cover the success-toast, reveal-fallback, error-toast, and reveal-error branches.

Problem

MemoryWorkspace.tsx View Vault sent obsidian://open?path=... through openUrl and relied on the host OS to launch Obsidian. When Obsidian is not installed, the OS shell (LaunchServices on macOS, xdg-open on Linux, ShellExecute on Windows) accepts the URL handoff but launches nothing. No toast, no error, no fallback — the button looks broken to non-technical users.

Solution

  • New revealPath(path) helper in app/src/utils/openUrl.ts wraps revealItemInDir from @tauri-apps/plugin-opener. No-op outside Tauri.
  • Capability app/src-tauri/capabilities/default.json adds opener:allow-reveal-item-in-dir.
  • MemoryWorkspace.tsx replaces the silent module helper with a handleViewVault callback. On click:
    • Try openUrl(obsidian://...).
    • On success: emit an info toast that names the vault path and exposes a Reveal Folder action.
    • On error: emit an error toast with the same Reveal Folder action.
    • Reveal Folder calls revealPath(content_root_abs); if that fails too, surface a final error toast with the underlying message.
  • New i18n keys (workspace.openingVault*, workspace.openVaultFailed*, workspace.revealFolder, workspace.revealVaultFailed) added to en.ts + en-3.ts, with English fallback into all 11 non-en -3 chunks so pnpm i18n:check exits 0.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — 6 new Vitest cases across MemoryWorkspace.test.tsx and openUrl.test.ts.
  • Diff coverage ≥ 80% — every new branch in handleViewVault and revealPath has a dedicated test.
  • Coverage matrix updated — N/A: behaviour-only fix for an existing UI affordance; no new feature row needed.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A: no matrix row affected.
  • No new external network dependencies introduced — no network calls added.
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: not on the release-cut surface list.
  • Linked issue closed via Closes #NNN in the ## Related section.

Impact

  • Runtime/platform: desktop (mac/win/linux). No mobile/web/CLI surfaces touched.
  • Performance: zero — a single extra toast emit + (optional, user-driven) revealItemInDir IPC call.
  • Security: new capability permission is read-only filesystem-reveal scoped to the host file manager; no path escape.
  • Migration / compatibility: backward-compatible. Existing obsidian:// deep-link behaviour preserved for users with Obsidian installed.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/2281-view-vault-no-feedback
  • Commit SHA: 964c122

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: pnpm test src/utils/openUrl.test.ts src/components/intelligence/__tests__/MemoryWorkspace.test.tsx (23/23 pass); full pnpm test (2880 pass, 3 skipped).
  • Rust fmt/check (if changed): N/A — no Rust changes.
  • Tauri fmt/check (if changed): N/A — Tauri capability JSON only.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Clicking View Vault now always emits a toast with the vault path and a Reveal Folder fallback, instead of silently no-op-ing when Obsidian is not installed.
  • User-visible effect: visible toast + working fallback on every click.

Parity Contract

  • Legacy behavior preserved: obsidian:// deep link still dispatched first; users with Obsidian installed see Obsidian launch as before.
  • Guard/fallback/dispatch parity checks: openUrl reject path still propagates non-http scheme errors; new error branch in handleViewVault surfaces those as user-facing toasts.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): None.
  • Canonical PR: This PR.
  • Resolution (closed/superseded/updated): N/A.

Summary by CodeRabbit

  • New Features

    • Users can now open Obsidian vaults directly from the MemoryWorkspace with improved error handling.
    • Added "Reveal Folder" action to vault operations for quick file system access when issues occur.
    • Enhanced feedback with toast notifications for success and failure states.
  • Documentation

    • Added translations for vault-opening workflows in 12+ languages.

Review Change Stack

obchain added 2 commits May 20, 2026 12:01
Wrap tauri-plugin-opener's revealItemInDir so callers can drive a
guaranteed-works folder reveal in the host OS (Finder, Explorer,
xdg-open) when a third-party deep link (e.g. obsidian://) may
silently no-op because the target app isn't installed. Capability
allowlist adds opener:allow-reveal-item-in-dir.
…inyhumansai#2281)

Clicking View Vault used to call openUrl('obsidian://...') and rely
entirely on the OS to launch Obsidian. When Obsidian isn't installed
the shell silently accepts the URL and does nothing, so the button
feels broken. Surface a toast on every click that names the vault
path AND offers a Reveal Folder action that opens the vault directory
in the host file manager via the new revealPath helper. Error path
swaps the info toast for an error toast with the same fallback.

Closes tinyhumansai#2281.
@obchain obchain requested a review from a team May 20, 2026 06:39
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ba97b893-9a53-4ed6-9843-2d59e3b363b5

📥 Commits

Reviewing files that changed from the base of the PR and between 65d92bf and 964c122.

📒 Files selected for processing (18)
  • app/src-tauri/capabilities/default.json
  • app/src/components/intelligence/MemoryWorkspace.tsx
  • app/src/components/intelligence/__tests__/MemoryWorkspace.test.tsx
  • app/src/lib/i18n/chunks/ar-3.ts
  • app/src/lib/i18n/chunks/bn-3.ts
  • app/src/lib/i18n/chunks/en-3.ts
  • app/src/lib/i18n/chunks/es-3.ts
  • app/src/lib/i18n/chunks/fr-3.ts
  • app/src/lib/i18n/chunks/hi-3.ts
  • app/src/lib/i18n/chunks/id-3.ts
  • app/src/lib/i18n/chunks/it-3.ts
  • app/src/lib/i18n/chunks/ko-3.ts
  • app/src/lib/i18n/chunks/pt-3.ts
  • app/src/lib/i18n/chunks/ru-3.ts
  • app/src/lib/i18n/chunks/zh-CN-3.ts
  • app/src/lib/i18n/en.ts
  • app/src/utils/openUrl.test.ts
  • app/src/utils/openUrl.ts

📝 Walkthrough

Walkthrough

This PR implements the "View Vault" button in Memory tree UI by adding Obsidian vault opening with comprehensive error handling and a fallback reveal action. It introduces a new revealPath utility to expose vault folders in the OS file manager, wires it into the MemoryWorkspace component, adds proper toast feedback for success and error cases, and provides localized UI strings across 13 languages.

Changes

View Vault Feature

Layer / File(s) Summary
Tauri capability and revealPath utility
app/src-tauri/capabilities/default.json, app/src/utils/openUrl.ts, app/src/utils/openUrl.test.ts
Adds Tauri opener:allow-reveal-item-in-dir permission and new revealPath(path) function that uses Tauri's opener plugin to reveal filesystem paths in the OS file manager with no-op behavior outside Tauri contexts. Tests verify Tauri dispatch, browser no-op, and error propagation.
MemoryWorkspace vault opening with toast feedback
app/src/components/intelligence/MemoryWorkspace.tsx, app/src/components/intelligence/__tests__/MemoryWorkspace.test.tsx
openVaultInObsidian returns null on success or caught error on failure. New handleViewVault callback opens the vault and emits info toast on success or error toast on failure, both with a "Reveal Folder" action that calls revealPath. Button click handler updated to invoke handleViewVault. Tests expanded to mock revealPath, verify toast emission with action wiring, and confirm error toast fallback on open/reveal failures.
i18n translations for vault UI
app/src/lib/i18n/en.ts, app/src/lib/i18n/chunks/ar-3.ts, app/src/lib/i18n/chunks/bn-3.ts, app/src/lib/i18n/chunks/en-3.ts, app/src/lib/i18n/chunks/es-3.ts, app/src/lib/i18n/chunks/fr-3.ts, app/src/lib/i18n/chunks/hi-3.ts, app/src/lib/i18n/chunks/id-3.ts, app/src/lib/i18n/chunks/it-3.ts, app/src/lib/i18n/chunks/ko-3.ts, app/src/lib/i18n/chunks/pt-3.ts, app/src/lib/i18n/chunks/ru-3.ts, app/src/lib/i18n/chunks/zh-CN-3.ts
Adds workspace.openingVaultTitle, workspace.openingVaultMessage, workspace.openVaultFailedTitle, workspace.openVaultFailedMessage, workspace.revealVaultFailed, and workspace.revealFolder translation keys across 13 languages to localize vault opening states and the reveal folder action.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

working

Poem

A vault once locked in memory's keep,
Now opens wide for those who seek—
Or reveals its path with one soft click,
A rabbit's touch makes UI slick. 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding toast feedback and a Reveal Folder fallback for the View Vault button.
Linked Issues check ✅ Passed All acceptance criteria from issue #2281 are met: visible feedback via toasts, no silent action, Reveal Folder fallback, comprehensive test coverage, and desktop platform support.
Out of Scope Changes check ✅ Passed All changes directly support the PR objectives: toast implementation, Reveal Folder fallback, i18n translations, tests, and underlying utilities for vault interaction.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 20, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix for #2281 — the toast + Reveal Folder fallback is a solid UX upgrade for users without Obsidian. Tests cover all four branches cleanly, capability is correctly scoped, and the i18n fallback strategy is pragmatic.

One minor type nit below, otherwise LGTM.

*/
async function openVaultInObsidian(contentRootAbs: string): Promise<void> {
async function openVaultInObsidian(contentRootAbs: string): Promise<unknown | null> {
const url = `obsidian://open?path=${encodeURIComponent(contentRootAbs)}`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor] Promise<unknown | null> simplifies to Promise<unknown>null is already a member of unknown, so the | null is a no-op and makes it look like the return could be unknown OR null as distinct cases (which is the intent, but the type doesn't express it).

Suggestion: either Promise<unknown> with a doc comment explaining the null-means-success convention, or a small discriminated type:

type VaultOpenResult = { ok: true } | { ok: false; error: unknown };

Copy link
Copy Markdown
Member

@senamakel senamakel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, nice work!

@senamakel senamakel merged commit a472d6f into tinyhumansai:main May 20, 2026
28 of 31 checks passed
@senamakel
Copy link
Copy Markdown
Member

huge thanks @obchain, the toast plus reveal folder fallback is such a nice touch for folks without obsidian 🙌 love how the vault path shows up right in the toast too, makes view vault feel way more reliable. thanks for shipping this one ✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

View Vault button does nothing in memory tree

3 participants