Skip to content

Markdown file links with ~ (home tilde) don't open — tilde not expanded before shell.openPath #573

Description

@polina-raznitsyna

Problem

Clicking a markdown file link that starts with ~/ does nothing. Example link in chat:

[~/Documents/CraftAgents/note.md](~/Documents/CraftAgents/note.md)

The same link with an absolute path (/Users/me/Documents/...) opens correctly.

Root cause

The tilde is never expanded before being handed to Electron's shell.openPath, which does not do shell-style ~ expansion. The error returned by openPath is swallowed by .then(() => {}), so the click appears to silently do nothing.

Trace through the code:

  1. packages/ui/src/components/markdown/linkify.tsFILE_PATH_TARGET_REGEX explicitly matches ~/ paths, so isFilePathTarget('~/foo.md') is true.
  2. packages/ui/src/components/markdown/link-target.tsresolveMarkdownLinkTarget returns { kind: 'file', path: '~/foo.md' } unchanged.
  3. packages/ui/src/components/markdown/Markdown.tsx — the a component calls onFileClick('~/foo.md').
  4. apps/electron/src/main/platform.ts:
    openPath: (p) => shell.openPath(p).then(() => {}),
    shell.openPath receives ~/foo.md literally. It returns a non-empty error string ("Failed to open path"), which is discarded.

Steps to reproduce

  1. In any chat turn, have the agent output a markdown link with a ~/ path to an existing file, e.g. [~/Documents/test.md](~/Documents/test.md).
  2. Click the link.
  3. Nothing happens. No error, no toast, no file opens.
  4. Replacing ~/ with the full home path makes the same link work.

Expected

Either:

  • The tilde is expanded to the user's home directory before shell.openPath, and the file opens, or
  • If opening fails, a visible error (toast/log) is shown instead of silently swallowing it.

Suggested fix

Expand ~ to os.homedir() in one of:

  • resolveMarkdownLinkTarget (renderer-side, UI package), or
  • the Electron main-process openPath wrapper in apps/electron/src/main/platform.ts.

The second option also fixes any other call site that passes ~/... to openPath. Consider also surfacing the error string from shell.openPath instead of discarding it.

Environment

  • Craft Agents 0.8.9
  • macOS 15 (Darwin 25.3.0), arm64

Related

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions