Skip to content

feat(tauri): support workspace file links#2476

Open
YOMXXX wants to merge 3 commits into
tinyhumansai:mainfrom
YOMXXX:feat/1402-workspace-file-links
Open

feat(tauri): support workspace file links#2476
YOMXXX wants to merge 3 commits into
tinyhumansai:mainfrom
YOMXXX:feat/1402-workspace-file-links

Conversation

@YOMXXX
Copy link
Copy Markdown
Contributor

@YOMXXX YOMXXX commented May 22, 2026

Summary

  • Adds safe Tauri IPC commands for opening, revealing, and previewing active-workspace files.
  • Adds frontend workspace: / openhuman-workspace: link parsing and routes chat markdown workspace links through the new Tauri command.
  • Keeps raw file:// markdown links blocked and preserves existing external http(s) / mailto: handling.
  • Documents the new workspace file-link IPC surface.

Problem

Agents and UI surfaces can reference files produced under the OpenHuman workspace, but the desktop app did not have a safe first-party path for handling those workspace file links. Using raw filesystem URLs would either be blocked by the existing link policy or risk bypassing workspace boundaries.

Solution

  • Introduce open_workspace_path, reveal_workspace_path, and preview_workspace_text Tauri commands.
  • Resolve only workspace-relative paths against the active OpenHuman workspace, canonicalize the target, and reject absolute paths, traversal, URI/drive prefixes, missing targets, and symlink escapes.
  • Add frontend helpers to parse workspace schemes and Tauri invoke wrappers that return camelCase preview payloads.
  • Update chat markdown link rendering so workspace links survive react-markdown URL filtering and are dispatched through the guarded Tauri command.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — not run locally; CI coverage gate is authoritative and will fail this PR if changed-line coverage is below 80%.
  • Coverage matrix updated — N/A: no existing feature row for workspace markdown/file-link IPC; focused tests added with the implementation.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A: no matrix feature ID applies.
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md) — N/A: no release smoke flow changes.
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Desktop/Tauri: adds three read/open-only workspace file commands behind the existing privileged core-process capability.
  • Frontend/chat: workspace markdown links now open through the OS only after Rust validates the target remains inside the active workspace.
  • Security: raw file:// links remain blocked; Rust canonicalization guards against path traversal and symlink escapes.
  • Compatibility: existing external link handling is preserved.

Related


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

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

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

Commit & Branch

  • Branch: feat/1402-workspace-file-links
  • Commit SHA: c8745d8c

Validation Run

  • pnpm --filter openhuman-app format:check (via pre-push hook)
  • pnpm typecheck (pnpm --filter openhuman-app compile)
  • Focused tests: pnpm --filter openhuman-app test:unit src/utils/workspaceLinks.test.ts src/utils/tauriCommands/workspacePaths.test.ts src/pages/conversations/components/AgentMessageBubble.test.tsx (11 passed)
  • Rust fmt/check (if changed): cargo fmt --manifest-path app/src-tauri/Cargo.toml -- --check; GGML_NATIVE=OFF cargo check --manifest-path app/src-tauri/Cargo.toml; pre-push pnpm --filter openhuman-app rust:check
  • Tauri fmt/check (if changed): GGML_NATIVE=OFF cargo test --manifest-path app/src-tauri/Cargo.toml workspace_paths::tests (6 passed)
  • Additional focused lint: pnpm --filter openhuman-app exec eslint src/utils/workspaceLinks.ts src/utils/workspaceLinks.test.ts src/utils/tauriCommands/workspacePaths.ts src/utils/tauriCommands/workspacePaths.test.ts src/pages/conversations/components/AgentMessageBubble.tsx src/pages/conversations/components/AgentMessageBubble.test.tsx
  • Whitespace: git diff --check

Validation Blocked

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

Behavior Changes

  • Intended behavior change: chat markdown can use workspace: or openhuman-workspace: links to open workspace-contained files through guarded Tauri commands.
  • User-visible effect: users can click agent-produced workspace file links instead of copying paths manually.

