Public: anyone can read this; the crew can change it.
A move made in the terminal reaches the open web pages too #91
A move made in the terminal now reaches every open board page live.
stopped closed without shipping
commented
Pushed. Merged main into this branch to pick up the control-character stripping (#85), byte-capped body reads (#60), and per-write rate limiting (#64) that landed there since this pull opened.
The only conflicts were import lines in src/mcp.ts and src/routes.ts, where both sides had added a new import on the same line — writeBucket/cleanText from main and noteRevision from this branch. Kept both; nothing else touched the two files at the same spot. bun test passes (177 tests, 0 fail).
commented
Parked by the crew: the check stayed red through 2 automatic tries
Sign in to join this conversation.
A move made in the terminal now reaches every open board page live.
src/watch.tsis the new piece: it pollsboardRevision(from #17) about twice a second, but only for boards that currently have an open/eventslistener, and publishes oneexternalevent withby: nullthe instant it sees a board move without this process having already announced it.routes.tsandmcp.ts's ownpublishhelpers now note the revision they just announced, so a normal web or MCP write is never double-reported by the poller a moment later.static/board.jstreatsexternalexactly likeundo: a full-board reconcile, deferred while you're mid-type or mid-drag, since the poller only knows that the board changed, not what.Tests:
src/watch.test.tsdrives the poll logic directly againstbus.ts/db.ts— no listener means no publish, a write already noted isn't re-announced, and forgetting a board once its last listener leaves means a later resubscribe doesn't replay stale history.src/server.test.tsadds the cross-process integration test the issue asks for: a second process writes throughdb.tsexactly the waysrc/tty.tsdoes, and an open/b/:id/eventsstream is asserted to receive theexternalframe.Left out: the event still carries no
ids, so a terminal move always triggers a full-board reconcile rather than a targeted DOM patch — the poller has no way to know which card or column changed, only that the revision did. Also renamedstatic/board.*.jsfor the content change (no build step here, so the hash suffix is hand-picked the same way prior commits did it).To try it: open a board in a browser, then from
$FORGE_APP_SSHopen the same board in the terminal and move a card — the browser tab updates within about a second with no reload.Closes #31