Skip to content
jalco-drop
Esc
↑↓navigate↵open⌘Jpreview
On this page

Add your own format

Teach jalco-drop to open a new kind of file or folder with its own page, link preview and JSON.

Every way a drop can open lives in src/formats/. There are two kinds.

Text formats turn one file into a view, chosen by file name. Markdown, CSV/TSV, HTML and SVG are text formats in src/formats/text.tsx; anything else that’s text falls back to highlighted code. The Source action appears for every text format.

export const changelog: TextFormat = {
  id: "changelog",
  test: (name) => /^CHANGELOG\.md$/i.test(name),
  render: async (text) => ({ body: <ReleaseList releases={parseReleases(text)} /> }),
};

Bundle formats turn a folder into its own page. The CLI zips the folder; the server finds the format’s manifest file at the zip’s root, and the format decides the page, the link preview, the summary on the card and the JSON agents read. Scrawl (src/formats/scrawl/) and Superwhisper (src/formats/superwhisper/) are bundle formats.

export const superwhisper: BundleFormat = {
  id: "superwhisper",
  manifest: "superwhisper.json",
  load(manifest, entries, root) {
    if (!isNote(manifest)) return null;
    return {
      summary: { title: "Meeting notes", details: ["12:04"] },
      json: (entryUrl) => ({ kind: "transcript", audio: entryUrl(manifest.audio) }),
      Page: (props) => <SuperwhisperPage {...props} note={manifest} />,
    };
  },
};

To add one:

  1. Create src/formats/<name>/ with the format, and list it in src/formats/index.ts. Order matters: the first format that claims a drop wins.
  2. If its page needs to be interactive, add an island in src/islands/ and register it in client/islands.tsx.
  3. If the source app writes more than the page needs, teach bin/jalco-drop to recognize the folder and write a trimmed manifest, the way it drops Scrawl’s window list and Superwhisper’s prompt.
  4. Add a fixture under e2e/fixtures/ and a spec, so npm run check covers it.
  5. Add a page for it under docs-site/docs/file-types/, so it shows up in this section of the sidebar.

Was this page helpful?