Parity Contract

  • Legacy behavior preserved: existing http:, https:, and mailto: links still route through openUrl; raw file:// links remain blocked.
  • Guard/fallback/dispatch parity checks: frontend rejects unsafe workspace hrefs before invoke; Rust independently validates canonical target containment before opening/revealing/previewing.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this PR
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

  • New Features

    • Added support for workspace file links in markdown messages—users can now click workspace: protocol links to open, reveal, or preview files within their workspace.
    • Implemented file opening, file explorer reveal, and text preview functionality for workspace files in the desktop application.
  • Documentation

    • Updated desktop shell architecture documentation with workspace file handling details and security constraints.

Review Change Stack

@YOMXXX YOMXXX requested a review from a team May 22, 2026 03:13
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 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: 53a11610-0dd5-4e9d-8ca6-e7923c64c4e2

📥 Commits

Reviewing files that changed from the base of the PR and between e08d5e8 and 344d5b4.

📒 Files selected for processing (5)
  • app/src-tauri/capabilities/default.json
  • app/src-tauri/permissions/allow-workspace-files.toml
  • app/src/utils/workspaceLinks.test.ts
  • app/src/utils/workspaceLinks.ts
  • gitbooks/developing/architecture/tauri-shell.md
✅ Files skipped from review due to trivial changes (1)
  • gitbooks/developing/architecture/tauri-shell.md

📝 Walkthrough

Walkthrough

This PR implements a unified workspace-file interaction layer for the Tauri desktop app. It adds frontend link-parsing utilities, backend Tauri commands for opening/revealing/previewing workspace files with path containment validation, TypeScript command wrappers, and upgrades chat markdown rendering to handle workspace links alongside external URLs.

Changes

Workspace File Links and Path Operations

Layer / File(s) Summary
Workspace link parsing utilities and tests
app/src/utils/workspaceLinks.ts, app/src/utils/workspaceLinks.test.ts
Frontend contract recognizes and validates workspace: / openhuman-workspace: hrefs, normalizing them to workspace-relative paths while rejecting traversal, absolute paths, Windows drives, and null-byte attacks. Tests verify both acceptance of valid variants and rejection of unsafe patterns.
Tauri backend workspace path commands
app/src-tauri/src/workspace_paths.rs, app/src-tauri/src/lib.rs
Three IPC commands (open_workspace_path, reveal_workspace_path, preview_workspace_text) implement workspace file operations. Path safety is enforced by workspace-root resolution, input normalization, canonicalization, and containment checks preventing traversal and symlink escape. Preview supports bounded UTF-8 reading with truncation handling. Unit tests cover acceptance of valid paths, rejection of parent-escape and absolute paths, UTF-8 correctness, truncation behavior, and Unix symlink safety.
Tauri permissions configuration
app/src-tauri/permissions/allow-workspace-files.toml, app/src-tauri/capabilities/default.json
New allow-workspace-files permission authorizes the three workspace path commands and is added to the default capability.
Frontend Tauri command wrappers
app/src/utils/tauriCommands/workspacePaths.ts, app/src/utils/tauriCommands/workspacePaths.test.ts, app/src/utils/tauriCommands/index.ts
TypeScript module providing type-safe, Tauri-environment-gated wrappers for workspace path operations, with response-shape conversion from Tauri snake_case to frontend camelCase. Tests verify Tauri gating behavior and correct command invocation with response mapping.
Markdown link handling in chat
app/src/pages/conversations/components/AgentMessageBubble.tsx, app/src/pages/conversations/components/AgentMessageBubble.test.tsx
Chat markdown rendering now recognizes and routes workspace links. Shared MarkdownAnchor component intercepts link clicks, parses hrefs as workspace links via parseWorkspaceHref, and dispatches to openWorkspacePath (workspace links) or openUrl (allowed external links), gracefully ignoring OS errors. Applied to both BubbleMarkdown and TableCellMarkdown. Tests verify external links trigger openUrl, workspace links trigger openWorkspacePath, and file:// links trigger neither.
Architecture documentation and i18n
gitbooks/developing/architecture/tauri-shell.md, app/src/lib/i18n/chunks/de-*.ts
Updated Tauri shell architecture docs describing app/src-tauri as desktop-only, clarified IPC command registration via generate_handler!, added "Workspace file links" command group with path-safety constraints, and updated core bridge description. Added German translations for subconscious provider and MCP-server developer UI.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • senamakel
  • graycyrus

