Skip to content

implement file association support#342

Open
tsconfigdotjson wants to merge 1 commit intoblackboardsh:mainfrom
tsconfigdotjson:feat/open-files-304
Open

implement file association support#342
tsconfigdotjson wants to merge 1 commit intoblackboardsh:mainfrom
tsconfigdotjson:feat/open-files-304

Conversation

@tsconfigdotjson
Copy link
Copy Markdown

@tsconfigdotjson tsconfigdotjson commented Mar 25, 2026

Summary

Fixes #304 — double-clicking a file associated with an Electrobun app now delivers it as a file:// URL through the existing open-url event.

  • Config: adds app.fileAssociations to electrobun.config.ts for declaring document types.
  • Build: the CLI generates CFBundleDocumentTypes with LSItemContentTypes and UTExportedTypeDeclarations in Info.plist for proper Launch Services integration on modern macOS. UTI identifiers are derived from the app identifier (e.g., com.example.app.myext). Icon files are copied to the bundle with build-time existence checks. Validation strips leading dots from extensions and skips entries with missing ext/name.
  • macOS: files opened via Finder arrive as file:// URLs through the existing application:openURLs: handler — no new native code needed.
  • Cold-launch fix: fixes a pre-existing race where URLs arriving before the Bun Worker registered its handler were dropped. They are now buffered with a mutex and flushed on registration.

Usage

// electrobun.config.ts
app: {
  fileAssociations: [{
    ext: ["myext"],
    name: "My Document",
    role: "Viewer",
    icon: "assets/doc-icon.icns",
  }],
}

// src/bun/index.ts — files arrive as file:// URLs via open-url
Electrobun.events.on("open-url", (e) => {
  if (e.data.url.startsWith("file://")) {
    console.log("Opened file:", e.data.url);
  }
});

Files changed (3)

Layer Files
Config ElectrobunConfig.ts — fileAssociations type + docs
CLI/build cli/index.ts — generateDocumentTypes (CFBundleDocumentTypes + UTExportedTypeDeclarations), icon copy + validation
Native (macOS) nativeWrapper.mm — URL cold-launch buffering with mutex

🤖 Generated with Claude Code

@tsconfigdotjson
Copy link
Copy Markdown
Author

@YoavCodes pretty big one to be able to support file assocations, have your agents PR

@tsconfigdotjson tsconfigdotjson changed the title implement application:openFiles: and file association support implement file association support Mar 25, 2026
@tsconfigdotjson
Copy link
Copy Markdown
Author

tsconfigdotjson commented Mar 25, 2026

Clean Room Validation

Tested end-to-end by creating a standalone project in /tmp/electrobun-file-assoc-test/ (completely outside the repo) that links to the local electrobun package. The project declares three file associations to exercise different code paths:

fileAssociations: [
  { ext: ["ebtest"], name: "Electrobun Test Document", role: "Viewer" },
  { ext: ["ebtest2", "ebtest3"], name: "Electrobun Multi-Ext Document", role: "Editor" },
  { ext: [".ebdot"], name: "Dot-Prefix Test", role: "Viewer" },
]

What was validated

  1. Info.plist generation — All three CFBundleDocumentTypes entries generated correctly with LSItemContentTypes referencing UTIs derived from the app identifier (e.g., dev.electrobun.fileassoctest.ebtest).

  2. UTExportedTypeDeclarations — One UTI exported per extension, each with UTTypeIdentifier, UTTypeDescription, UTTypeConformsTo (public.data), and UTTypeTagSpecification mapping the extension. Multi-ext associations correctly generate separate UTIs.

  3. Leading dot stripping.ebdot stripped to ebdot with a build-time warning.

  4. File open deliveryopen -a FileAssocTest-dev.app /tmp/test-document.ebtest delivers file:///private/tmp/test-document.ebtest via the existing open-url event.

  5. No spurious events — No empty events on cold launch.

  6. Cold-launch race — URL buffering + mutex flush delivers file URLs correctly after handler registration.

  7. Typecheckbunx tsc --noEmit passes on the package.

  8. Unit tests — All 48 unit tests pass.

@tsconfigdotjson tsconfigdotjson force-pushed the feat/open-files-304 branch 5 times, most recently from 527ac15 to 926d314 Compare March 25, 2026 14:18
Adds app.fileAssociations config for declaring document types. The CLI
generates CFBundleDocumentTypes in Info.plist and copies document type
icon files to the app bundle's Resources folder. Build-time validation
strips leading dots from extensions, skips entries with missing ext/name,
and verifies icon files exist before writing plist references.

On macOS, files opened via associations arrive as file:// URLs through
the existing application:openURLs: handler and open-url event — no new
event type or native code needed.

Also fixes a pre-existing cold-launch race in URL handling: URLs that
arrived before the Bun Worker registered its handler were dropped. They
are now buffered with a mutex and flushed on registration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS application:openFiles support

1 participant