Skip to content

Add the Roam Inbox prototype: /message and the inbox badge - #24

Open
mattakamatsu wants to merge 1 commit into
mainfrom
roam-inbox
Open

Add the Roam Inbox prototype: /message and the inbox badge#24
mattakamatsu wants to merge 1 commit into
mainfrom
roam-inbox

Conversation

@mattakamatsu

Copy link
Copy Markdown
Contributor

What this adds

prototypes/roam-inbox: in-graph messaging for Roam, ported from the private DiscourseGraphs/roam-inbox roam/js prototype (v0.5.1, piloted on dg-team) into this repository's installable form. It is one bundle with two halves that only work together:

  • /message registers a "Send message" slash command. Picking a person turns the block into {{[[TODO]]}} [[+Name]] , which matches [[Convention/Inbox]] verbatim.
  • A topbar inbox badge counts messages addressed to you that arrived since you last looked. Clicking it opens a panel (Messages, Mentions, Tasks) with Open, Reply, and Done on every row.

The README explains why the convention rotted (no signal, hand-built queues, read and done were the same checkbox) and the design decisions that fix it. Related feedback ticket: FEE-535.

What changed in the port

  • Every graph read goes through window.roamAlphaAPI.data.async.*, every write through data.block.* and data.page.*, and datalog inputs are parameterized. The pull-watch entity is the one string built from text, so the page title is quoted through JSON.stringify.
  • Two queries per refresh instead of three: one over +Me split into messages and mentions by the TODO reference, one over Me for the /task channel. Each row pulls only its direct parent.
  • Badge, panel, and toasts subscribe to the inbox state and repaint themselves. A stale refresh never overwrites a newer one, and the fallback poll pauses while the tab is hidden.
  • The live-verified Roam editor traps from the original are preserved and documented in place: the store lags the textarea while a block is being edited, writes go through the textarea when an editor is open, pull results are read namespaced-key-first, and "new" is tracked by uid rather than by any timestamp.
  • Two small fixes found on the way: a hashtag-form address left a stray # in panel rows, and the badge mount retry was not cancelled on unload.

The code went through a four-angle simplification review (reuse, simplification, efficiency, altitude) before this PR. One conclusion worth recording here: no roamjs-components helper is a legal replacement for the graph code, because writes/* and queries/* route through the legacy roamAlphaAPI.createBlock and .q aliases via submitActions. Also, the barrel form import { addStyle } from "roamjs-components/dom" does work, but it pulls the whole dom barrel (marked, prismjs, refractor) into the bundle, measured at 900 KB against the 57 KB this extension ships. The stylesheet stays inline for that reason, and the comment in src/styles.ts now says so.

Verification

  • pnpm test at the root passes. The prototype has 43 vitest cases: the unread-count cases from the roam/js build, text flattening, result shaping, a source guard against default imports from roamjs-components and the legacy roamAlphaAPI aliases, and a built-bundle check that imports dist/extension.js into jsdom and runs onload with extensionAPI undefined, the way a roam/js loader block does.
  • pnpm typecheck (opt-in, strict) is clean. pnpm build and pnpm prepare:artifacts succeed.
  • Loaded live in the sandbox-discourse-graphs graph from the built bundle: identity resolved, badge mounted after the search box, counts matched an independent three-query datalog cross-check exactly (0 / 12 / 10). A test message lit the badge to 1 through the pull watch in 2.5 s, opening the panel acknowledged it and rendered the row with flattened text, Done wrote {{[[DONE]]}}, and the full /message flow (slash menu, picker with the recently active list, filter, Enter, insert, persistence) worked end to end. The test page was deleted afterwards and onunload removed everything.

Notes for the reviewer

  • pnpm-lock.yaml gains the new workspace entry plus two devDependencies (typescript, @types/node) for the opt-in typecheck. The diff also re-resolves two peer hashes for existing prototypes; a frozen-lockfile install passes.
  • Two repo-level follow-ups surfaced by the review, not done here: missingCapability and reportLoadFailure in src/index.ts are now the third near-verbatim copy across prototypes and belong in the extension-base template, and the AGENTS.md / react-rendering skill example that recommends the roamjs-components/dom barrel should carry the bundle-size warning above.
  • Handbook DevOps items an agent cannot satisfy: no Loom. Reviewer assignment is left to whoever picks this up.

🤖 Generated with Claude Code

Ports DiscourseGraphs/roam-inbox v0.5.1 (a pasted roam/js file piloted on
dg-team) into this repository's installable form. The two halves, the
/message person picker and the topbar inbox badge with its panel, ship as
one bundle so neither can be installed alone.

Graph access goes through data.async.* with parameterized inputs; writes
through data.block.* and data.page.*. Messages and mentions share one query
and each row pulls only its direct parent. Badge, panel, and toasts
subscribe to the inbox state and repaint themselves. The live-verified Roam
editor traps (store lag, textarea write-through, namespaced-key-first
reads, uid-based seen tracking) are preserved and documented in place.

Tests: 43 vitest cases, including the unread-count cases from the roam/js
build, a source guard against default imports from roamjs-components and
legacy roamAlphaAPI aliases, and a built-bundle load check that runs onload
the way a roam/js loader block does.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Roam prototype previews

The preview deployment is ready. Paste a URL below into Load Developer Extensions from URL in Roam:

View publishing details

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.

1 participant