block / block/buzz

Feature: safely open trusted local files and Obsidian notes from Desktop messages

Open
#6,172 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

Buzz Desktop messages cannot open a local file or application-owned document from a Markdown link. This blocks a common same-machine agent workflow: an agent creates a plan, report, or presentation brief in the user's local workspace or Obsidian vault, then cites it in Buzz. The human still has to locate the file manually.

## Reproduction

1. Send a message containing an absolute local path:

```markdown
[Open the plan](/Users/example/workspace/PLANS/PLAN.md)
```

2. Click the rendered link in Buzz Desktop.
3. Nothing opens. The path is treated as an app-relative URL, not a filesystem target.
4. Try a `file://` or `obsidian://` Markdown link. The URL sanitizer removes the unsupported scheme before the anchor can open it.

Observed in Buzz Desktop 0.5.14 on macOS 26.6.1.

## Current implementation

On current `main`, `buzzDeepLinkUrlTransform` explicitly preserves supported `buzz://` message, channel, repository, issue, and pull-request links. Everything else is delegated to React Markdown's default URL transform, which strips unknown schemes.

Relevant code:

- `desktop/src/shared/ui/markdown/utils.ts`
- `desktop/src/shared/ui/markdown/ExternalLinkAnchor.tsx`

The sanitizer is doing useful security work. The fix should not pass arbitrary sender-controlled schemes to the operating system.

## Proposed behavior

Add a first-party, Desktop-only local-file deep link, for example:

```text
buzz://local-file?path=%2FUsers%2Fexample%2Fworkspace%2FPLANS%2FPLAN.md
```

Handle it through a trusted-roots policy:

1. Local-file links are disabled until the user approves a folder root.
2. On first use, Buzz shows the decoded path, the sender, and the requested action. The user may allow the single file or approve a parent folder.
3. Buzz canonicalizes the path, resolves symlinks, and refuses traversal or any target outside the approved roots.
4. Approved files open in the operating system's configured application. A root may optionally specify an application handler, such as Obsidian for a vault.
5. Folders open in Finder.
6. Web and mobile show a clear “Available on Desktop” state and allow the path to be copied.

An alternative UI would let the user configure trusted local roots in Settings before any message can open them. The important constraint is that trust comes from the recipient's local configuration, never from the sender.

## Acceptance criteria

- [ ] Valid `buzz://local-file` Markdown links survive URL transformation and render as clickable links in Desktop.
- [ ] No local target opens outside an approved root without an explicit user decision.
- [ ] Path normalization rejects traversal, NUL bytes, malformed encoding, and symlink escapes.
- [ ] A missing, moved, or inaccessible target produces a clear, non-destructive error.
- [ ] An approved Markdown file inside an Obsidian vault can open in Obsidian when that root uses the Obsidian handler.
- [ ] Folder targets can open in Finder.
- [ ] Web and mobile present a safe Desktop-only fallback.
- [ ] Copy and paste preserve the deep link.
- [ ] Existing HTTP(S), message, channel, repository, issue, and pull-request links are unaffected.
- [ ] Parser, permission, canonicalization, handler, and error cases have automated tests.

## Relationship to existing issues

- #2906 covers files stored in a Buzz repository and explicitly excludes arbitrary local `file://` access. This request covers local files outside a Buzz repository, including Obsidian vaults and agent workspaces.
- #3761 covers `nostr:naddr` long-form references. It demonstrates the same first-party deep-link pattern but addresses relay content rather than local files.

## Why this matters

Human-agent work often ends with a local artifact. A handoff is not complete when the agent merely prints a path that the human must hunt down. A constrained local-file link would make that evidence one click away without allowing arbitrary messages to open arbitrary files.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.