James Hooker161 downloadsTwo-way sync of your JokeBakery jokes, sprints, lists and crashes with your vault as Markdown. Requires a JokeBakery account.
Two-way sync between JokeBakery and an Obsidian vault. Your sprints, jokes, lists and gigs become Markdown files you can read and edit in Obsidian; edits flow back to JokeBakery on the next sync.
<folder>/
Sprints/
2026-06-06.md # one "10 in 10" sprint per file, named by its date
Jokes/
whats-the-deal-with-airline-food.md
Lists/
dentist.md # one reusable list per file
Gigs/
2026-07-14-the-comedy-cellar.md # one performance, with how it went
Conflicts/ # auto-created only when a sync conflict happens
Sprints/YYYY-MM-DD.md. A numbered list of joke lines. If you do
two sprints in one day the second is …-2.md; identity is the bw-id in the
file's frontmatter, not the filename, so renaming is safe.Jokes/<slug>.md. Editable prose under ## Setup,
## Development, ## Punchline, plus ## Notes and ## Scratchpad.
Structured fields (stage, status, families, theme, angle) are Obsidian
properties; rhythm/IEN markup rides in an opaque bw-meta property. The
joke's JokeBakery tags are its Obsidian tags, so they show in the tag
pane and in search. They are read-only here: a space in a name becomes a
hyphen (big-joke) because Obsidian will not index a tag with a space,
and tagging happens in JokeBakery.Lists/<slug>.md. A user-owned, reusable list: its items are a
plain bullet list in the body; edit them here. A list can be attached to many
jokes (attach/detach in JokeBakery).Gigs/<date>-<venue>.md. The set as you performed it, plus how it
went. See below.A joke's ## Lists section is now a read-only list of the labels attached to
that joke — open the matching note in Lists/ to edit a list's contents.
## Alternative punchlines and ## Setup versions are likewise read-only —
manage those in JokeBakery.
A gig note is where you write up a set after you've done it. Each one carries the lineup you performed, with a link through to every joke's own note, so the gig is a way back into the material rather than a dead record.
You can edit: venue, bill position, who you followed, the vibe, the crowd,
actual minutes, seconds to the first applause break, the recording URL and
whether you've reviewed it; the ## What went well, ## What went badly,
## Notes and ## Routine notes sections; and per joke in the lineup, its
rating (1-5), laugh types and note.
You can't edit here: the date, the set it came from, the running order,
which jokes were in it, or the ## Next time actions. Those belong to the gig
itself — change them in JokeBakery. A gig is also created in JokeBakery,
at the moment you log a set: a gig note you write by hand in Gigs/ has
nothing to attach to and is skipped (the plugin tells you so).
Laugh types are the ones from the app: Applause break, Rolling, Recognition, Titter, Groan, Gasp, Cheer, Silence. Write them as a comma-separated list. If you type something that isn't a laugh type, or a rating outside 1-5, that one value is left unchanged and the sync report says why — the rest of your edits still go through.
https://jokebakery.comJokeBakery<folder>/Sprints named after its date
(2026-06-10.md) and write one joke per line (numbered or not).<folder>/Jokes. Use ## Setup / ## Punchline
headings, or just write freeform — freeform text lands in the joke's
scratchpad.<folder>/Lists. The note title (or label
property) is the list name; write one item per bullet line.On the next sync these are created in JokeBakery and get their bw-id written
back into the file.
Sync is last-writer-wins by modified time. If the same item changed on both
sides between syncs, nothing is lost: the losing version is written to
<folder>/Conflicts/… for you to merge by hand.
Deletions sync both ways:
As a safety net, if 20 or more deletions are queued at once (e.g. the sync folder itself was deleted), they are held back: auto-syncs skip them and a manual Sync now asks for confirmation before deleting anything server-side.
Caveat: Obsidian-side deletions are detected while the plugin is running. Delete items as individual files — deleting a synced file you no longer want is the reliable signal. If a synced file goes missing without a delete event (e.g. it was removed outside Obsidian), the next pull treats the server as authoritative and restores it.
tags property mirrors its JokeBakery
tags on every sync, including when only the tag changed (a rename, an attach
or a detach rewrites the untouched notes it is on). Editing the property in
Obsidian does nothing on the next push; the app is where tags change.tested, working, hit, needsrewrite, retired).
Anything else is ignored rather than sent.The easiest way to add this to Obsidian today:
https://github.com/jimhooker/jokebakery-obsidianBRAT keeps the plugin updated as new releases are published here.
main.js, manifest.json and styles.css from the
latest release,
or build them yourself with npm install && npm run build.<your-vault>/.obsidian/plugins/jokebakery-sync/.0.4.0 changed the plugin id from bakerwriter-sync to jokebakery-sync, so
Obsidian treats it as a new plugin. To keep your settings and sync state:
<vault>/.obsidian/plugins/bakerwriter-sync/data.json into
<vault>/.obsidian/plugins/jokebakery-sync/.Skipping step 2 also works — re-enter your token and folder and run a sync;
files are matched by their bw-id, so nothing duplicates.
npm run dev runs esbuild in watch mode. Symlink this folder into your vault's
.obsidian/plugins/ to iterate live.
npm test runs two vitest suites: tests/serialize.test.ts (Markdown ⇄ DTO
round-trips) and tests/sync.test.ts, which drives the real SyncEngine
against an in-memory vault and a fake server. Run both after touching
src/serialize.ts or src/sync.ts. The sync suite is the one that guards the
rules about what may be pushed — above all that a frontmatter key a note
doesn't carry is never sent as an empty value, because the server would apply
that as "clear this field".
npm run build typechecks (src and tests) then bundles.
This is the release repo: the one BRAT watches and the one releases are tagged
from (a tag named after the version, with no v prefix, builds main.js and
attaches it with manifest.json and styles.css to a GitHub Release). The
plugin is developed and tested inside the JokeBakery app repo and mirrored
here, so a change lands in the app repo first and arrives here with the
release that ships it. Issues are welcome here either way.
This plugin is a companion to the hosted JokeBakery
service and talks only to https://jokebakery.com (the Server URL setting
exists for development builds). On each sync it sends the contents of notes
inside the configured sync folder (your jokes, sprints, lists and crashes)
together with your access token, and pulls your items back. No other part of
your vault is read or transmitted, and there are no analytics or third-party
services. Your access token is stored in the plugin's data.json inside your
vault — treat it as a secret; you can revoke it any time in JokeBakery under
Settings → Obsidian sync.
Using the plugin requires a JokeBakery account (currently invite-only).
The plugin talks to JokeBakery's /api/sync REST API with a Bearer token.
Each sync runs push (send new/edited vault files) then pull (write
changed server items into the vault). All Markdown ⇄ JSON translation happens
here in the plugin; the server only ever speaks JSON. See src/serialize.ts
for the file format and src/sync.ts for the sync algorithm.