Poem

🐰 A workspace link lands in the chat,
No more just text, no more of that!
Click it true, the Tauri way—
Open, reveal, or preview's display.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive German i18n translations (de-3.ts, de-5.ts) appear unrelated to workspace file links; their purpose and scope require clarification. Clarify why German translations were added in this workspace-file-links PR; confirm they are not accidental or intended for a separate issue.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(tauri): support workspace file links' directly and concisely summarizes the primary change: adding workspace file link support to Tauri.
Linked Issues check ✅ Passed The PR implements all primary objectives from #1402: Tauri commands for open/reveal/preview with path validation [#1402], frontend parsing/rendering for workspace links [#1402], tests for safety [#1402], and documentation updates [#1402].

✏️ 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 22, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
gitbooks/developing/architecture/tauri-shell.md (1)

151-160: 💤 Low value

Well-documented workspace file link commands.

The documentation clearly explains the three new commands and their path safety constraints. All security considerations from the PR are covered: workspace-relative paths only, canonicalization, and rejection of traversal/absolute/URI/symlink escapes.

Optional: Consider adding issue reference for traceability

For consistency with the screen share section (line 143, which references #713 and #812), you could optionally mention that this closes issue #1402:

 ### Workspace file links
 
-From **`workspace_paths.rs`**. These commands accept workspace-relative paths only. The shell resolves each path against the active OpenHuman workspace, canonicalizes the target, and rejects traversal, absolute paths, URI-like prefixes, and symlink escapes before opening or reading anything.
+From **`workspace_paths.rs`**. These commands accept workspace-relative paths only. The shell resolves each path against the active OpenHuman workspace, canonicalizes the target, and rejects traversal, absolute paths, URI-like prefixes, and symlink escapes before opening or reading anything. See issue `#1402` (workspace file interactions).

This adds traceability similar to other command sections, but is not essential.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gitbooks/developing/architecture/tauri-shell.md` around lines 151 - 160, Add
an optional issue reference for traceability by appending a short note in this
section (near the Workspace file links header or the screen-share style
reference) that indicates this documentation closes issue `#1402`; update the
prose around the list or add a parenthetical “(closes `#1402`)” so readers can
trace the implementation to the issue, referencing the workspace_paths.rs
commands open_workspace_path, reveal_workspace_path, and preview_workspace_text
when placing the note.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src-tauri/permissions/allow-core-process.toml`:
- Around line 114-123: The allow-core-process TOML currently includes
workspace-file commands ("open_workspace_path", "reveal_workspace_path",
"preview_workspace_text"), widening a high-privilege bundle; create a new
permission TOML (e.g., allow-workspace-files) containing only those three
command identifiers, remove them from allow-core-process, and then update
capability grant files under app/src-tauri/capabilities/ to replace any grant of
allow-core-process with a grant for allow-workspace-files where only
workspace-file access is required so UI surfaces request the narrower
permission.

In `@app/src/utils/workspaceLinks.ts`:
- Around line 16-24: After calling decodeURIComponent on rawPath (the decoded
variable), immediately reject any decoded NUL bytes by checking for '\0' (or
char code 0) and returning null if found; update the logic in workspaceLinks.ts
right after the try/catch that sets decoded and before creating normalized so
that a decoded string containing NUL is treated as invalid (preserving the
existing WINDOWS_DRIVE_RE and normalized checks).

---

Nitpick comments:
In `@gitbooks/developing/architecture/tauri-shell.md`:
- Around line 151-160: Add an optional issue reference for traceability by
appending a short note in this section (near the Workspace file links header or
the screen-share style reference) that indicates this documentation closes issue
`#1402`; update the prose around the list or add a parenthetical “(closes `#1402`)”
so readers can trace the implementation to the issue, referencing the
workspace_paths.rs commands open_workspace_path, reveal_workspace_path, and
preview_workspace_text when placing the note.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 56615497-6482-4b9e-ab1a-b5945727268d

📥 Commits

Reviewing files that changed from the base of the PR and between 7fe3dd0 and c8745d8.

📒 Files selected for processing (11)
  • app/src-tauri/permissions/allow-core-process.toml
  • app/src-tauri/src/lib.rs
  • app/src-tauri/src/workspace_paths.rs
  • app/src/pages/conversations/components/AgentMessageBubble.test.tsx
  • app/src/pages/conversations/components/AgentMessageBubble.tsx
  • app/src/utils/tauriCommands/index.ts
  • app/src/utils/tauriCommands/workspacePaths.test.ts
  • app/src/utils/tauriCommands/workspacePaths.ts
  • app/src/utils/workspaceLinks.test.ts
  • app/src/utils/workspaceLinks.ts
  • gitbooks/developing/architecture/tauri-shell.md

Comment thread app/src-tauri/permissions/allow-core-process.toml Outdated
Comment thread app/src/utils/workspaceLinks.ts
@coderabbitai coderabbitai Bot added the feature Net-new user-facing capability or product behavior. label May 22, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/src/lib/i18n/chunks/de-5.ts (1)

504-526: 🏗️ Heavy lift

Split this locale chunk before it grows further.

Line 526 keeps this source above the preferred ~500-line limit; please split de-5.ts into smaller namespace-focused chunks to preserve readability and single responsibility.

As per coding guidelines "**/*.{js,ts,tsx,jsx}: Prefer files ≤ ~500 lines per source file; split modules when growing to maintain readability and single responsibility."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/lib/i18n/chunks/de-5.ts` around lines 504 - 526, The de-5.ts locale
file has grown past the ~500-line guideline; extract the MCP-server keys (all
entries with the 'settings.mcpServer.*' and related
'settings.developerMenu.mcpServer.*' keys shown) into a new, smaller locale
chunk (e.g., a namespace-focused de-xxx file), export that chunk the same shape
as the existing locale object, and remove those keys from de-5.ts; then update
the locale aggregator where chunks are combined to import and merge the new MCP
chunk so runtime behavior and key names (settings.mcpServer.* and
settings.developerMenu.mcpServer.*) remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@app/src/lib/i18n/chunks/de-5.ts`:
- Around line 504-526: The de-5.ts locale file has grown past the ~500-line
guideline; extract the MCP-server keys (all entries with the
'settings.mcpServer.*' and related 'settings.developerMenu.mcpServer.*' keys
shown) into a new, smaller locale chunk (e.g., a namespace-focused de-xxx file),
export that chunk the same shape as the existing locale object, and remove those
keys from de-5.ts; then update the locale aggregator where chunks are combined
to import and merge the new MCP chunk so runtime behavior and key names
(settings.mcpServer.* and settings.developerMenu.mcpServer.*) remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8121d2c8-fdcd-4191-b8f8-7604c706ed60

📥 Commits

Reviewing files that changed from the base of the PR and between c8745d8 and e08d5e8.

📒 Files selected for processing (2)
  • app/src/lib/i18n/chunks/de-3.ts
  • app/src/lib/i18n/chunks/de-5.ts

@YOMXXX
Copy link
Copy Markdown
Contributor Author

YOMXXX commented May 22, 2026

Clarification for the CodeRabbit pre-merge note: the German i18n additions are intentional CI-gate cleanup, not a separate feature. pnpm i18n:check failed on this PR because de was missing the MCP-server keys and two existing subconscious keys; adding those translations brought the locale back to 0 missing keys and unblocked test / i18n Coverage.

@YOMXXX
Copy link
Copy Markdown
Contributor Author

YOMXXX commented May 22, 2026

CI is green and the CodeRabbit threads are resolved. Ready for reviewer pass / merge when convenient.

@YOMXXX
Copy link
Copy Markdown
Contributor Author

YOMXXX commented May 22, 2026

@graycyrus Could you take a reviewer pass on this when convenient? CI is green, CodeRabbit is approved, and there are no unresolved review threads on the PR. The German i18n additions are only to satisfy the current i18n gate.

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

Labels

feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make the Tauri frontend handle workspace file links and views properly

1 participant