Changelog
What's new in share-doc. Currently on v0.106.0. The CLI updates itself when you re-run the installer.
v0.106.0
October 29, 2026
LATEST
Find a file on your own computer
- •Find a file on your own computer. Right-click a file or folder in the sidebar and, if it's synced to one of your computers, you can copy its path on that computer, show it in Finder, or open it in VS Code or Cursor. share-doc asks the sync running on each of your computers where its copy is, and works out which computer you're using from which one you just touched; with two computers in play, the menu shows both by name and remembers the one you pick for this browser. A computer that's asleep still gives its last known path. This needs
sharedoc sync running on the computer, updated to this version.
Videos that keep playing, and pictures served by share-doc itself
- •Videos that keep playing, and pictures served by share-doc itself. Pictures, videos and files used to come straight from the storage service behind share-doc, through links that ran out: a video paused in a DM for ten minutes could sit spinning forever when you pressed play again, "Open in new tab" on a file could land on a page of XML saying the file wasn't available, and a channel with a few videos in it could hold every other picture up behind them. Now share-doc serves every byte itself, over the connection the app already has open, so a paused video picks up where it was, an expired link is simply asked for again, and an error is a plain message instead of XML. A video that stops getting data while it plays now tries again by itself after a few seconds, from where it was. Thumbnails and video posters are kept in share-doc's own database, so they arrive in a few milliseconds instead of a trip to the storage service, and a picture that never got a thumbnail gets one the first time it is shown. For the server:
MEDIA_STREAM=0 goes back to links straight to storage, MEDIA_URL_SECRET signs the links (derived from the storage secret when unset), and bun apps/sync/scripts/thumbs-migrate.ts (--apply, later --cleanup) moves the old thumbnails into the database.
Pictures in chat and folders show sooner
- •Pictures in chat and folders show sooner. A channel used to ask the server about each attached file one at a time before it could draw any of them; now it asks about all of them at once, so a channel full of screenshots fills in after one round trip instead of a queue of them. In a picture's full-size view, the pictures on either side load while you look, so ← and → open them straight away. A folder's quick preview of a picture downloads it once, not twice, and opening it again within the hour comes from the browser's cache. Folder thumbnails no longer turn into plain icons when you come back to a folder after a while, and pictures further up a channel wait until you scroll to them, so the ones on screen arrive first.
Open a link in a new tab from a phone
- •Open a link in a new tab from a phone. The card that appears when you tap a link in a doc now has New tab beside Open, for a link to another doc, a heading or a folder, since a phone has no ⌘-click or middle-click. A web link already opens in a new tab, so it keeps just Open.
Open links from a phone
- •Open links from a phone. In a doc you can edit, tapping a link places the cursor, and on a phone there was no other way to follow it: a web link, a link to a heading or folder, or a doc link still being looked up did nothing, and the preview a doc link did get closed again as the keyboard came up. Tapping any link now shows where it goes with an Open button, which stays up while the keyboard appears and goes away when you tap elsewhere. And on a phone the formatting bar for a selection now sits below the text, rather than hidden under the phone's own cut / copy / paste menu.
Measuring how fast pictures and videos load
- •Under the hood: measuring how fast pictures and videos load. The app now records how long each picture, video and thumbnail takes to arrive, and how long a video takes to start once you press play, so the work to make them faster (
docs/spec-media-speed.md) can be measured before and after. It sends only timings, sizes and the kind of request, never which file, and like the rest of the app's analytics it is off in a browser that sends Global Privacy Control or Do Not Track. The [privacy policy](/privacy) says so as of today. For the server: bun run video:probe reports how many stored videos keep their index at the end of the file, which makes them slower to start.
Rename, move and make folders from the sidebar
- •Rename, move and make folders from the sidebar. Right-click a file, or use a folder's ⋯ menu, for Rename (type the new name in place; Enter keeps it, Esc leaves it) and Move to…, which steps through the project's folders. Drag a file or folder onto a folder to move it there, onto a file to move it into that file's folder, or onto the tree's empty space to move it to the top of the project; hovering over a closed folder while dragging opens it. A drop that would move more than one file (a folder with files in it) asks first, so a slip of the mouse can't move a big folder. Every move says what it did, with Undo, and a doc you have open follows to its new place. A folder moves whole, with its comments, history, sharing and sync settings; connected folders on your computer move it too. Nothing is ever merged: a move onto a name that is already taken is refused. Anyone with a moved doc open is taken to its new place, and what they had just typed goes with it. New folder is on a folder's menu and next to the project's +; a new folder stays in the sidebar until something is in it. Owners and editors of a project see these. On the command line,
sharedoc files mv now moves a folder too.
Chat pictures you have already seen don't download again
- •Chat pictures you have already seen don't download again. Every time a picture, its thumbnail or a video was shown, the server handed out a new signed link to it, and the browser, which remembers files by link, fetched the whole file again: scrolling back, switching channels, reopening a picture or reloading the page all downloaded it afresh. A file's link now stays the same for a while (an hour for most, ten minutes for a thumbnail or a file in a private conversation), and the file tells the browser to keep it, so a picture you have seen comes from the browser's own cache.
Watch a chat video larger
- •Watch a chat video larger. A video under a message has a button in its top corner (on hover; always there on a phone) that opens it over the app, as big as the window allows, without going to the full screen. It carries on from where it was, playing or paused, with the file's name, Download and Open in folder (or Open in Slack and Save to project…) along the top. Esc, ✕ or a click outside the video closes it, and the player under the message picks up from wherever you got to. The player's own full-screen button is still there for the whole screen.
Zoom into a chat picture
- •Zoom into a chat picture. In the full-size view of a picture under a message, click a spot to see it at the picture's own size, right there, and drag to look around; click again to fit it back to the window. Pinch on a trackpad or a phone, or hold ⌘ or Ctrl and scroll, to zoom in and out about the pointer, and scroll to move around a zoomed picture. The bar has zoom out and zoom in buttons, and while zoomed, how big the picture is drawn (100% is its real size), which fits it back when pressed. + − zoom and 0 fits; zoomed in, the arrow keys move around the picture instead of stepping to the next one. A big grid of pictures can now be read cell by cell.
A spinner while a chat picture loads in full view
- •A spinner while a chat picture loads in full view. While the full-size picture is still downloading, a small spinner sits over the preview, so you can tell more detail is on the way. It only shows if the picture takes longer than a moment, so one that opens straight from the cache never flashes it.
A chat picture opens at once in full view
- •A chat picture opens at once in full view. Clicking a picture in a message used to show an empty dark screen until the whole file had arrived, and the download started twice: once by one route, then over again by another, throwing away what had come in. Now the small preview appears straight away at full size and the full picture replaces it when it has loaded, downloaded once. Opening the same picture again within a few minutes comes from the browser's cache.
The installed app's header clears the iPhone's top blur
- •The installed app's header clears the iPhone's top blur. On iOS 26, an app added to the Home Screen gets a blur across the top of the screen that reaches a little below the clock, and it smudged the header's ☰, the conversation name and the buttons beside it. Nothing a page draws there turns it off, so on a phone, upright, in the installed app, the header and the tops of the side panels and settings pages now sit 20 points lower, below the blur. Safari tabs, Android and desktop are unchanged.
Security fixes in the web server and the editor's libraries
- •Security fixes in the web server and the editor's libraries. React Router, which serves every page, moves to 7.18.2: it fixes several ways to slow the server down or crash it with a crafted request, an open redirect, and a way to run code through the data a page sends back. The database library (
drizzle-orm) moves to 0.45.4, which fixes an SQL-escaping bug. Smaller security fixes come along: the editor's paste handling (prosemirror-view, a cross-site scripting fix), markdown reading (markdown-it, which could be made to take seconds on a crafted doc), image resizing (sharp), the server's response compression, and the diagram renderer (mermaid 12.2). Nothing else changes.
Security fixes in two dependencies
- •Security fixes in two dependencies. The part of the web server that works out a visitor's IP address (
proxy-addr, inside Express) moves to 2.0.8, which fixes a way to spoof a client's IP address through an IPv4-mapped IPv6 trusted-proxy range. The HTML sanitizer that cleans mermaid diagrams (dompurify) moves to 3.4.17, which fixes a sanitizer bypass. Nothing else changes.
A guest's edits reach everyone else in the doc
- •A guest's edits reach everyone else in the doc. When someone from the workspace had a doc open, a guest editing it through a no-sign-in link was disconnected about a second after joining. They could keep typing, but the changes stayed in their own browser and nobody else saw them. Their browser was passing teammates' presence back to the server, as every browser does, and the check that stops a guest from posing as a teammate treated that as impersonation. That check now lets these unchanged copies through, and still refuses a guest who tries to appear as, or remove, someone else.
Raising a link's role reaches people who already opened it
- •Raising a link's role reaches people who already opened it. Switching a link from *Viewer* to *Editor* used to give the new role only to people opening it for the first time. Anyone who had already opened it stayed a viewer, even when they opened it again. Now everyone who opened the link gets whatever role it currently gives, higher or lower. Tabs that are already open pick up a higher role when they're reloaded.
- •The share dialog stays still. *Link copied*, *Link updated* and similar notes now appear as a small toast at the bottom of the screen. Before, they appeared inside the dialog and pushed everything below them down.
Share a file or folder with people who have no account
- •Share a file or folder with people who have no account. *Share* has a fourth kind of link: *Anyone with the link, no sign-in*. Whoever opens it gets the file or folder straight away, with no sign-up and no seat in your workspace, as a viewer, a commenter or an editor (the link says which). It's for bringing a trusted group into one folder, like a client's assets or a partner's brief, without inviting them in. They see only what you shared: a folder's own tree and its folder view, or the file on its own, with no chat, people or search around it. They show as guests everywhere, *Sam (guest)* on their comments and their cursor, and nothing a guest writes can wake an agent. The link is the only key, so the dialog says so. It asks before letting strangers comment or edit, starts the link at 30 days, and lists the guests who used it, each with *Remove*. Turning the link off, replacing it or letting it expire signs its guests out within seconds, including tabs they have open. A guest who creates an account keeps their comments and edits under their new name. Owners and admins can turn these links off for a whole workspace in workspace settings. From the CLI:
sharedoc invite link --folder <path> --audience public. - •Sharing is tighter for everyone. A viewer could still leave a comment through an old route the editor fell back to; now only commenters and editors can. Removing someone's access, turning a link off or lowering its role now reaches tabs they already have open within seconds, not on their next reload. A doc shared on its own now shows its pictures instead of broken images, and an HTML page in a shared folder opens for the people it's shared with.
A preview pane you can resize, step through and edit in
- •The folder view's preview pane does more. Drag its left edge to make it as wide as you like, so a picture is no longer stuck small; it remembers the width, and a double-click on the edge resets it. ‹ › at the top of the pane, or ← and →, step to the previous or next file without going back to the grid. A doc now opens in the pane in the full editor, where you can edit, comment and see its status, instead of as its first lines of plain text. The ⛶ button opens any file on its own page.
Folders show what's in each file
- •Folders show what's in each file. The cards in a folder view were small, and only pictures had a preview, so a folder of docs or videos was a grid of the same icon. Now each card is a bigger thumbnail of the whole file: a picture uncropped, a video's poster (or, for a video that came from a synced folder or the CLI, a frame your browser draws from it), and a doc as a little page with its title and first lines. Pick *Small*, *Medium* or *Large cards* beside the sort; your browser remembers it. The API's one-level listing (
GET /api/v1/files?depth=1) now gives each markdown doc an excerpt, its opening lines without the front matter; thumbs=0 leaves it out.
A link preview's × stays put while you reach for it
- •A link preview's × stays put while you reach for it. The × that removes or hides a link preview showed only while the pointer was on the card, and it sits just outside the card's right edge, so moving toward it made it vanish. Now it stays as the pointer travels to it.
See a doc's pictures full size, and comment on each one
- •See a doc's pictures full size, and comment on each one. A doc of screenshots, especially a table of them, showed each one too small to read. Now a button in a picture's corner, or a double-click, opens it full size (in a doc you can only read, a click does). The arrow keys step through every picture in the doc, a click shows the picture at its own size, and Esc closes. Beside each picture are its comment threads: press C to start one on the picture you're looking at, then → for the next. A picture with open threads shows their count in the doc, and the thread in the panel shows the picture's thumbnail. Click it to open that picture.
A thread link opens its thread every time
- •A thread link opens its thread every time. A *thread in #channel* link in a message did nothing when you had already opened that thread and closed it again. Now it opens the thread each time you click it, and so does a link to a comment on a doc after you closed the comments.
Copies and moves of big files are instant
- •A copy of a big file goes up in no time. When a synced folder or
sharedoc files put sends a file your workspace already holds (a render copied into another folder, a sound reused in every episode) and you can already open one of those copies, nothing is uploaded. The hub records the copy at once. The CLI now hashes each big file right before sending it, so an edit is never mistaken for the old bytes. Run sharedoc update to get it. - •Moving or renaming a file no longer copies it. Moving a picture or a video to another folder or project used to copy its bytes in storage and then delete the old ones, so a big render took a while to move. Now a move changes only where the file is listed and its bytes stay where they are, so a 2 GB video moves as quickly as a note. And replacing a file in a project moved over from another workspace no longer leaves its previous version taking up storage for good.
A thread shows which day each reply is from
- •A thread shows which day each reply is from. A thread whose replies went on for days showed only a time on each one, so a reply from yesterday looked like it came minutes after the post. Now, once a thread spans more than one day, it has the same day dividers as a channel: the post's day above it, and *Yesterday*, *Today* or the date wherever the replies move to a new day. A thread that all happened on one day looks as it did.
Long huddles keep their whole transcript
- •Long huddles keep their whole transcript. In a transcribed huddle longer than about five minutes, the speech-to-text service went to sleep every five to ten minutes and restarted at once, so a line being said at that moment could be cut short or lost, both in the transcript and for an agent listening. Now it stays awake for as long as a huddle is being transcribed, and still sleeps between huddles.
You hear an agent come and go
- •You hear an agent come and go. When an agent joined or left a huddle, it showed up on the card and bar without a sound, so a call could gain a listener nobody noticed. Now an agent joining or leaving plays the same sound as a person does.
An agent can sit in a huddle
- •An agent can sit in a huddle. An agent from Workspace settings → Agents can now join a huddle that the person who controls it is in, with
sharedoc huddle join on its own token. It hears the call as it is transcribed, line by line, and writes in the huddle's thread: a Claude Code session can follow a call and post the doc someone mentioned or open the issue someone asked for. It shows on the huddle card and bar with a small badge and whose agent it is, and turns transcription on, since that is how it hears. Anyone in the call can remove it from the bar, and it leaves when its owner does. It doesn't speak yet.
Reply faces show who replied
- •Reply faces show who replied. Under a post, the faces beside *1 reply* used to include whoever wrote the post, so one reply showed two people. Now they're only the people who replied, and the poster appears there only if they replied too.
A big project's file tree no longer goes blank
- •A big project's file tree no longer goes blank. With hundreds of files open in a project's tree, the sidebar could show a long empty stretch below the project's name instead of its files, and scrolling didn't bring them back until you folded the project or reloaded. It happened when the tree started well down the sidebar, under people or another open project. Now the files are always there as you scroll.
The huddle bar names your microphone
- •The huddle bar names your microphone. It used to show only a gear, and its menu said *Default*, so nothing told you a call was on your laptop's built-in mic while your headset sat unused. Now the bar shows the microphone you're on by name ("MacBook Pro Microphone (Built-in)"), on a desktop and on a phone. Click it to switch, and the menu shows that device instead of *Default*.
Quick search keeps its top match
- •Quick search keeps the file you were about to open. In the ⌘K dialog a file matching your words by name shows at once, and the full results arrive a moment later. When they did, a doc that only mentioned your words could take the top spot and the selection with it, so pressing Enter opened the wrong file. Now the selection stays on the row it was on, and a file whose name is what you typed ranks above docs that merely mention it, in quick search and on the search page.
Copy a doc for an agent
- •Copy a doc for an agent. Clicking a doc's name at the end of the breadcrumb used to copy its path on the server (
/data/workspace/…), which an agent on your computer can't open and doesn't recognise. Now it copies a short note an agent can act on: the project and path, the doc's link, the sharedoc files cat command that reads it and the threads list command for its comments, and where a synced copy sits. A picture or file gets the command that downloads it, a folder the one that lists it. ⋯ → Copy for agent does the same, and Copy path is still there for the bare path. Pasted into a message, the note becomes the doc's chip, as the path did.
Audio plays faster or slower
- •A speed button on every audio player. Beside Download, the player now shows its speed: press it to step from 1× to 1.25×, 1.5×, 1.75×, 2×, then 0.75× and back to 1×. Voices keep their pitch. The speed you pick is remembered in that browser: players that load after that, in chat, a doc or the previewer, start at it too.
An open page signs out with its session
- •A page left open signs out with its session. Signing out, resetting your password or changing it in Settings used to leave a page already open elsewhere (another tab, another computer) reading and editing for up to a week, until it was reloaded. Now that page stops within a minute, usually within seconds: it stops receiving updates and can't save, and goes to the sign-in screen, which says you were signed out or that your password was changed. Signing in again brings you back to the same page. Other browsers where you're still signed in carry on as before.
A new doc in a synced folder goes up once
- •A new doc in a synced folder goes up once. A doc moved or copied into a synced folder could be sent to the server twice within a second. It kept one version, but a browser edit made in that second could be overwritten by the second send. Now a new doc is sent once, however many times the folder reports it. Run
sharedoc update to pick it up.
Password resets sign out everywhere else
- •A password reset signs out everywhere else. Resetting your password used to leave every other place you were signed in still signed in for up to 30 days. Now a reset signs out every other session and cancels any other reset links you were sent, and you can choose to sign out the CLI and agents too. Changing your password in Settings signs out your other sessions as well. (A page already open on another device kept editing what it had open until it was reloaded; since v0.92.0 it is signed out too.)
- •You hear about every password change. A reset, or a change from Settings, emails you when it happened, from which browser and IP address, with a link to reset it again if it wasn't you.
- •A reset link asks before switching accounts. Opening a reset link while you're signed in as someone else used to sign that browser into the other account without a word. It now says who you're signed in as and whose password the link resets, and switches only if you continue. A link that has expired says so before you type a new password. Sign-in, sign-up and reset forms posted from another website are refused.
- •Switch account on an invitation works. On an invitation sent to another address, Switch account went back to the app still signed in as the wrong account. It now signs you out and brings you back to the invitation.
- •A sign-in history, for security. Sign-ins, failed attempts, sign-outs, reset requests and password changes are now recorded with the IP address and browser they came from, which are deleted after 90 days. The [privacy policy](/privacy) says so.
Audio files play inline
- •Audio files play where they're shared. A message with an
.mp3, .m4a, .wav or other audio file now shows a player instead of a card you had to open: play, the name, a scrubber, the length (before you press play) and Download and Open in folder. Several stack one under another, below any pictures, so comparing four music options is four rows, not four trips to the previewer. The same in threads and DMs, and on a phone, where the scrubber is big enough for a thumb. - •One at a time. Starting a track pauses any other audio playing on the page, in chat, a doc or the previewer. A huddle's sound is left alone.
- •In a doc, too. A link to an audio file gets the same player under its paragraph, the way a video link does (several links in one paragraph, a row each); the markdown stays a plain link. Dropping or pasting an audio file onto a doc now puts it in
media/ beside the doc, like a video, rather than _inbox. The previewer uses the same player, and a file your browser can't play (an .ogg in Safari) says so and offers the download instead of a dead control. The doc editor's picker on a phone offers audio files as well as pictures and video.
A replaced file reaches every synced folder
- •A file replaced on the server now reaches folders that already had it. When someone replaced a file that isn't a doc (a picture, a video, a
.json or .js), a synced folder that already had the old copy kept it: the server stored the new file without marking it as new, and nothing told a running sync. sync status still said live. Now each replacement is a new version, a running sync pulls it within seconds, and a folder that is already stale pulls the newer files on its next start. Run sharedoc update to pick it up.
A busy inbox no longer slows things down
- •A busy `_inbox` no longer slows things down. Once a workspace's
_inbox held a hundred or so attachments, working out which of them you may see (for search, file listings, comments and live updates) could take half a second or more, nearly all of it spent compiling the query rather than running it. The database no longer compiles queries this way, for any query; the same step had been most of its work in production.
Big projects open fast, and folders can be hidden from the sidebar
- •Big projects open fast. Opening a project, or a doc deep inside one, used to load every file in it, and any new, moved or archived file anywhere in it, or any file saved through the CLI or a sync, made each open sidebar load it all again. Now the sidebar and the page fetch only the folders you open, one level at a time, and a change re-lists only the open folders it touched; editing a doc re-lists nothing. A folder of hundreds of files draws only the rows on screen, so it scrolls smoothly, and arriving at a doc from search or a link scrolls the sidebar to it. A project's file counts, in the sidebar and on its home page, are kept as files change instead of counted each time.
- •Folders start closed. A project shows its top level, plus the folders down to the doc you're on; the folders you open are remembered in that browser. Folders you closed before this update are forgotten, since everything now starts closed.
- •Hide a folder from your sidebar. A folder's ⋯ menu has Hide from sidebar. It's yours alone: everyone else still sees it, and its files still sync, show in search and open from links. Open a doc inside a hidden folder and its folders show dimmed for that visit, with Unhide in the ⋯ menu. A Hidden group at the foot of the project's tree lists what you hid, each with Unhide; it works in
_inbox and in folders shared with you, too. - •Archived loads when you open it. Every expanded project's Archived group shows its count, and lists its files, a page at a time, only once you open it.
- •API:
GET /api/v1/files/lookup?project=&path= answers one path (the file, its .md, a folder, or an archived file) without listing the project; GET /api/v1/files/archived lists archived files a page at a time (limit, cursor); GET /api/v1/files/versions gives the versions of up to 100 files; GET/POST /api/v1/files/hidden lists, hides and unhides your hidden folders. GET /api/v1/files?depth=1 with no filter no longer reads the whole project: at the root it adds total, archivedCount and hiddenCount, a folder you hid carries hidden: true, and thumbs=0 leaves thumbnails out. The tree event now carries { projectId, paths } (just projectId for a big change or _inbox, {} for everything) and is sent only when a file is created, moved, archived or reopened, not on every save.
Sharing with people outside the workspace
- •A share email that didn't go out no longer says it did. When the mail service refused an invitation (or had no key), the Share dialog still said *Invitation sent* and the person waited for an email that never came. It now says *Couldn't email them*, with Copy invite link so you can send the link yourself, and the invitation shows *email not sent* until one does go.
- •Signing in from a shared link lands on what was shared. Opening a doc link while signed out, then logging in, signing up or using Google, used to drop you on your home page. It now comes back to the doc.
- •No access says so. Opening a project or doc you can't see used to send you to your home page without a word. It now says you don't have access, shows which account you're signed in as, and offers Switch account, which comes back to the same link once you've signed in as the other one.
A huddle transcript starts with the first thing said
- •A huddle transcript starts with the first thing said. The transcript doc is now made when the first line is ready, not when transcription is switched on, so a quick huddle where nobody spoke (or one where transcription was only switched on and off) leaves no empty doc behind; the pause and resume notes go in with the first line. And the start of a call is no longer missed: when someone's audio wasn't flowing yet as the huddle began, the hub waited 30 seconds before trying again, losing what they said meanwhile; it now tries again within a second.
Mentions in comment previews
- •A comment that mentions someone reads @Name in the comments panel. When a mention fell around the 140th character of a comment, its card showed the raw
@[Name](user:…) markup, cut off partway. The preview now ends after the whole mention, and the same goes for a channel tag, a link or a [[doc]] reference.
The CLI ignores a repo's .env
- •A repo's `.env` can no longer steer the CLI. The installed
sharedoc used to pick up SHAREDOC_TOKEN, SHAREDOC_HTTP, SHAREDOC_HUB, SHAREDOC_AGENT and SHAREDOC_MODEL from a .env in whatever folder you ran it in, so a repo you cd into could point it at another server, act as someone else, or sign posts as a model that didn't write them. It now ignores them there; export them in your shell to use them. Run sharedoc update to pick it up.
Huddles ding when people come and go
- •Huddles ding when people come and go. A soft two-note ding steps up when someone joins the huddle you're in (you included) and down when someone leaves, so you know who's there without looking. It plays on the speaker you picked for the call, and turning notification sounds off doesn't silence it.
Huddle transcripts
- •Huddle transcripts. A huddle can be transcribed into a doc, live: a line per person per thing said, written into the channel project's
meetings/ folder during the call (a DM's or a private channel's goes to the workspace's attachments, readable only by its members), so people can follow along and agents can read it from disk while the call is still going. The huddle's post and card link it. Workspace settings → Huddle transcripts decides whether new huddles start transcribed (off unless an admin turns it on); anyone in the call can turn it off and on again from the huddle bar, the doc notes each pause, and everyone sees a red *Transcribing* dot while it is on. When the huddle ends the doc gets its end time, length and who was there. No audio is recorded or kept: speech is turned into text on our own server as it arrives and the audio is dropped. The [privacy policy](/privacy) says so, effective today. - •API:
POST /api/v1/huddles/:id/transcription ({ sessionId, on }) turns it on or off for the call, and the hub sends a transcription huddle frame and a huddle.transcription event. Huddles carry transcribing and transcript ({ project, path }); the join answer adds transcription (the call can be transcribed), the heartbeat transcribing and transcript, and GET /api/v1/huddles/config adds transcription.
Huddles connect from strict networks
- •Huddles connect from strict networks. Huddle audio now goes through Cloudflare's call servers instead of directly between browsers, with a relay for networks that block direct calls, so a phone on mobile data, a hotel's wifi or a locked-down office can join a call and be heard. Each person keeps one connection however many people are in the call. Nothing changes in how you start, join, mute or leave a huddle. A page that has been open since before this update is asked to reload before it joins a huddle that's already going. The [privacy policy](/privacy) says so, effective today.
- •API:
POST /api/v1/huddles/:id/join takes transports and answers transport (mesh or sfu); on the SFU the page publishes and pulls audio through POST /api/v1/huddles/:id/sfu/push|pull|answer|close, and the hub sends a published huddle frame. GET /api/v1/huddles/config adds sfu.
Deleting a synced folder no longer empties the project
- •Deleting a synced folder no longer empties the project. Deleting a folder that
sharedoc sync is syncing (or the folder above it) used to archive every doc in it on the server, for everyone, within a second. Now a folder that goes missing (deleted, moved, an unmounted drive) archives nothing and isn't re-created: sync status and project settings → Connections say it is missing, and it resumes when the folder is back. sharedoc sync rm <dir> unpairs it and leaves the server as it is; sharedoc sync archive-missing <dir> --yes archives what it held, if that's what you meant. More than 25 files deleted at once are held until someone says yes (Archive or Keep them on Connections, or sharedoc sync approve <id> --deletes / sync discard <id> --deletes). And a burst of deletes that was archived can be undone in one step: Undo on Connections, or sharedoc sync undo <id>. Run sharedoc update to pick it up.
The Unread page stops re-asking
- •The Unread page stops re-asking, and the sidebar no longer flickers when the server stumbles. An open Unread page fetched its list, the sidebar's channels and the unread counts over and over, hundreds of times a second, for as long as it stayed open. It now asks once when it opens and again only when something changes: a new notification, *Mark read*, or a different filter. A request that fails no longer counts as an empty answer, so a busy or restarting server can't flash the sidebar to *No channels yet.* or the list to *You're all caught up*. The last good list stays up, and a slow, older answer can't replace a newer one. While the sidebar is still loading it shows nothing rather than *No channels yet.*, and after the live connection drops and comes back, the sidebar and counts load again to catch anything that changed while it was down.
Lighter on the network
- •Lighter on the network. The server now compresses what it sends back (file listings, documents, messages) for every client that asks, which is every browser and every
sharedoc version, with nothing to update. A big project's file listing goes out several times smaller. And when files change in one project, only the people and synced folders that can be in it are told to look, not everyone on the server, so a busy project no longer makes every synced folder elsewhere re-read its own files.
The docs say less
- •The docs say less, and what they say is right. A deletion pass over the site: the home page no longer repeats the quick start a third time, and *Share a folder* now covers
sharedoc share and leaves invitations, links and file shares to *Sharing & permissions*. The quick start, *Docs in your repo* and the home page no longer say a big first push waits for approval: it is sent with a warning, and held only in a workspace that has turned large files off, as *Sync* says. The *Slack* page now says that posts made while a connection needs reconnecting are not sent later, and that people who are only in Slack can't be @mentioned yet.
The sync service names itself
- •The sync service names itself on every request.
sharedoc sync run and sharedoc connect now send their user agent on the requests that sync files, not only on the CLI's own calls, so the server can count their traffic correctly. Run sharedoc update to pick it up.
A thread tag says where the thread lives
- •A thread tag says where the thread lives. The chip for
[[thread:id]] showed the first words of the thread's post, which could run to a long sentence and didn't look like a link to a thread. It now says what it points to, the way Slack labels a shared message: *thread in #general*, *thread in a DM*, *comment on plan.md*, with a small reply or comment icon. A Slack-linked channel or DM goes by its Slack name, as in the sidebar. Hover it for the thread's title or first words. GET /api/v1/threads/:id/place also returns where: { kind, name }.
Usage measured per workspace
- •Usage measured per workspace, for running the service. The server now measures, per workspace, the network traffic it serves (by kind: the API, live updates, documents being edited, pages, files it uploads), and once a day each workspace's storage, members and how many people were active. These are counts for the workspace, sent to our own analytics with the workspace's name, never tied to a person. They tell us what each workspace costs to run, and warn us the same day when one suddenly grows. The [privacy policy](/privacy) says so, effective today.
- •The sync service says it is the sync service.
sharedoc sync run and sharedoc connect now add (sync) to their user agent, so the server can tell their traffic from one-off CLI commands. Nothing else changes; run sharedoc update to pick it up.
A thread tag is a link
- •A thread tag is a link.
[[thread:id]] in a message — what sharedoc help gives agents for pointing at another thread — used to show a chip that said *thread* and went nowhere. It now says which thread it is (its title, or the first words of its post) and opens it: a channel or DM post in its conversation with the thread open, a doc comment on its doc. That holds in a channel, a thread's replies and a doc's comments. A thread you can't open, like one in a private channel you're not in, keeps the plain *thread* label. Keep the tag rather than pasting the thread's URL: the tag is what records on the other thread that it was mentioned. - •API:
GET /api/v1/threads/:id/place answers { place: { href, label } } for a thread you can read, and 404 otherwise; ?workspace= keeps a shared channel's link in the workspace you are looking from.
The sync service holds far fewer connections
- •The sync service holds far fewer connections.
sharedoc sync run kept a live connection open to the server for every markdown file it synced, about a thousand on a machine with a few big folders, all the time, whether anyone was editing or not. Now an idle folder holds none. A doc saved in the browser opens a live connection for that doc, so the rest of that person's typing still lands on disk as they type, and it closes after five minutes without a change. A change written from the CLI or the API comes down in one request, about two seconds after it is saved. Your own edits go up as before, and the server's merged text comes back with the upload. sync status shows docsOpen near zero on a quiet machine, and a server restart no longer brings a thousand reconnects from every machine. - •Docs the old sync service left out of date are repaired. In earlier versions a doc's live connection could stop delivering without any error, so a synced folder kept old text while recording it as current, and the next edit there could overwrite changes made elsewhere. On its first sync after the update, the service now finds those docs by their content: an untouched one is brought up to date, and one edited since is merged against the version it actually came from, so nobody's changes are lost.
- •API:
GET /api/v1/files now lists a markdown doc's hash (the sha1 of its text), as it already did for other files, and says docHashes: true. A doc's doc.updated now goes out only once the new text can be read. PUT /api/v1/files/content for markdown answers with contentHash, and with text when the doc now holds other text than was sent (merged, or written out canonically).
Delete a workspace
- •Delete a workspace. The owner of a workspace can now delete it for good: Workspace settings → Delete workspace, at the very bottom. A dialog lists what goes with it — its projects and files (archived ones and
_inbox attachments too), its channels, DMs and messages, everyone's place in it and its invitations — and the button stays off until you type the workspace's slug. Admins don't get the button. You land in your next workspace, or on *create your first project* if it was your last. - •What else a delete takes care of. Its agents are retired the way Delete in the Agents section does it: tokens revoked, what they wrote still signed with their name. Its Slack connections are disconnected and their tokens revoked in Slack. A CLI login that opened only this workspace stops working; one that also opened others just loses this one. People's synced folders stop syncing it and keep their files. Its files and icon are removed from storage.
- •Shared channels go too. A channel your workspace hosts and shares goes for every workspace in it, and the dialog names them. A shared channel you joined from another workspace, you leave: its host keeps the channel, minus your side's threads in a hub channel. The workspace that hosts the Talk channel can't be deleted while the Talk channel points at it.
- •From the CLI:
sharedoc workspaces delete <slug> --dry-run says what would go; --yes deletes it. The API is DELETE /api/v1/workspaces/:slug?confirm=<slug> (?dryRun=1 to preview). Agents can't delete workspaces.
Share a channel with another workspace
- •Share a channel with another workspace. Any channel of yours can now be shared with another team on ShareDoc, the way the Talk channel is shared with us. An owner or admin opens the channel's ⋮ menu → Share with another workspace… and invites someone there by email. They pick which of their workspaces joins, what the channel is called there, and whether all their members can find it or only the people they add; they are in it themselves either way. Nobody gets a seat in the other workspace: each side sees the channel and the people in it, nothing else, and adds its own people. Use it for a dedicated channel with one customer, or with a partner.
- •Open or hub. Before anyone joins, you choose how the channel works. *Open*: everyone in it sees every post. *Hub*: each workspace sees your posts to everyone and its own threads with you, never another workspace's — for one channel with many customers. Once a workspace has joined, the mode stays.
- •An admin's say on both sides. Only owners and admins can share a channel. Someone who accepts an invitation into a workspace where they are a member, not an admin, asks for it: the workspace's owners and admins are notified and approve or decline it under Workspace settings → Shared channels. Invitations last seven days and can be withdrawn.
- •Leaving and removing. Either side can end it at any time: the host removes a workspace from the share dialog, and a workspace that joined disconnects from the channel's ⋮ menu or from Workspace settings → Shared channels. A post in the channel says who left or was removed (in a hub channel only the host and that workspace see it). The workspace that goes loses the channel and its history, its own posts included; the host keeps everything. The Talk channel is turned off the same way, and now says so in the channel too.
- •From the CLI:
sharedoc channel share <channel> --email <addr> [--hub]; sharedoc channel invites lists the invitations sent to you (with a channel: who you have invited); sharedoc channel accept <id> --workspace <slug> [--name <name>] [--open]; sharedoc channel approve [<channel>] [--decline]; sharedoc channel disconnect <channel> [--from <workspace>] --yes. The API is POST|GET /api/v1/conversations/:id/invitations, GET /api/v1/shared-channels/invitations, POST /api/v1/shared-channels/invitations/:id/accept, GET /api/v1/shared-channels?workspace= and POST /api/v1/shared-channels/:id/approve|decline|leave|remove; conversations carry canShare. Agents can't share, accept, approve or disconnect a channel.
Talk to the ShareDoc team, in shared channels
- •Talk to the ShareDoc team. Every workspace now has #talk-to-sharedoc, a channel shared with us, the people who make ShareDoc. Use it for bug reports, ideas and questions. What your team posts there is a thread only your team and ours can see. Our posts to everyone (release notes, outages) show up there too. You can reply to one, and only your team and ours see your replies. Other customers using the same channel never see your threads, your replies, your names or your workspace's name, and you never see theirs. The channel is listed for your workspace's members (not guests) like any open channel, and nobody is added to it, so it stays quiet until you join it or someone mentions you. If your workspace already had a channel by that name, this one is called
#talk-to-sharedoc-2. - •Send feedback. Send feedback in the account menu, or in ⌘K, opens a short form: what happened, an optional screenshot (pasted or picked) and, if you leave it ticked, the page you were on. It posts that, with the app's version, as a new thread in the Talk channel, seen only by your team and ours. Your team can follow up in that thread like any other.
- •You choose whether it's there. Owners and admins can turn the Talk channel off under Workspace settings → Talk to the ShareDoc team, and back on later. Off, your workspace loses the channel and its threads until it is turned back on.
- •Shared channels. The Talk channel is the first *shared channel*: one channel that several workspaces take part in. One workspace hosts it, and each other workspace has it under its own name. Nobody gets a seat in the other workspace: you see the channel and the people in it, nothing else of theirs. The sidebar and the channel header show a shared icon and who it is shared with, people from another workspace carry its name beside theirs ("Jason · Acme"), the member list is grouped by workspace, and nobody sees the email of someone from another workspace. In an *open* shared channel everyone sees every post. In a *hub* channel, like the Talk channel, the host sees everything, filters the channel to one workspace from the header, picks who a new post is for (everyone, or one workspace), and sees the replies to its posts in tabs, *Everyone · Acme (3) · Cockpit (1)*, a reply going only to the tab it's written in. Each other workspace sees only the host's posts to everyone and its own threads, with its own reply counts, reactions and follower counts. Inviting another workspace into one of your own channels comes in a later release.
- •Search, drafts, Saved and the chat mirror know about shared channels. Search finds a shared channel in your workspace, under your name for it, with only what you can see there: another workspace's threads and replies are never hits, never counted and never ranked, and a thread's reply count is the replies you see. A draft or a saved message in a shared channel is kept in your own workspace, on your Drafts page and your Saved list. A scheduled message from a workspace that has since left the channel is not sent through another workspace you're in; it's marked failed. If your workspace leaves the channel, a saved message from it says *no longer available* and shows none of its words. The chat mirror (
sharedoc sync run) writes a shared channel into a folder named after your name for it, with only what you can see, its header saying who it is shared with, and people from another workspace labelled with it. - •API and CLI:
POST /api/v1/feedback sends feedback; GET /api/v1/conversations/locate finds where a link copied from another workspace opens for you; GET /api/v1/conversations/:id/sides lists a hub channel's workspaces for its host. Conversations carry shared, messages and search hits authorWorkspace, and hub-channel threads and messages audienceWorkspaceId. Posts, replies, drafts and saves take workspace (the side you write from), and the host's posts and replies take audience. A CLI token limited to one workspace now reaches the shared channels that workspace is in, drafts included. A hub finds its Talk channel through SUPPORT_CONVERSATION_ID; without it there is none.
Steadier under a slow database
- •Steadier under a slow database. When the database's disk slowed down, every request from the CLI and the sync service waited on a small bookkeeping write, and every open tab re-fetched its Connected folders list again and again. Together they made the whole app wait a minute or more per page. The bookkeeping now happens at most once a minute and in the background, the Connected folders list refreshes at most every few seconds, and the Slack bridge no longer writes to the database on every check.
Delete a project
- •Delete a project. An owner of a project, or a workspace owner or admin, can now delete it for good: Project settings → Delete project. A dialog lists what goes with it — its files (archived ones too) with every version, its comments, its channel and its posts, its members, invites and join links — and the button stays off until you type the project's slug. Everyone loses it at once; tabs that had one of its docs open are disconnected, and the files are removed from the server and its storage. Posts in other channels that only carried it as a label stay where they are and lose the label. People's synced folders stop syncing it and keep the files they already have. The workspace's
_inbox can't be deleted. - •From the CLI:
sharedoc projects delete <slug> --dry-run says what would go; --yes deletes it. The API is DELETE /api/v1/projects/:slug?confirm=<slug> (the slug, typed back; ?dryRun=1 to preview). Agents can't delete projects.
The comments panel closes on a doc without comments
- •The comments panel closes on a doc without comments. With the comments panel open, moving to a document that has no open comments left the panel open and empty until you closed it. It now opens only on documents that have open comments, and it comes back by itself on the next one that does. The comment button in the header still opens it anywhere, to start the first comment.
Removal from a workspace closes its DMs
- •Removal from a workspace closes its DMs. Someone removed from a workspace could still read and post in their old direct and group messages there from the CLI or the API, given the conversation's id, though the sidebar no longer showed them. New messages in them still reached them as notifications and typing indicators. Now a direct or group message is open only to people who are still in its workspace, as a channel already was. The conversation itself is kept, so someone who comes back, even as a guest, finds the same DMs with their history.
Your agent can set share-doc up from one link
- •Your agent can set share-doc up from one link. Tell your coding agent *“Set up share-doc for this repo: https://sharedoc.brightmotion.io/setup.md”* and it takes it from there: it asks you its questions in one message (which workspace, which project or a new one, which folder, whether to keep the sync running, whether to mirror the chat), installs the CLI, sends you a login link, pairs the repo's
docs/ folder, adds it to .gitignore and CLAUDE.md, starts the sync service and records the pairing in the project's sharedoc-instructions.md. The only thing you do is approve the login in your browser and paste the code back. Every command in the runbook is checked against the CLI's own command list, so it can't send an agent to a command that doesn't exist. - •Copy the prompt from the project. A project's home page, under For agents, now has that line with the project and workspace filled in, so the agent skips those questions. The quick start, *Working with agents* and the installer point to it too.
- •An agent can log you in.
sharedoc login --no-wait prints the link to approve and exits; sharedoc login --code <code> finishes with the code the page shows. That works even for an agent whose shell runs one command at a time and so can't answer a Code: prompt. The share-doc skill no longer tells agents to stop and ask you to run sharedoc login yourself, and the authorize page says the code can go to the agent that asked. - •A failed re-login no longer logs you out.
sharedoc login --force used to revoke your saved login before the new one went through, so an expired or mistyped code left the machine logged out. It now revokes the old login only once the new one has arrived.
A busy server no longer blanks the app
- •A busy server no longer blanks the app. When a synced folder pushed a few hundred files at once (a video render's frames, say), every open tab refreshed once per file. The server slowed to several seconds a page, each refresh cut off the one before it, and when one finally failed the whole window went to a bare *An unexpected error occurred.* until a reload. A burst of changes now refreshes each tab once, and never more often than every 2 seconds while it lasts; a refresh waits for the one in flight instead of cutting it off.
- •When a refresh does fail, the app stays. The sidebar stays usable and only the page shows *Lost touch with the server* (or *The server is having trouble*). It tries again by itself after 1, 3 and 10 seconds and puts the page back as soon as the server answers, or you can press Try again. A call in progress still ends when this happens, as it did before. A page that is missing or not shared with you says so instead, and a page that breaks on its own says *Something went wrong on this page*. The sidebar's document counts and connected folders quietly keep what they showed if their background refresh fails. The last-resort error page has a Reload button.
Workspace icons
- •Workspaces can have their own icon. An owner or admin opens workspace settings and chooses Add an icon under General: pick a PNG, JPEG, WebP or an iPhone photo, then drag and zoom to crop it to a rounded square. It replaces the coloured initials square in the sidebar's workspace picker and switcher, at the top of workspace settings and on the CLI sign-in page. Members' open tabs pick up a new icon straight away, without a reload. Change icon replaces it and Remove icon brings the initials back. From the CLI:
sharedoc workspaces icon <slug> ./logo.png, or --remove. Members who aren't an owner or admin see the icon but can't change it.
The workspace name comes first
- •The workspace name is at the top of workspace settings. A new General section comes first, right under the header, for owners and admins: the name with a Save button, and the workspace's address (
/w/<slug>) with a note that renaming never changes it or any link. It used to be the last thing on the page, below Members, Projects and Storage, so it was easy to miss. Link straight to it with /w/<slug>/settings#general. - •Rename from the workspace menu. The menu under the workspace name in the left bar has a Rename workspace item next to *Workspace settings*. It opens settings with the name box ready to type in.
- •Name your team when you start. *Create your first project* now has an optional Team or company name field, which becomes your workspace's name. Leave it blank and the workspace is named after you, *Ada's workspace*, as before.
- •Rename instead of a second workspace. If the only workspace you own still has that made-up name and you type a new workspace name in the menu, share-doc first asks whether to rename the one you have. Create a second workspace still makes a new one.
Guests see only the channels they are added to
- •Guests see only the channels they are added to. A workspace guest could read every open channel in the workspace,
#general included, without being in any of them: the channels were in their sidebar, in sharedoc channels list and in search, and they could join any of them. Now a guest is in a workspace channel only if someone adds them (Add people on the channel, or sharedoc channels add). Once added, they read and post like anyone else. Project channels are unchanged: they still follow the project. - •No channel adds a guest automatically. A guest who joins the workspace is not put in
#general, a new public channel does not take them in, and they cannot join one on their own. Guests who were already in open channels have been taken out of them, so add them back where they belong. - •Changing a role moves the channels along. Making a guest a member puts them in
#general, as joining does. Making a member a guest takes them out of every open workspace channel. Their private channels and project channels stay as they are. - •Leaving a workspace takes you out of its channels. Someone removed from a workspace is taken out of every channel in it, private ones included, so coming back later (as a guest, say) brings none of them back. And a channel stays closed to anyone no longer in its workspace, even if they were in it.
Sort the board by priority
- •Sort the board by priority. A new Sort by menu on the [board](/docs/features/statuses) orders each column by the priority at the start of a doc's name:
P0-hotfix before P1-guests-read-open-channels before P2-pricing, and docs with no priority at the bottom. Docs of the same priority stay most recently changed first, which is still the default order. The choice is part of the board's address (sort=priority), so a sorted board can be linked, and each workspace remembers it.
Large files just sync
- •Large files just sync. Every workspace now accepts large files, and it is on for every workspace that already exists. A synced folder sends any file up to 50 GB without stopping to ask: no more *waiting for approval* on a big video, and nothing held until someone runs
sharedoc sync approve. Turn it off under workspace settings → Storage → *Accept large files*. Off, the old per-file limit and the ask-first size apply again. - •A big new folder warns you and keeps going. Connecting a folder whose first push is over 50 files or 20 MB used to stop it before anything was sent:
sharedoc share refused without --yes, and sync add and connect left the folder *waiting for approval*. One video was enough to trip it, and nothing synced until someone noticed. Now the CLI prints what is about to go up, with a warning and a pointer to .sharedocignore, and sends it. Folders that were already waiting have been let go. - •A slow answer from the server no longer pauses a synced folder. The sync service re-checks each folder's settings with the server every 30 seconds. If one of those checks timed out, the folder stopped sending until the next check got through. Now it keeps syncing on the settings it last read for up to 10 minutes, and logs that it is doing so. Only an outage longer than that pauses the folder.
- •The server decides all of this, so sync services already running pick it up without an update.
What's new, from the update notice
- •The update notice links to what changed. When a new version ships, the notice at the bottom of the left bar (*A new version is available*) now has a What's new link next to it. It opens the [changelog](/changelog) in a new tab, so you can read what's new before you Refresh, and anything you were in the middle of stays where it is.
A film on the front page
- •A film on the front page. Under *The problem* on [/home](/home), a 77-second film shows what share-doc is for: docs were made for people, agents work in files, and share-doc keeps both in sync. It plays in our own player, with captions on by default (the CC button turns them off), a scrubber, mute, full screen and keyboard controls (space, ←/→, M, C, F). Nothing downloads until you press play. Link straight to it with [/home#film](/home#film).
- •The public site's analytics now count how the film is watched: play, pause, seeks, how far in (25, 50 and 75 percent, and the end), captions, mute and full screen, and the seconds watched. The [privacy policy](/privacy) says so.
Synced folders never stop sending
- •A synced folder never stops sending. On a Mac, a synced folder could stop uploading new and edited files, while it went on pulling everything from the web and
sharedoc sync status said *live*, until the sync service was restarted. The file watcher watched every file and folder separately, and once the synced folders held more than about 4,000 of them between them it stopped reporting anything at all, without an error. A burst of new screenshots from an agent was enough to cross that line, and a restart crossed it again within a minute. Each folder now has a single watch, however many files it holds. - •A missed change goes up within a minute anyway. The sync re-reads each folder once a minute and sends anything the watcher did not report: new files, edits and deletes. It checks each file's size and modification time, so a file is read only when one of them has changed. If more than 25 synced files disappear at once without the watcher seeing them go (an unmounted disk, a moved checkout), nothing is archived on the server; the log says so instead.
- •`sharedoc sync status` shows when each folder was last re-read (*local scan*). It warns when the watcher has missed changes, and when the re-read itself has stopped. The sync log names every file the re-read had to send.
- •The connection to the server drops and reconnects every 15 minutes. After each reconnect the sync now checks the project for files added during the gap.
v0.73.0
September 30, 2026
Usage analytics
- •We now measure how share-doc is used, with AgentHog, Brightmotion's own analytics service. The public pages (the home page, the docs, the changelog, sign-up and log-in) count visits, clicks and scroll depth. Inside the app we record which *kind* of page you opened (a doc, a channel, the board — never which one) and named actions such as signing up, creating a project, connecting a folder, sending a message or opening search, with counts and types but never titles, paths, names or anything you wrote. Details, and how to opt out, are in the [privacy policy](/privacy), updated today.
- •The CLI reports its commands. After each command,
sharedoc tells the server it is logged in to the command's name, the names of the flags used (not their values or any arguments), how it ended and how long it took, with its version and OS. It never slows a command (one request, capped under a second) and never prints anything. sharedoc telemetry off, SHAREDOC_TELEMETRY=0 or DO_NOT_TRACK=1 turns it off; sharedoc telemetry says whether it is on. - •A browser that sends Global Privacy Control or Do Not Track is not measured at all.
v0.72.0
September 30, 2026
A front page and a docs site
- •A new front page.
/home now says what share-doc is and why in one screen: the product itself in a browser frame, the problem it solves (docs in git that only engineers read, docs in Notion the agent can't see), how the folder, the browser and your agent fit together, the editor, the chat, the board and the raw markdown, what your agent gets, a comparison, the four-command quick start and the questions people ask first. It follows your light or dark theme and works on a phone. - •Docs at `/docs`. A proper docs site with a sidebar, *On this page* and next / previous: a five-minute Quick start, Concepts, four guides (*Docs in your repo*, *Working with agents*, *Agents of their own*, *Share a folder*) and a page for each part of the product: the editor, comments and history, chat, statuses and the board, sync, files, sharing, search, notifications and Slack. Screenshots come from a demo workspace.
- •The CLI reference, rendered.
/docs/cli-reference lists every sharedoc command with its arguments, flags, examples, JSON shape and API route, plus global flags, exit codes, environment and config files, and a filter box. It is built from the CLI's own command table, so it matches the release. The plain-text /docs/cli for agents is unchanged. - •
/start, /basics and /cli-overview now redirect to the Quick start, Concepts and the CLI reference, so old links and welcome emails keep working. The book icon in the app's header opens /docs.
v0.71.2
September 29, 2026
Unread stays unread in a tab you aren't looking at
- •A channel you left open somewhere no longer reads itself. With "mark read when I open a channel or thread" on, a channel open in a browser tab marked every new post read the moment it arrived, even with the tab in the background, the window behind another app, or the computer locked. The channel then showed no unread dot anywhere else, so posts went by without you seeing them. Now a channel (and an open thread) is marked read only while its tab is in front and its window has focus. Come back to it and it catches up then.
v0.71.1
September 28, 2026
Replaced pictures show up
- •Replaced pictures show up in docs. Replace an image a doc shows (a new screenshot synced over the old one, the same file name) and the doc now shows the new one: straight away in a doc you have open, and on the next load everywhere else. It used to keep showing the old picture for up to an hour, even through a reload, while the file itself and search already had the new one. Nothing changes in the markdown:
 stays exactly as written.
v0.71.0
September 28, 2026
Turn #general off
- •Turn #general off. Workspace settings has a #general switch for owners and admins. Turned off,
#general leaves everyone's sidebar and the # channel picker, takes no new posts or replies (from the web, the CLI or an agent, which are told it is turned off), and stops being mirrored to ~/sharedoc/chat/. Nothing is deleted: turn it back on and it comes back with its history, for everyone. - •The chat mirror picks up a restored channel straight away. Un-archiving a channel (or turning #general back on) used to wait for the mirror's next 10-minute check.
v0.70.0
September 28, 2026
Link previews
- •Links to web pages show a preview. Paste a link to a web page in a message and a card appears under it, the way Slack does it: the site with its icon, the page's title (a link), a few lines of description, and its picture: full width when it's a big one, a small thumbnail beside the text when not. A YouTube link shows the video's title, channel and thumbnail, and pressing play plays it right in the message. Up to three links per message get a card; a link inside
code doesn't, and links to share-doc's own docs keep their doc cards. share-doc fetches the page for you, so the linked site never sees who is reading, and a page with nothing to show (or one that can't be reached) simply gets no card. - •Close a preview you don't want. Hover a preview and press ×. On your own message that removes it for everyone reading the conversation (the link itself stays in your message). On someone else's it hides it just for you, in this browser, and nobody else's view changes.
v0.69.1
September 28, 2026
Emoji picker on a phone
- •The emoji picker stays in view on a phone. Tapping ☺ to react to a message on an iPhone focused the picker's search box, so the keyboard came up and covered the emoji you'd opened it for. On a phone or tablet the picker now opens without the keyboard: tap an emoji straight away, or tap the search box to search. When the keyboard is up (you tapped search, or opened the picker from the message box while typing) the picker moves up above it instead of sitting behind it. On a computer the search box still has the cursor as soon as the picker opens.
v0.69.0
September 27, 2026
Approvals for big syncs
- •Approve a big new folder from the web. When a folder is paired with
sharedoc sync add (usually by your agent) and its first push is big (over 50 files or 20 MB), nothing is sent until someone says yes. It used to stop in the terminal and wait for --yes, where you'd never see it. Now the folder is registered and waits: project settings → Connections shows what it would send (how many files, how big, which folders) with Approve and sync, Choose folders first and Don't sync. Settings → Devices marks it *Waiting for approval*. --yes still sends it straight away. - •Big files ask first. A synced folder now waits for a yes before it uploads or downloads a file over the workspace's ask-first size (1 GB by default). The files waiting are listed on project settings → Connections, each with Approve, plus Approve all. An approved file goes within seconds. If it changes after being approved, it asks again. Set the size under workspace settings → Storage, or 0 to never ask. Uploads in the browser and
sharedoc files put never ask: they're a yes already. - •The CLI says what is waiting and how to approve it, so an agent can tell you.
sync add prints the size of the first push, the web link and the command, and its --json carries the same as approval. The sync log names each big file it is holding. sync status lists what is waiting. sharedoc sync approve <id> approves a folder; add --file <path> or --held for big files.
v0.68.0
September 27, 2026
Big files
- •Big files sync. A connected folder now sends and receives files up to your workspace's per-file limit, 5 GB by default, where it used to leave anything over 25 MB behind without a word. Video, audio, design files, exports: the kind of thing git handles badly. Big files go straight to storage in 16 MB parts, several at a time. A part that fails is retried by itself, and a sync interrupted halfway through a 4 GB video picks up where it stopped the next time it runs, instead of starting over.
- •Uploads in the browser go past 250 MB too. Dropping or uploading a big file goes up in parts, with progress, and a flaky part is retried rather than failing the file.
sharedoc files put and --attach send big files the same way. - •Syncing big files is gentle on your computer. A file is never held in memory: sending or receiving a 4 GB file uses about the same ~300 MB as a small one. A file still being written (a video export, a render) is sent once it has stopped changing, not half-finished several times over. A download is written beside the file and swapped in at the end, so an interrupted one never leaves a broken copy under the real name. An unchanged file isn't re-read end to end on every start.
- •Storage in workspace settings. Workspace settings has a Storage section: how much the workspace holds against its limit, split into open files, archived files and chat attachments, with the biggest projects listed. Owners and admins set the largest file (5 GB by default, up to 50 GB) and the workspace total (100 GB by default). A file over a limit is refused before anything is sent, and says which limit and by how much. A synced folder names the file it is leaving alone once, not on every pass.
- •Uploads nobody finished (a tab closed halfway, a sync stopped for good) are cleared out of storage after a day, so they stop taking up space.
v0.67.1
September 25, 2026
Paste a path, get a link
- •Paste a doc's path and get a link. Copy path on a doc, the name in its header, or an image or video, then paste it into a message: it becomes the doc chip, the same as picking the doc from
[[, with the card under the message once it is sent and a click that opens it. A path into another project links to that project's doc. So does a doc's page link from ⋯ → Copy link, pasted on its own. Inside code the path stays text, and so does a path in the middle of a longer paste.
v0.67.0
September 25, 2026
Editing docs on a phone
- •Indent and outdent on a phone. Editing a doc on a phone or tablet now brings up a formatting bar that sits just above the keyboard. It has outdent and indent, the same as ⇧Tab and Tab on a computer, so you can nest a list item three levels deep and bring it back out without a Tab key. The bar also has the heading level (tap H to step through H1, H2, H3 and back to text), bullet, checklist and numbered lists, and undo / redo. Tapping a button keeps your place and the keyboard open. Done puts the keyboard away, and the bar goes with it. Nothing changes on a computer.
- •Collapsible headings work on a phone. The chevron that folds a section away used to sit in the left margin, which a phone doesn't have, so the toggles seemed to be missing. On a narrow screen it is now just before the heading, always showing, with a finger-sized target. Folding is still only on your screen and never changes the doc.
v0.66.0
September 25, 2026
Mermaid diagrams
- •Mermaid diagrams are drawn. A fenced block tagged
mermaid (a flowchart, a sequence diagram, state, gantt, ER, every kind mermaid knows) now shows as the diagram, in the doc, in a past version in History, in a project's README and in chat, instead of forty lines of arrows in a grey box. Subgraphs, quoted labels and <br/> line breaks come out as they do on GitHub, and the diagram follows your light or dark theme. A wide one is scaled to the column; Full size opens it at its real size in a window of its own. - •The source is one click away. In a doc you can edit, Edit source (or a click on the diagram) opens the text under the diagram. It redraws when you pause typing, and goes back to the diagram when you leave it. It is an ordinary code block in the file, so collaboration, undo and the raw view work as before, and the markdown changes only by what you typed. Reading a doc, Show source toggles it. In chat, the code button next to wrap and copy swaps in the source.
- •A diagram with a mistake shows it. A source that doesn't parse is shown as text with mermaid's error under it, and while you are typing the last good drawing stays up above the error. Diagrams are drawn in mermaid's strict mode, so a
click directive or a javascript: link in one runs nothing. The diagram code is only downloaded when a diagram is on screen; a page without one loads none of it.
v0.65.0
September 25, 2026
Saved items and reminders
- •Save a message or a doc for later. Point at a message and press s (or the new bookmark in its action bar) and it goes on your Saved list, in the sidebar under Board. Only you can see the list. A doc's ⋯ menu has Save for later, and a heading's block menu (right-click its handle) has Save section for later. The same action unsaves, and a saved message says *Saved for later* above it.
- •Remind me about this. A message's ⋯, a doc's ⋯ and a heading's block menu offer *In 30 minutes*, *In 1 hour*, *In 3 hours*, *Tomorrow*, *Next week* (each showing the time it lands on, with tomorrow and next week at the start of your working hours), or a custom time. When the time comes you get a Reminder in Unread with Mark done and Remind me again, plus a push if you have browser notifications on. Like every other notification, the push waits out snooze and your working hours. A reminder that comes due while the server is down arrives as soon as it is back. Setting a new time replaces the old one.
- •The Saved page lists Reminders first, soonest at the top with the ones that are due marked, then everything else you saved, newest first. A row opens the message or the doc at that section, and can be marked done, given a new time or removed. Every change can be undone from its toast. The sidebar's Saved shows how many reminders are due. A doc is kept by its identity, so it survives a rename or a move. Something you can no longer open (a private channel you left, a doc you lost access to) reads *No longer available*, and so does its reminder, without its words.
- •Right-clicking a heading's handle now copies that section and its bookmark reliably. The menu could resolve to the gap just before the heading and copy the page link instead.
v0.64.4
September 25, 2026
↑ to edit
- •↑ edits your last message. In an empty message box, press ↑ and your newest message in that channel, DM or thread opens for editing, as in Slack. Someone else's newer message is skipped. Escape or Save puts you back in the box. With text in the box, ↑ moves the caret as before, and with the @ / # / [[ / emoji menu open it moves through the menu.
v0.64.3
September 25, 2026
Reply bar stays put
- •The reply bar under a message no longer jumps when you point at it. In a narrower window (half a laptop screen, or with the thread panel open) hovering 1 reply · Last reply … · View thread used to push it onto two lines, so the message under the mouse grew and the list jumped. Now the bar keeps View thread's room all the time and never wraps; when the column is short of space, *Last reply …* is trimmed and then dropped, then View thread.
v0.64.2
September 25, 2026
Purple buttons on hover
- •Filled buttons stay purple when you point at them. Hovering a purple button (Add to Slack, Save, a dialog's main action) used to turn it the pale grey of an ordinary button's hover under its white label, so the label all but vanished. Now it darkens a shade and stays readable, in light and dark themes; a disabled one doesn't change.
v0.64.1
September 24, 2026
Slack mark
- •A small Slack mark shows where Slack is. The sidebar's Slack · <team> header has Slack's logo beside its name, and the composer of a two-way Slack conversation (and of a thread in one) has it beside Send, so it is plain that what you post goes to Slack too. Its tooltip says where: *Sends to #design in Brightmotion Slack*. It shows only where your post really goes to Slack: not on a read-only or archived one, not while the connection or the link needs attention, not on someone else's Slack conversation you were added to, and never on share-doc's own channels.
v0.64.0
September 24, 2026
Slack in the sidebar
- •Slack gets its own place in the sidebar. Each connected Slack workspace is a Slack · <team> section under Channels, with its conversations named as in Slack (
#design, Colin Wu, Colin, Dana) instead of sitting among your channels as slack-brightmotion-design (docs/spec-slack-interop.md step 3.7). The section collapses like the others; its + starts a new Slack DM or group DM. A read-only conversation has a small eye, one with a problem (the connection needs reconnecting, you left it in Slack) an amber dot, and while history is still coming in a Backfilling pill under the header says which ones. - •Removed and disconnected Slack conversations can be read again. Each Slack section has an Archived list: conversations you unticked, or whose workspace you disconnected, open with their whole history, read only. A disconnected workspace keeps its section, marked *disconnected*, until you remove it in Settings.
- •A read-only Slack conversation has no composer. In its place: *Read only — change in Settings → Slack*, so nothing you type there quietly stays behind. An archived one says it is no longer linked.
- •Save a Slack file to a project. Files from Slack have a Save to project… button (on the file's card, and in the picture viewer): pick a project and a folder, and a copy lands there, where everyone who can open that project can see it. It is the one way a Slack file becomes a share-doc file; nothing is posted.
- •Messages from Slack say via Slack, and a Slack conversation's tab and breadcrumb use its Slack name.
- •`sharedoc slack links` lists the conversations a connection brings in and changes one:
--set "#design" --direction in|both|off makes it read only, two-way, or removes it, and links one that isn't linked yet. `sharedoc slack status` shows how each connection and conversation is doing: last event and post, direction, health, how far the history has come in. /skill.md tells agents how Slack conversations work.
v0.63.9
September 24, 2026
New Slack message and disconnect
- •Start a Slack conversation from share-doc. New Slack message in … in ⌘K, or New message on a connection in Settings → Slack, opens a people picker over that Slack workspace: search by name, @handle or email; people who are also in your share-doc workspace are marked and listed first; bots and deactivated accounts are left out (
docs/spec-slack-interop.md step 3.6). One person opens your DM with them, two to eight a group DM. Start brings it in as a private share-doc conversation with its history and puts you in the composer. A DM you had already linked just opens, and one you had removed comes back. Nothing is sent to Slack until you post. - •Disconnect a Slack workspace. Settings → Slack → Disconnect asks first, naming the conversations that go. Then Slack revokes share-doc's access, the token is deleted, and those conversations are archived here with their history (pictures and files from Slack stop showing in them; their links to Slack stay). Nothing changes in Slack. Connect the same Slack account again later, and Edit links can tick them back in, history included; a DM comes back by itself the next time someone writes in it. A disconnected workspace stays on the page until you remove it.
- •`sharedoc slack people [query]`, `slack dm @colin @dana` and `slack disconnect <workspace> --yes` do the same from the CLI, for agents too:
slack dm prints the conversation to post into with channel post.
v0.63.8
September 24, 2026
Files go to Slack
- •Files you send in a linked Slack conversation reach Slack. A picture or file you paste, drop or attach in a two-way Slack conversation now goes to Slack with your message, as one post, the way it would if you had sent it in Slack (
docs/spec-slack-interop.md §8.2). In share-doc it stays where it always lands, in _inbox, private to that conversation. A file that is only tagged, such as one from a project or from another conversation, still goes as a link. If Slack won't take a file (too big, or files are turned off in that Slack), the message goes anyway with a link to the file, and a line under it says which file didn't make it.
v0.63.7
September 24, 2026
Slack history and files
- •A linked Slack conversation arrives with its history. Ticking a channel or DM in Settings → Slack now brings in its history — threads and reactions included — newest first, so the channel is useful right away (
docs/spec-slack-interop.md step 3.5). Under the list you choose how much: the last 30 days (the default), the last 7, or none. A DM someone starts with you in Slack brings the 7 days before it. Re-ticking one you had removed fills in what was said meanwhile, as far back as you choose, and puts its reactions right. None of it notifies you or lands in Unread; what you had already read in Slack arrives read. Conversations linked before this release are filled in once, too. - •Files from Slack show as files. A picture or video posted in a linked Slack conversation now shows under the message like any attachment (pictures open full size); other files show as a chip with Open in Slack and Download. They stay in Slack: share-doc fetches them when you look, with your Slack connection, and only for people who can open that channel, so a file deleted in Slack disappears here too. The message keeps its link to the file in Slack, which is what you see if the file can't be fetched (while the connection needs reconnecting, say).
- •`sharedoc slack file <message-id>` lists the Slack files on a message, and
--index n downloads one, for agents reading a Slack channel from the chat mirror.
v0.63.6
September 24, 2026
Slack goes both ways (behind the scenes)
- •Under the hood: what you write in a linked Slack conversation now goes to Slack as you (
docs/spec-slack-interop.md step 3.4). A post, a thread reply, an edit, a deletion or a reaction you make in its share-doc channel happens in Slack within seconds, and doesn't come back as a copy. Mentions of people who are in that Slack go out as real Slack mentions. Files are not sent yet. - •Each linked conversation is two-way or read only. Settings → Slack → Edit links has a *Two-way* / *Read only* choice on every ticked conversation; new ones are two-way, and a DM someone starts with you in Slack links itself as two-way. On a read-only one, or when someone you added to the channel posts, the post stays in share-doc and a line under it says it was not sent. A post Slack refuses gets a *Not delivered to Slack* line saying why, after three tries.
- •Reading a linked conversation here marks it read in Slack, a few seconds later, for two-way and read-only ones alike.
- •If Slack stops accepting your connection, you're told once — a notification pointing to Settings → Slack → Reconnect — and nothing more is sent until you reconnect. The Slack card also shows when something was last posted.
v0.63.5
September 24, 2026
Files sent in a DM stay in the DM
- •A file you send in a DM stays in the DM. Anything pasted, dropped or attached in a direct message, a group DM, a private channel or a comment on a doc in a private project still lands in
_inbox, but now only the people who can read that conversation (or that doc) can see it — in the _inbox folder view and its counts, the sidebar's *n docs*, ⌘K, search, the [[ file picker, sharedoc files list / files cat, previews and downloads, the live updates and a synced _inbox folder. Before, everyone in the workspace could open it. Workspace owners and admins get no exception, the same as for the DM itself. - •Moving it into a project is how you share it wider. Move to project… takes the file out of
_inbox, and from then on it follows that project's access like any other file. Renaming it inside _inbox, or saving a new version of it, keeps it private. Someone you share the file with directly can still open it. - •Tagging a private file in an open channel doesn't open it up. People in the channel see the tag, but not the picture or the file behind it. A file posted in a public channel is still visible to the whole workspace, as before.
- •`sharedoc dm`, `channel post`, `thread create`, `thread reply` and `draft create` with `--attach` follow the same rule — a Markdown file included, which also stays out of
sharedoc docs for everyone else. The CLI now tells the hub which conversation or doc the file is for; a draft to people (sharedoc draft create @bob @ada --attach …) opens their DM or group first, so its file belongs to them from the start, before and after it is sent. - •A file dropped into a doc follows the doc. A file that isn't a picture or a video, dropped into a doc in the editor, lands in
_inbox as before, but if the doc is in a private project only the people who can open that doc can open the file. A doc in a project the whole workspace can open is unaffected, and Move to project… widens it the same way. A picture pasted into a doc that is itself a private attachment — a Markdown file someone sent you in a DM — is exactly as private as that doc, and stays so if the doc is later moved into a project. A file attached to a thread on a private project (rather than on one of its docs) is for the project's members only. - •Other people's private comments stay out of your view. A file's backlinks now only quote messages from conversations and comment threads you can read. You're no longer notified about a comment on a doc you can't open, or a message in a conversation you're not in — even if someone @-mentions you there. And the live "comments changed" signal, which names the doc, now only goes to people who can read it.
- •Links to a file from a DM, a private channel or a private project's doc expire within 20 minutes, even when you ask for a longer
--ttl, and so do the links behind a video you're watching. Files from public channels and workspace-wide projects keep the usual lifetimes. Files uploaded before this release stay visible to the whole workspace.
v0.63.4
September 24, 2026
No more /automation page
- •The /automation page is gone. It described how to run an agent as itself, and that is now a doc for our own team rather than a public page. /automation now shows the not-found page, and the home page and the CLI overview no longer link to it. Agents themselves are unchanged:
sharedoc agents create, their tokens and Workspace settings → Agents work as before.
v0.63.3
September 24, 2026
Slack messages come in (behind the scenes)
- •Under the hood: messages now flow in from a connected Slack workspace (
docs/spec-slack-interop.md step 3.3), still switched off on this server. Posts, thread replies, edits, deletions and reactions in a linked Slack conversation arrive in its private share-doc channel within seconds, under the Slack person's name; a mention of you and a message in a linked Slack DM show up in Unread like any other. Reading a conversation in Slack clears it here within about a minute. A DM someone starts with you in Slack links itself on its first message (turn that off per workspace). Files stay in Slack and arrive as links to them. - •Marking a conversation read up to a point leaves what came after it unread. Marking read with an explicit time (
at) used to clear every mention and DM notification in the conversation, including ones newer than that time; now it clears only those up to it.
v0.63.2
September 24, 2026
Slack in Your settings
- •Slack has its own section in Your settings. It lists the Slack workspaces you've connected, how many conversations each brings in and which share-doc workspace they go into, and flags one that needs reconnecting. Manage Slack opens the full page, and Add to Slack connects another workspace. It used to be a small button among the notification settings.
v0.63.1
September 24, 2026
Slack, connected (behind the scenes)
- •Under the hood: the next step toward connecting a Slack workspace (
docs/spec-slack-interop.md). Settings → Slack can connect a workspace through Slack's own consent screen and pick which channels and DMs to bring in, each as a private channel only you can see; sharedoc slack connect and sharedoc slack list do the same from the terminal. Messages don't flow in yet, and it stays switched off on this server until they do. - •An archived private channel stays closed. Creating a channel with the same name as an archived private channel you were never in brought it back with you as its owner, history included. That name now counts as taken; the channel's own members can still bring it back by creating it again.
v0.63.0
September 24, 2026
Huddles survive a reload
- •A reload no longer loses the huddle. Reload share-doc mid-call and the huddle bar comes back as *You were in this huddle* with Rejoin and Leave, and so does the huddle's card. Rejoin takes your seat back with one click (the microphone still needs that click — nothing turns it on by itself); Leave takes you out so the others see you go at once.
- •No more "in another tab" with no way out. If the call is running in another tab or window of the app, the card now says so with Move here (the call moves to this tab and the other one lets go) and Leave (the other tab hangs up). A tab that crashed or was killed without closing properly no longer blocks you for 25 seconds: share-doc checks whether that tab is still there and, if it isn't, offers Rejoin and Leave straight away.
- •In the call on another device? The bar and the card say *You're in this huddle in another window or device*, with Move here and Leave.
- •The last one to click Leave ends the huddle. It used to stay live for another minute after everyone had left. A room emptied by a reload or a dropped connection still waits a minute, so a reload doesn't end a two-person call.
- •Links to share-doc in messages open in the same tab. Clicking a doc, folder or channel link someone posted used to open a second copy of the app in a new tab; it now opens in place, so a huddle carries on. ⌘/Ctrl-click still opens a new tab, and links to other sites still do. Tapping a notification also switches pages in place instead of reloading the tab, which used to drop the call.
v0.62.3
September 24, 2026
More emoji
- •About 75 more emoji. The reaction picker and the
:name: autocomplete gain the faces, hands and symbols people react with most in Slack — 🤩 🙄 🤨 ✋ 🙇 🤘 🥹 ☑️ 🔄 🧵 and more — each under the name Slack uses, so :star-struck:, :face_with_rolling_eyes: and :raised_hand: work as you'd type them there. - •Under the hood: groundwork for connecting a Slack workspace (
docs/spec-slack-interop.md). The database has the tables for Slack connections, linked conversations and caches of Slack people and custom emoji; a reaction can belong to someone without a share-doc account, which is how a Slack person's 👍 will show on a bridged message; and reacting with an emoji you already reacted with, or removing one you hadn't, no longer writes a line to the activity log. Nothing Slack-facing is switched on yet.
v0.62.2
September 24, 2026
A privacy policy
- •A privacy policy at /privacy. What share-doc collects, why, which companies help run it, how long it is kept and how to have it deleted — including what happens with Slack data once you can connect a Slack workspace. Linked from the footer of
/home.
v0.62.1
September 24, 2026
Log in from the front page
- •Log in from the front page works. Signed out, the Log in link at the top right of
/home (and the one in its footer) took you back to the same page instead of the login form. Both now open the login page.
v0.62.0
September 24, 2026
A menu for files, and one-tap save on phones
- •A ⋯ menu on every image, video and file. Open a file and the bar above it has the same three dots a doc's header does: Copy link (the file's page), Copy path (where it lives in your synced folder), Share… (the same dialog as the header's Share), Download and Archive. Archive asks first and leaves the file readable at its URL with Reopen above it, as a doc does. Share and Archive only show when you can use them.
- •One tap saves a video or picture to your phone. On a phone, an image or video now has a big Save video / Save image button across the bottom. On iPhone and Android it opens the share sheet with the file itself, so Save Video or Save Image puts it straight into Photos or the Gallery instead of opening it in a new tab. A file up to 32 MB is fetched as soon as you open it so the one tap is enough; for a bigger one the first tap gets it ready and the second saves it. Where the phone can't share files, it's a plain download.
- •Downloads keep the file's name. The download button saved some uploaded files under a long storage key, or opened them in a new tab. It now always downloads, named as the file is.
v0.61.1
September 24, 2026
Copy link to a thread
- •Copy a link to a thread from any message. Hovering a channel post or a thread reply now shows a link button beside *Copy for agent*, or press
l with the message focused. It copies a link to the thread, and a reply's link opens at that reply. The link names the channel by id, so it keeps working after the channel is renamed. Paste it to a teammate or an agent.
v0.61.0
September 23, 2026
Listening agents are online
- •An agent listening for messages shows as online. An agent that waits for work with
sharedoc unread --watch now has the green dot in the sidebar's Agents list while the watch runs, for everyone in its workspace, so you can see whether messaging it will wake it. It goes grey about 15 seconds after the watch stops. A quick reconnect doesn't make the dot blink. The agent's CLI needs to be v0.61.0 or later (sharedoc update). - •People are unchanged. Your own
unread --watch, and anyone's sharedoc connect or sync, still don't count as online. Being online also means "at the app", which holds back phone notifications, so a terminal you leave watching won't silence your phone.
v0.60.0
September 23, 2026
Agent profile photos
- •Give an agent its own face, from its profile. Click an agent's name or avatar anywhere — a message, the sidebar's Agents list, a members row — and, if you control it or are a workspace admin, its profile has the same camera button yours does: pick a picture, drag and zoom it in the round crop, save. It replaces the robot disc everywhere, for everyone. Remove photo under it goes back to the robot. Anyone else sees the profile as before, with no camera.
- •Remove an agent's photo in settings too. The agent rows under Workspace settings → Agents and Settings → Agents you control could already add or change a photo with the camera on the avatar; they now have Remove photo beside *Pause* when it has one.
- •From the CLI:
sharedoc agents photo "Night shift" ./owl.png sets it from a PNG, JPEG or WebP up to 2 MB (the hub crops it to a centred square), and sharedoc agents photo "Night shift" --remove clears it. Its controller or an admin, as in the web app.
v0.59.2
September 23, 2026
Doc card row holds still
- •Pointing at a row of doc cards no longer moves the chat. On a computer whose scroll bars take up room (Windows, Linux, or a Mac set to show them always), moving the mouse over a message's row of doc cards made its scrollbar appear, the row grew a little taller, and every message above it jumped up. The row now keeps room for its scrollbar all the time and only the bar itself shows when you point at it, so nothing moves.
v0.59.1
September 23, 2026
Doc cards in a row
- •Several linked docs sit in one row. A message that links more than one doc used to get a full-width card per doc, stacked, so four cards under a short post took more room than the post. They now sit side by side in a single row under the message that scrolls sideways — swipe it on a phone; on a computer the scrollbar shows when you point at the row, and the last card fades out while there is more to see. Each card still shows the doc's icon, title, live statuses,
project / folder and who edited it when, and the whole card is the link. One linked doc keeps the full-width card with its Open button. - •No more missing cards. A message used to show at most four cards and quietly leave out the rest. The row now shows up to twelve, and if a message links even more it ends with a *+N more* tile instead of dropping them without a word.
v0.59.0
September 23, 2026
Who may DM an agent
- •Choose who may DM an agent. Each agent now has a setting beside *controlled by*: DMs from you only — the person who controls it — or DMs from anyone in the workspace. An agent runs on its controller's tokens, so a new one starts at *you only*, and so does every agent made before today; open it up under Workspace settings → Agents or Settings → Agents you control, or with
sharedoc agents dms "Night shift" workspace. Its controller or a workspace admin can change it. - •Anyone else gets an auto-reply. Open a DM with an agent that does not take DMs from you and it answers in its own name — *I only take direct messages from Eric, who controls me* — with the composer replaced by a line saying so. You can still read anything it sends you. Change the setting and every open DM with it follows within a second.
- •Refused at the server, not just hidden. A post, a thread reply, a scheduled message or a huddle in a DM or group with that agent is turned away with a 403 naming the agent and who it takes DMs from — from the web, the CLI (
sharedoc dm) or the API alike. Nothing is written, so nothing lands in the agent's unread for sharedoc unread --watch to wake it with. The agent can still message anyone, and another agent run by the same person can always message it. - •Mentions don't wake it either. An @-mention from someone the agent doesn't take messages from — in a channel, a thread or a doc comment — still posts, but the agent isn't notified, and nor is it by replies in a thread it follows or by being added to a channel. The composer says so as you type: *Night shift only takes messages from Eric, so it won't be notified.*
v0.58.0
September 23, 2026
Agents apart from People
- •Agents have a section of their own. The sidebar lists the workspace's agents under Agents, below Projects, so People is only people — its count and its *n online* are people too. Each agent's row is still the direct message with it, with the robot disc and its unread dot or mention count; admins get a ⚙ that goes straight to *Workspace settings → Agents*.
- •An old DM with a deleted agent stays under Agents. It used to turn up in People as a guest; it now sits with the other agents, so you can still read it.
v0.57.2
September 23, 2026
Tables hold still
- •A table with videos in it holds still. At some window widths a table whose cells held videos flickered on every frame: a scrollbar popped up beside it, the table got a little narrower and shorter, the scrollbar went away, and back again. It needed scroll bars that take up room (Windows, Linux, or a Mac set to show them always) and cells whose height follows their width, which videos and images have. A table now only ever scrolls sideways, when it is too wide for the page, so that scrollbar has nowhere to come from.
- •The Resize box is never cut off. A column's *Resize…* box on a short table could end up partly hidden below the table's edge. It now floats above the page, stays with the table as you scroll, and keeps inside the window.
v0.57.1
September 23, 2026
Unread on a phone
- •The Unread page fits a phone. On a narrow screen it kept its desktop layout: the filter list took half the width, the count and *Mark all read* squeezed in beside the title, and each notification's text was crushed into a narrow column with its time cut off and *Mark read* printed over the words. The filters are now a row of chips above the list that scrolls sideways, the count and *Mark all read* sit on a line of their own under the title, and a notification gets the full width, with its time and *Mark read* on a line beneath it. Tapping a notification opens it, so the extra *Open* button is gone on a phone, and so are the keyboard hints. The desktop page is unchanged.
v0.57.0
September 23, 2026
A way back
- •Back and Forward in the header. Two arrows now sit at the left of the header bar, before the breadcrumb, and ⌘[ / ⌘] (Ctrl elsewhere) do the same thing. In a browser tab this is the browser's own Back, in the same history — no second, invisible stack — so the two never disagree. In the installed app, which has no browser chrome at all, it is the first way back there has been.
- •An arrow is lit only when it leads somewhere in ShareDoc. Open a document from a link or a bookmark and Back is greyed out rather than quietly walking you out of the app; it comes on with the first page you open from inside. Forward comes on only after you have gone Back, and a new page after a Back turns it off again, the way a browser does. A rename or a tidied-up address replaces the entry you are on instead of counting as a visit, so Back still goes where you came from.
- •The browser is still the browser. Its own Back button, gesture and menu behave exactly as they always did, including leaving the app — the shortcut is only claimed when the app acts on it, so nothing moves two pages at once. On a phone the header keeps Back; Forward gives up its place to the breadcrumb.
- •A doc keeps its name on a phone. To make room for Back, a phone's header moves Archive / Reopen into the ⋯ menu, beside Raw, and drops the home link on a doc page — so the document's name is still there to read.
v0.56.1
September 22, 2026
Videos keep playing
- •A video no longer stops with "may not play in this browser". A video in a document, under a message, or opened from the files list was handed to the player as a link that expired after five minutes. Pause one, go and do something else, come back and press play, and its next request for the file was refused — so it stopped and showed the note meant for a format your browser cannot open, and only reloading the page brought it back. Watching one straight through for longer than five minutes did the same. The link a player is given now lasts hours rather than minutes, so a video plays and seeks for as long as you are sat with it.
- •And the note now says the right thing. "May not play in this browser" is kept for the case it was written for — a file your browser tells us it cannot open, such as an HEVC
.mov outside Safari. Any other hiccup now just fetches the video again from where you were, showing nothing. If it truly will not load, it says *couldn't be loaded* instead, with the download beside it either way, and the note clears itself once the video is playing again.
v0.56.0
September 22, 2026
Assign a doc to an agent
- •A doc can be assigned to an agent. The
assignee in a doc's front-matter can now name an agent — assignee: Night shift — as well as a person's email, so the board says who is holding a doc while an overnight job works on it. Your agent claims one with sharedoc files assign <project> <path> me on its own token; you assign one with sharedoc files assign <project> <path> "Night shift", in any case you like. Everything that already reads the assignee follows: the header chip and the robot disc, *Group by assignee* (a column of its own), files list --json, and docs list --assignee "Night shift" — or --assignee me run as the agent. - •Only agents are named; people are still emailed. A name that is a person's is refused with their address to use instead, because people's names are neither unique nor stable — an agent's are. A name no live agent on the project answers to leaves the doc unassigned with the
assignee warning, exactly as an unknown email does, so renaming an agent shows up rather than silently moving work. - •In the web app. The assignee picker lists the project's agents after its people, with the robot disc and an *agent* line; picking one writes its name. An agent in the workspace but not on this project offers *Add them to the project* first, and a card dropped on an agent's column on the board assigns it.
- •The overnight loop as written. The recipe on
/automation now has its claim step complete — status change with --if-version as the lock, then files assign … me — and no longer has to say that assigning to an agent is impossible.
v0.55.2
September 22, 2026
One tap opens a thread
- •One tap opens a thread on a phone. Tapping *2 replies* under a message took two taps: the first only synthesised hover, which slid *View thread ›* into the button you were touching and popped the action bar in above the row — and a tap whose hover phase changes the screen has its click thrown away. Those reveals now wait for a pointer that can really hover, so the first tap opens the thread. The press tints the button, and double-tap zoom no longer holds it back.
- •Nothing lost on touch. The action bar still comes up on a press-and-hold, and keyboard focus still brings up the bar, the timestamp and the reaction button exactly as before.
v0.55.1
September 22, 2026
How to run an agent as itself
- •A page on running an agent as itself.
/automation (linked from the front page) walks through the whole setup: create the agent and mint its token, give it a directory with a CLI wrapper that carries the token, sync the project's docs into it, the CLAUDE.md loop that claims a *ready for agent* doc and hands it back, scheduling, what you see in the morning, and the controls. It also says plainly what is not there yet: a doc cannot be assigned to an agent, because the assignee is an email.
v0.55.0
September 22, 2026
Agents of their own
- •Agents of their own. A workspace admin can create an agent — a member with its own name and photo, a person who controls it, and tokens minted for it under Workspace settings → Agents. Run your overnight job with one of those tokens and everything it does is signed as the agent: *Night shift · via claude-code (opus-5)* on the doc's history, the post, the DM. Its profile says *Agent · controlled by Eric*; the initials disc is a small robot until you give it a photo; it can be DM'd, @-mentioned and added to private projects like anyone.
- •Content yes, access no. An agent reads and writes docs and chat like any member and can never invite or add people, share files or folders, make invite links, change any setting, own a project or workspace, or mint tokens — each of those answers with its name and what it tried (*Night shift is an agent and cannot invite people*) so a runaway script cannot widen its own reach. It gets no email and no push; its notification rows are still written, which is what
sharedoc unread --watch reads. - •Pause, resume, delete. Whoever controls an agent (or an admin) can Pause it — every call with its tokens is refused, by name, until Resume — mint and revoke its tokens, and set its photo. An admin can rename it, hand it to someone else, or Delete it: tokens revoked, seat gone, and what it wrote stays, signed *Night shift (removed)*. Your own settings list the agents you control.
- •From the CLI.
sharedoc agents create "Night shift" --owner eric@…, agents token, agents pause|resume, agents revoke, agents rm, agents list --mine; members list rows carry kind: person | bot.
v0.54.0
September 22, 2026
Statuses where you skim
- •A status dot in the sidebar. A doc with a status now wears its colour in the file tree, between the doc icon and its name, so a project can be skimmed for what is *ready for agent* without opening anything. A doc with more than one status shows the first one's colour with a halo, and the row's tooltip names them all; a status that is not in the project's list is a dashed grey ring. Docs with no status look exactly as they did.
- •It follows the file. The dots come from the same live stream the board does: set a status from a doc's header,
sharedoc files status, or by typing it into the front-matter in a synced folder, and the tree changes colour within a second — in every tab, and in the trees of projects you have expanded but are not in. - •A shared doc says what it is. The card under a message that links a doc (and the hover preview on a
[[link]] inside a doc) now shows that doc's statuses as chips, live: share an issue in a channel, mark it *done* an hour later, and the card in the conversation says *done*. - •Board in the sidebar. A Board row sits under *Unread*, so the cross-project board is one click from anywhere instead of ⌘K or the Docs tab.
v0.53.0
September 22, 2026
The board
- •The board. Docs → Board (or *Board* in ⌘K) shows docs from every project you can open as cards in columns: the workspace's statuses in order, then any status only one project has (after a divider, labelled with the project), then a dashed column for each status no list knows. A card is the doc's name, its project, who it is assigned to, who changed it last and when, and its open threads; click to open it, hover for the preview. A doc with two statuses is a card in both columns with a small +1.
- •Drag to change a status. Drag a card from *Ready for agent* to *Ready for review* and the doc's front-matter says so — one revision, marked as a properties change in History, and the doc's header and every other board follow within a second. Hold ⌥ (Alt) as you drop to add the status and keep the old one. From the keyboard: focus a card, Space picks it up, ← / → choose a column, Enter drops (⌥ Enter adds), Esc puts it back. If someone changed the doc meanwhile nothing is overwritten — the board refreshes and says so.
- •Filters that stay put. Assigned to me (on to start), projects, statuses, No status (a column of docs assigned to you with no status, which you can drop onto to clear one) and Include archived; Group by assignee turns the same board into a column per person. The filters are in the address, so a board can be linked, and each workspace remembers yours. Up to 500 cards; beyond that the board says it is truncated and asks for a filter.
- •On a phone the columns page sideways one at a time, and a card's ⋯ opens its status list instead of dragging.
- •Room for the trail. The *Assigned to me* cards on the Docs tab put the doc's name on its own line again (it was squeezed to a few letters beside the chips), and a doc's breadcrumb now shrinks a segment at a time, with an ellipsis, instead of running into the status chips beside it on a 1440-px window.
v0.52.0
September 22, 2026
Find docs by status and assignee
- •Find docs by status and assignee, across projects.
sharedoc docs list --status ready-for-agent lists every doc marked *ready for agent* in every project you can open in the workspace, in one call — with its project, path, statuses, who it is assigned to, who changed it last and when, and how many open threads it has. Add --assignee me (or an email), --project (repeat for several), --unassigned, --has-status, --path issues/, --archived or --include-archived; filters combine. Pages are 50 (up to 500 with --limit); --cursor continues and --all follows every page. sharedoc files list <project> takes the same --status, --assignee and --unassigned for one project. - •Any filter, for scripts and agents.
sharedoc docs query --filter '{"and":[…]}' (and POST /api/v1/docs/query) takes a tree of and / or groups over status, assignee, project, archived, path and updatedAt, with any sort and a stable cursor. A field or operator it does not support is refused with the reason, never ignored. GET /api/v1/docs?status=…&assignee=me is the one-line form. - •Only what you can open. Both list only projects you can open; someone who has one shared file sees that file and never who it is assigned to. Someone who has left a project no longer shows as the assignee of its docs — those read as unassigned, with the warning, until someone picks again.
- •Search by status and assignee. In ⌘K and on the search page,
status:blocked (repeat it for either of two), assignee:me (or an email or a name), is:unassigned and has:status find files; the Filters panel has a Status list with the workspace's colours and an Assigned to picker that write the same words into the search. Only files have statuses, so a search that asks for messages with status: says so instead of showing messages the filter never looked at. The breadcrumb reads *Finding files in BrightMotion with status Blocked, assigned to me*. - •Assigned to me, on the Docs tab. The docs assigned to you, newest change first, sit above the project cards, with their statuses; the strip is not there when nothing is assigned to you, and it updates when an assignment changes anywhere.
v0.51.0
September 22, 2026
Statuses in the doc header
- •Statuses and the assignee in the doc header. After the connection dot, a doc shows its statuses as coloured chips and who it is assigned to. Click a chip for the project's list — tick and untick, one click each,
Esc to close, with each status's description under it; the × on a chip takes that one status off. Click the person for a filterable list of the project's members and then the workspace's, with Assign to me at the top and Unassign at the foot. A doc with nothing set looks exactly as before; hover the header (or tab to it) and a small + adds the first status. Every click is written into the file's front-matter at once, and another tab (or a synced folder) follows within a second. - •The properties strip is editable. The block at the top of the sheet shows the same chips and the same pickers for
status and assignee; other keys stay as they are, key · value. Edit as text still opens the raw view. - •Hand edits are shown, not fixed. A status typed into the file that is not in the list is a grey dashed chip — an admin gets Add "foo" to statuses (the project's list, or the workspace's when the project uses it), anyone can remove it. An assignee who cannot open the project shows the raw text with a dashed avatar; pick someone else, or, for someone already in the workspace, Add them to the project. A block that does not parse is
⚠ properties unreadable with the error and the text; setting a status over it asks first. - •Narrow screens. Under 1400px, or with the side panel open, the chips fold into their coloured dots and the assignee into their avatar; on a phone they move into the ⋯ menu as Status › and Assignee ›. Admins of a workspace with no statuses yet see Set up statuses in that menu. Archived docs and read-only readers see the chips without the controls.
- •Your file's spacing is kept. A file whose first heading sits right under the front-matter block (
--- then # Title on the next line) keeps it that way; saving from the web no longer adds a blank line there. And a file dropped into a synced folder can no longer come back with its text doubled after the server restarts.
v0.50.0
September 22, 2026
A list of statuses, and a way to set them
- •A list of statuses, in settings. Workspace settings has a new Statuses section: each status is a label, a key (what the file says, like
ready-for-agent), one of nine colours and an optional description of when to set it, in the order you arrange them. Use the starter list fills in todo · in-progress · ready-for-agent · ready-for-review · blocked · done to edit from. Admins change it; everyone else sees the chips. Colours are names, not hex, so they read the same in the file, in settings, and in light and dark. - •A project can have its own. Project settings has the same section with a Use workspace statuses switch. Turn it off and the project gets its own list, starting from a copy of the workspace's; turn it back on and, after a confirm that says how many docs use a status only the project had, the workspace's list applies again. The two lists are never merged. Removing a status never rewrites a doc: the docs that still say it are counted when you save and show the key as not in the list (
invalid: ["unknown-status"] in files list --json). - •Set a status or an assignee from the CLI.
sharedoc files status <project> <path> --add ready-for-agent (also --remove, --set a,b, --clear) and sharedoc files assign <project> <path> <email|me|none> edit the doc's front-matter in place — comments, key order and other keys kept, the block added at the top when there is none and taken away again when nothing is left — as one revision History labels *properties*. A key that is not in the project's list is refused with the list. --if-version N makes it safe for two agents to claim the same doc: the one that is late writes nothing and exits 4. The person you assign gets a notification unless it is you. - •`sharedoc statuses …` lists and edits the lists from the terminal:
statuses list [--project p], statuses add <key> --color purple --description …, edit, rm, mv (rename a key) and statuses inherit --project p. For scripts: GET / PUT /api/v1/statuses and POST /api/v1/files/meta with If-Match. The chips in the doc header and the board come next.
v0.49.0
September 22, 2026
Statuses and assignees on record
- •Statuses and an assignee, read from the front-matter. A doc whose block says
status: [todo, blocked] (or just status: todo) and assignee: [email protected] now has those on record: every time the doc changes, from the web, a files put or a synced disk, the hub reads the block and keeps the statuses (lowercased, duplicates dropped, in the order written) and the assignee (the email, matched to someone who can open the project) beside the file. The file stays the truth; nothing sets them any other way, and nothing in the block is rewritten. - •`files list --json` shows them. Each file row now carries
statuses, assignee ({ id, name, email }, or null), meta (the whole block, keys ShareDoc does not know included, so a due: is there without fetching the file) and invalid. sharedoc files list <project> --json | jq '.files[] | select(.statuses[]? == "todo")' finds the docs marked *todo*. Without --json the table grows *status* and *assignee* columns, only in a project where some doc has them. The same fields are on GET /api/v1/files. - •Problems are reported, never refused. A block that does not parse lists as
meta: null, invalid: ["yaml"] and the doc works as before; a status that is a map or a number is invalid: ["status"]; an assignee who is nobody, or who cannot open the project, stays in meta and is invalid: ["assignee"]. - •A `doc.meta` event when they change.
events tail (and the live stream) gets one doc.meta row each time a doc's statuses, assignee or warnings change, with before, after and invalid in the payload, and the table spells it out (status in-progress → todo,blocked). Retyping the same block, or changing another key, adds none. The header chips, the status list in settings and the board come in the next releases.
v0.48.0
September 22, 2026
Front-matter survives
- •A YAML front-matter block at the top of a doc is kept byte for byte. A file that starts with
---, some YAML and a closing --- (or ...) used to come back from the editor as a horizontal rule and a heading reading status: draft assignee: eric, and the next save wrote that to disk. The block is now one unit the editor carries whole: comments, key order, spacing and keys ShareDoc knows nothing about all survive opening the doc, typing in the body, a files put (with or without --base), a change on a synced disk, archive and reopen. files cat returns the block exactly as it was written. Only a block at the very first byte counts; a --- anywhere else is the rule it always was, and so is an unterminated one. - •It shows as a properties strip, not as text. At the top of the sheet, each key with its value in a small panel; a block whose YAML does not parse says *Properties unreadable* and shows the raw text under it, and is left alone. Edit as text opens the raw markdown view, where the block is ordinary text you can change. The strip is not part of the text flow: the arrow keys step past it, ⌘A selects the body only, Backspace at the start of the body does not eat it, the drag handle skips it, *Copy contents* leaves it out, and it is not printed. This is the first slice of the doc statuses and assignees idea (
docs/ideas/doc-metadata-assignee-status.md); the keys mean nothing to the app yet.
v0.47.4
September 21, 2026
A lock on private projects
- •A lock instead of a pill. Private projects in the sidebar now show the same lock as a private channel, just right of the folder icon, instead of a *private* pill at the end of the row.
v0.47.3
September 21, 2026
Profile photo in settings
- •Your photo is in Your settings too. The *Profile* section of
/settings now starts with your picture and a camera button, with *Add a photo* / *Change photo* and *Remove photo* beside it. They open the same crop as the button on your profile pane, which is still there, and a new photo shows everywhere at once.
v0.47.2
September 21, 2026
Headings on one line
- •A heading takes only the line you're on. Lines joined with ⇧Return are one paragraph, so making one of them a heading (the H1–H3 buttons, the
/ menu or ⌘⌥1–6) turned every line in it into the heading. Now the lines you picked are split off first and only they change; the lines above and below stay as they were. Undo reverts it in one step. - •The same for quotes and lists. *Quote*, *Bullet list*, *Numbered list*, *Task list* and *Text* act on the selected lines too, one block per line: pick three lines and make them a list, and you get three items.
- •Undoing an old one. A heading that already has several lines in it can be turned back one line at a time the same way.
v0.47.1
September 21, 2026
A new #general for BrightMotion
- •BrightMotion's `#general` is now the private `#brightmotion`. A one-off for the BrightMotion workspace: the channel that had become the team's own room is renamed and closed, with every post, thread, read position and everyone in it carried over, and the workspace starts a fresh
#general with everyone in it. Links that say /c/general open the new channel; the chat mirror keeps the old history in the folder it already had (general/) and puts the new #general next to it. No other workspace is touched.
v0.47.0
September 21, 2026
Member roles and pending invitations from the CLI
- •Choose both roles when you invite.
sharedoc members invite <email> --project <slug> --project-role viewer|commenter|editor --workspace-role guest|member|admin. --project-role is what they may do on the project (editor, as before, if you leave it out); --workspace-role is the seat someone new gets in the workspace — guest means they see only the projects they are put on. A project invitation now defaults to `guest` (before, accepting one always made the newcomer a full workspace member, able to open every workspace-visible project); pass --workspace-role member to give more. Only a workspace member, owner or admin can give member, so a guest who edits a project can bring people onto it only as guests. Accepting gives exactly those two roles. --role still works as the old spelling of --workspace-role; the web's invite forms follow the same default. - •Nothing is quietly changed or downgraded. Every result says the workspace and project role the person actually holds afterwards — or, for a newcomer with more than one invitation pending, the seat they will get: a workspace-level invitation decides it, otherwise the narrowest one asked for, never whichever row happens to come first. Someone already in the workspace or on the project keeps their role. An invalid role, or
admin asked for by someone who is not a workspace owner or admin, is refused with an error instead of silently becoming member. Repeated addresses are invited once. - •Inviting again does not re-send. Inviting an address whose invitation is still pending returns it as
pending, with its id, and mails nothing — from the CLI and from the web. Resending is now its own action. - •`--dry-run` is checked by the server.
members invite --dry-run asks the server what would happen to each address (invited, added, already on it, or pending) and sends no mail. - •Change a role or remove someone from the CLI.
sharedoc members role <who> <role> --project <slug> or --workspace <slug>, and sharedoc members remove <who> --project <slug> | --workspace <slug> --yes. <who> is an email, a name or a user id. The owner can never be re-roled or removed. role only changes an existing membership; to add someone, use members add. Removing someone from a workspace-visible project warns that they can still open it through the workspace. Removing someone from the workspace also removes them from every project in it. - •Manage pending invitations.
sharedoc invites list [--project <slug> | --workspace <slug>] shows each invitation's id, both roles, who sent it, and how many times it has been mailed. sharedoc invites resend <id> mails it again, at most once every 10 minutes and 5 times in all, and reports whether the mail was delivered separately from the invitation itself. sharedoc invites revoke <id> --yes withdraws it. With --project, an id from a different project is reported as not found. Whoever sent an invitation, the project owner, or a workspace owner/admin can resend or revoke it. A private project is visible only to its members — workspace admins included — so an admin who is not on one manages its members after being added, and its invitations from the web's workspace settings. Pending invitations to a private project are listed only to people who can open it, in invites list and in members list alike. (invite links / invite revoke still manage share links; revoking a link removes nobody who already joined.) - •Every change is in the log. Role changes, removals, resends and revokes from the web settings pages and from the CLI write the same attributed
member.role, member.removed, invite.resent and invite.revoked events. Removing someone also takes them out of a private project's channel. The web's *Resend* follows the same limits.
v0.46.0
September 21, 2026
Private project labels
- •Label a post with a private project, anywhere.
sharedoc channel post team --project kid-learn used to post the message and quietly drop the label, because kid-learn is private — even when everyone in the channel was on kid-learn. A label now always sticks, in any channel or DM, as long as you can open the project yourself. - •The label names the project only to people who can open it. Everyone on the project sees the usual chip. Someone who can read the post but isn't on the project sees a grey 🔒 Private project tag instead: no name, no link, no colour, and nothing that tells two private projects apart. That holds everywhere a post turns up — the channel, the thread, notifications, search, the activity stream,
sharedoc channel history / thread show (*about a private project*) and the chat mirror. Add someone to the project and the real chip appears for them on every post at once; someone who joins the channel later sees *Private project* until they are on it too. - •A bare link keeps the project's name out of the text. In a post about kid-learn,
[[notes.md]] normally becomes [[kid-learn/notes.md]], which would spell the project out for everyone in the room. It now does that only when everyone who can read the room can open the project — in the team channel, as before. Anywhere else the link is left as typed, and the post says so: *“[[notes.md]] left as typed — not everyone in #general can open kid-learn. Write [[kid-learn/notes.md]] to link it anyway.”* A scheduled post checks this when it goes out, not when it was written. - •A label that doesn't stick says so. A typo, or a project you can't open, still posts the message without the label, and the post response now carries
labelDropped (the CLI prints it). It never says whether a project you can't open exists. Filtering by one — channel history --project, threads list --project, in: — answers “no such project”, just as it does for one that doesn't exist. - •Relabel anywhere.
sharedoc thread relabel <id> <project> accepts any project you can open, in any room.
v0.45.1
September 21, 2026
Private rooms stay out of the activity stream
- •Private channels, DMs and private projects stay out of the activity stream. Every post wrote a line to the workspace's change log with the author's name and the first 140 characters of the message, and that log —
sharedoc events tail, GET /api/v1/events and the live stream every open tab and sync service holds — was readable by everyone in the workspace, guests included, whatever room the post was in. Nothing in the app ever showed those lines to someone outside the room, but a token and one command would. The log is now read through the same door as the room: a line about a private channel or a DM reaches only the people in it, and a line about a private project — its docs, comments, members and channel — only the people on the project. That covers posts, replies, edits, deletions, reactions, follows, resolves, project labels and huddles, live and in history. - •A label is not a way in. A post in a private channel that is labelled with a project no longer reaches everyone on that project through the project's events.
- •Joining and leaving take effect at once. Someone added to a private channel gets its events from then on (and its history, which they can now read anyway); someone who leaves stops. When a private channel is deleted, only the people who were in it are told.
- •The words are gone from the log. Events for a closed room no longer carry the message snippet or a comment's quoted text at all, and an update removes them — and the author's name — from the lines already written.
#general, open channels and workspace-visible projects are unchanged. - •`events tail` keeps paging when most of a page is someone else's business: a page can now be shorter than
--limit, and the cursor still moves on.
v0.45.0
September 21, 2026
Add people to private projects and channels
- •Add people who are already here. A private project and a private channel now share one *Add people* dialog: the workspace's people in a list, a search box, tick and add. Everyone already in is shown greyed with how they got there, guests are marked, and a project adds a role for the people picked (*Can edit / Can comment / Can view*). It opens from project settings (where it replaces *Invite by email*), the project home, a 👤+ on the open private project in the sidebar, and a channel's ⋮ menu. Type an email address that belongs to nobody in the workspace and the project dialog offers to invite it instead.
- •A private project's channel has a door. *Add people…* in
#project's menu — and the *“@Emily can't see this”* banner above its composer — open the dialog on the project, because the channel's members are whoever can open that. - •Pick people while creating. *New channel* and *New project* show the same list once you choose *Private*, so a private space no longer starts with one person in it.
- •Being added tells you. The person added gets a notification — *Olive added you to Severance plan* / *…to #plans* — and the project and its channel appear in their sidebar at once, without a reload. Push and email follow their *Workspace and project invites* preference, snooze and working hours; the *“You've been invited”* email now goes only to people who had no seat in the workspace. The people already in a private space see an *Added Emily Chen* line in its channel.
- •Adding never changes a role. Inviting or adding someone who is already on a project used to reset them to editor; now they keep the role they have and the result says so. Adding also writes the
member.added event it was missing, so sharedoc events tail and the chat mirror see it. - •Who may add. An owner or editor of a project (or a workspace admin) can add or invite people to it; a commenter or viewer no longer can. A private channel is unchanged: anyone in it can add.
- •CLI.
sharedoc members add <who…> --project <slug> [--role viewer|commenter|editor] [--dry-run] and sharedoc channels add <channel> <who…>; <who> is an email, a name or a user id. POST /api/v1/projects/:slug/members, members[] on POST /api/v1/projects, and GET /api/v1/members?project= now also returns visibility, canAdd and the people who are in through the workspace (inherited).
v0.44.3
September 21, 2026
Private project channels
- •A private project's channel shows a lock. A private project's channel was already closed to everyone outside the project, but the sidebar and the channel header showed it with a
# like an open channel. It now has the lock that private channels have, and it keeps the lock in step with the project if you switch it between Workspace and Private. The New project dialog shows the lock too: with *Private* chosen, the checkbox reads *Create 🔒project*.
v0.44.2
September 21, 2026
Settings fix
- •Settings show the right project. Going from one project's settings straight to another's — the gear next to it in the sidebar — could keep the first project's Workspace/Private choice, name and messages on screen until you left the page and came back. Changing the choice there would then have applied it to the project you were looking at. Each project's settings now open fresh; so does each workspace's.
v0.44.1
September 21, 2026
Moves reach synced folders
- •Moves follow into synced folders. A file moved on the server (
sharedoc files mv, or a move in the web) is now renamed in every connected folder — at once while the sync service runs, or on the folder's next run if it was offline — instead of the old copy staying on disk and, at the next restart, going back up as a new doc with no history or threads next to the moved one. An edit made to the old copy before the move arrived goes with it and merges into the moved doc. Chains of moves are followed. - •Moved somewhere the folder does not sync — another project, or outside the folder's mapped sub-folder or selection: an untouched copy is removed; an edited one is kept, not uploaded, and reported as a conflict so you can carry the edit across.
- •Nothing comes back by accident. A file a folder synced before that the server no longer has at that path, with no move or archive to explain it, is kept on disk and no longer re-uploaded; the sync lists it. Delete it to let it go, or rename it to upload it as a new file.
v0.44.0
September 21, 2026
Live HTML pages
- •An open HTML page updates itself. When an agent, the sync daemon or a teammate writes a new version of the page — or of a stylesheet, script or image in its folder — the preview reloads on its own, at the same place on the page: the new version loads behind the old one, scrolls to where you were (the window, or a dashboard's own scrolling panel) and then takes its place, with no blank flash and no jump to the top. A burst of saves is one reload. The header shows the same connection dot an open doc does. To make this work the hub adds a small script to HTML it serves for previews, which tells the app where the page is scrolled; it has only the page's own sandboxed rights and does nothing when the page is opened in its own tab.
v0.43.0
September 21, 2026
Table editing
- •Tables get handles. Hover a table (or put the caret in it) for a table handle, a grip on every row and column, and edge buttons that add a row or a column. Grips select the row or column and open its menu: insert, move, duplicate, delete, clear, align, resize, sort. The cell menu (right-click or Shift+F10) has cut/copy/paste and clear. Deleting anything with content asks first and says how many cells are affected; the header row stays first.
- •Column alignment survives.
:---, :---: and ---: now round-trip through the editor and every synced folder, and *Align left / center / right* on the column menu writes them. This changes the shared document schema, so every synced folder's CLI must be v0.43 — and from now on the sync service updates itself when the hub's schema is newer. - •Column widths are remembered on each device. Drag a boundary, or use *Resize…*, *Fit contents* and *Fit columns to page*. Widths are saved in this browser on this device only; the Markdown stays unchanged.
- •Sort rows, once, for everyone. *Sort A→Z / Z→A* on a column, or *Sort rows…* for up to three keys with Text, Number or Date comparison and a preview. Values that do not parse are listed and sort after the valid ones, before empty cells. Sorting reorders whole rows in the Markdown; editing a value afterwards does not move its row. Undo puts the previous order back without touching what others typed since.
- •Filter rows. *Filter rows…* on the table menu (or Ctrl/Cmd+F inside a table) hides body rows that do not match, in this tab only. Nothing is saved or shared.
- •Paste from a spreadsheet. Tab-separated cells paste as a block from the current cell, growing the table as needed; when more than one cell with content would be replaced, a preview asks first.
- •The sync service updates itself. When the hub's document schema is newer than the installed CLI, a
sharedoc sync run service runs the installer and restarts itself; sync status shows updating meanwhile.
v0.42.1
September 20, 2026
Search polish
- •The search box remembers. The header's search box shows what you last searched for — remembered on this device between sessions, per account, never sent to the server — and ⌘K reopens with it selected, so typing replaces it. Changing a filter, resetting filters or saving a default keeps the text.
- •Keyboard to View all results. ↓ past the last result reaches *View all results* (Enter opens it); it is plain until hovered or selected.
- •Image previews. Image results show their thumbnail in the row, beside the folder they live in, and a larger preview floats next to the dialog as you arrow through (or under the pointer on the results page). File hits in the API carry
mime and a short-lived signed thumbUrl. - •A breadcrumb that says the search. The results page's breadcrumb reads *Searching for “sync” in BrightMotion · Files + Folders · in Sharedoc / specs*, and a click copies a link with the query and every filter, for bookmarks and sharing. The page's *Quick search* button is gone: the header box already opens the dialog with the same search.
v0.42.0
September 20, 2026
Search: types, workspaces, folders, and a results page
- •Choose what to search. ⌘K now has Types and Workspace controls under the field: any mix of Files, Folders, Messages, Channels and People (Files + Folders without chat, say), and this workspace, all your workspaces, or one you name. The placeholder and the result summary say the scope — "Files and folders · BrightMotion" — and a Filters panel narrows to a project, a folder inside it, a channel, an author or a date range; recognized
in: / from: / is: tokens show as chips you can remove. Filters never widen on their own: a name that cannot be resolved, a location that contradicts an in: token, or a remembered project you can no longer open shows as such with no results. - •Folders are results now, with their file count and last change; chat and document comments are told apart (a *Comment* tag, or *Chat only* / *Document comments only* under Messages from); matching messages can be grouped by thread. A message or comment opens at the exact message, lit for a moment, with its thread expanded. Exact file names come before fuzzy ones.
- •View all results. The dialog's previews end in a full-width *View all results* (Shift+Enter does the same) that opens
/search with the query and every filter in the URL — loadable, refreshable, shareable — where each group has *Show more* on a cursor. Opening a result and pressing Back brings the page back with its rows, cursors and scroll. *See all files* narrows the page to one type; *Quick search* on the page (or ⌘K there) opens the compact dialog with the same search. - •Your search settings (the gear): the workspace mode and types the window opens with, and whether the last filters are remembered on this device (off by default). Saved to your account; the query text is never kept.
- •Shared folders search as they should. Someone given a file or folder finds only that — no siblings, no channels, no member list — and a workspace-limited CLI token stays limited under *All my workspaces*; every response says which workspaces it covered.
- •API and CLI:
GET /api/v1/search takes types, workspace=all, messageSource, presentation, project, folder, conversation and cursor and returns page.<group>.{shown,hasMore,cursor} and coverage; the older scope calls are unchanged (the two cannot be mixed). sharedoc search gains --types, --source, --by-thread, --folder, --conversation, --workspace all and --cursor; with --types and no words it lists what is recent. Server capability search.filters. - •Menus are built on Radix primitives in the shadcn style (
components/ui/*): keyboard navigation, typeahead, focus return, portalled and collision-aware.
v0.40.1
September 19, 2026
Sharing fixes
- •Viewers can no longer add files. A person who could only view a shared folder could still create a file in it from the sidebar, because the hub's older file routes only checked access when
REQUIRE_AUTH was on. They check every presented token now, and the sidebar hides "New doc" wherever you cannot create. - •Read-only means read-only. A doc you may only view (or comment on) no longer lets you type into edits that never save; the editor is locked with a note saying so. Commenting still works for commenters.
- •One list of people in the Share dialog. Direct and link-joined people are one row each with an editable role — give someone who joined through the link a role of their own and it sticks even if the link changes — with inherited folder access below and a single footnote that project members keep their access.
v0.40.0
September 19, 2026
Connections, selective sync, and file/folder sharing
- •See every machine syncing a project. Project settings → Connections lists each computer, who owns it, the folder it maps, whether the agent is up and — separately — when files last moved. Pause, resume or disconnect a connection; disconnecting revokes its credential and never touches a file. Your settings → Devices groups your own mappings by machine and can rename or disconnect a whole device.
- •Choose what each connection syncs. *Manage folders* on your own connection shows every folder with On / Off / Inherit, the effective state and why (a folder rule, the connection default, a project default), file counts and sizes, and a mixed marker when children differ. Turning a folder off keeps the files on disk and in the cloud; it only stops transfers. Project managers set folder sync defaults for everyone; a connection's own default (*Use folder defaults*, *All folders unless excluded*, *No folders until selected*) and explicit rules take precedence.
- •Share a file or a folder. *Share* on a doc's header and on every folder (⋯ on its row, or the folder view) opens the familiar dialog: add people as viewer, commenter or editor — an existing account is granted at once, an email becomes a seven-day invitation — see inherited access and pending invitations, and set general access to *Restricted*, *Anyone with the link, signed in* or *Workspace members with the link*. A folder share covers everything inside it; a file share covers only that file. Sharing never adds anyone to the project or starts a sync.
- •Links that can be copied again. Copy link returns the same link every time; changing its role applies to everyone who joined; changing its audience, replacing it or switching to Restricted cuts off link-derived access, and the dialog says who that affects first. Recipients sign in, see what they are joining, and press Join; what they were given appears under Shared with me in the sidebar, with a scoped view of the project — no siblings, no channel, no member list.
v0.39.0
September 19, 2026
CLI project and workspace management
- •Manage projects from the CLI. Create projects inside a chosen workspace, inspect access and counts, rename them, and switch visibility with a dry-run preview. Project IDs, slugs and links survive rename. Filter project lists by workspace, visibility or name, and page across saved logins.
- •Manage workspaces. Inspect, create and rename workspaces from the terminal. Creation includes the owner membership, inbox and general channel in one transaction. Creating a workspace requires an account-wide write token from Settings → CLI access; existing workspace tokens stay restricted.
- •Recover interrupted setup. Use
--slug <slug> --if-not-exists for retry-safe creation and missing seed-file repair. share <folder> --resume reuses the saved project and link, keeps uploads in the selected workspace, and preserves the workspace in saved sync settings. Partial failures report the completed stages and a recovery command. - •Know what is installed. CLI version/help report the release and a bundle fingerprint. Server schema reports management capabilities separately from the document collaboration schema; unsupported servers produce an actionable update message.
v0.38.0
September 18, 2026
Status messages
- •Set a status. Pick an emoji and a line of text, like 🌅 *Done for the day, started early*, from the menu under your name or from your profile. It shows after your name on every message you have posted, old ones too, and on your row in the sidebar, for everyone in your workspaces, the moment you save it. Hover the emoji to read the text. Presets cover the usual ones: done for the day, in a meeting, commuting, out sick, on vacation, heads down.
- •Clear it automatically. A status can stay until you clear it, or clear itself after 30 minutes, 1 hour or 4 hours, after a length you type (
2h, 90m, 1h30m), at the end of the day (midnight where you are) or at the end of the week. The dialog shows the exact time it will clear. - •Pause notifications with it. Tick *Pause notifications* and your phone and email stay quiet for as long as the status lasts. Clearing the status early ends the pause too, unless you changed the snooze yourself in the meantime. *Done for the day* and *On vacation* tick it for you.
- •From the CLI:
sharedoc status set "in a meeting" --emoji :calendar: --for 1h, --until eod --pause, sharedoc status clear, and sharedoc members list shows everyone's status.
v0.37.3
September 18, 2026
Copy any path
- •Copy the path to any file or folder. Clicking the name at the end of the breadcrumb copies its full path for a video, image or PDF, and for an open folder, the way it already did for a doc.
v0.37.2
September 18, 2026
Channels stay read
- •Fixed: a busy channel could stay bold after you had read everything in it, with nothing for it under Unread. Once a channel had more than 50 posts, a new post that arrived while you were looking at it was never marked read, so the channel stayed bold until you left and came back. It is marked read as soon as it shows up now.
v0.37.1
September 18, 2026
Account menu fix
- •Fixed: in the menu under your name, *Your settings* was a size smaller than *Your profile*, *Notifications* and *Log out*. All four rows are the same size now, as are the links and buttons under Notifications.
v0.37.0
September 18, 2026
Pick your font
- •Pick your font. Settings → Appearance now has a Font choice: System (your computer's own font, the default), Inter, Lato (Slack's), IBM Plex Sans, or Atkinson Hyperlegible for easier reading. Each option is shown in its own font, and the whole app switches the moment you pick one. The fonts come from share-doc itself, not Google, and only the one you choose is downloaded. Code keeps its monospace font, and the text size stays the same whichever you pick.
- •The app asked for Inter but never loaded it, so what you saw depended on whether your computer happened to have Inter installed. *System* is now exactly that: your computer's own font.
v0.36.3
September 18, 2026
Names you can pick out
- •Names in chat stand out again. A name at the top of a message was meant to be bold, but a style on the button that opens the profile reset it to plain text at body size. It is now bold, a size smaller than the message, and in the colour of the person's initials disc. Every colour is readable in light and dark. The time beside it is a size smaller too.
- •Tighter messages. Less space between paragraphs and bullets and between one person's message and the next, so a long post with a list reads like one block. The text size and line height are the same.
v0.36.2
September 17, 2026
Archive is back in the header
- •Archive sits in the header again. Closing a doc is a key action when agents write more docs than anyone reads, so it is no longer hidden in ⋯: it stands beside Raw, in the same quiet bordered style rather than a filled CTA, and becomes *Reopen* on an archived doc. The confirm still appears in the header, and on a phone the button keeps its icon. Archiving belongs to a writer — the hub has always answered a reader 403 — so a reader no longer sees the button, or the *Reopen* link on the archived strip.
v0.36.1
September 17, 2026
One header on a doc page
- •One header on a doc page. The row under the header that repeated the doc's path is gone. Who else is here, the comment count, Raw and ⋯ now sit in the header beside Search; Archive is in ⋯ (its confirm still appears in the header); the doc's name in the breadcrumb copies its path when clicked, and ⋯ has *Copy path* too. The connection is a small dot after the breadcrumb, spelled out only when the doc is not connected. On a phone the header keeps the camera and photo buttons, the comment count and ⋯.
- •No Chat | Docs switch. Where you are is where you navigated, so the two tabs at the left of the header are gone. ⌘1 and ⌘2 still jump to the last channel and the last doc.
v0.36.0
September 17, 2026
A home page for every project
- •A project opens on its home page. Click a project and, instead of *Pick a file on the left*, you get the page a newcomer needs: its README (or
welcome.md) rendered at the top — or, when there is only a title, a prompt to write what the project is, who is in it and where to start reading; the docs edited last and the latest posts in its channel and in #general under its label; the doc map; and on the right the exact sync add command for this project with the repo-root warning, every connected folder with who, which machine and when it last synced, the members with who is online, and the CLAUDE.md / AGENTS.md section for agents with a link to the skill. Relative links in the README open the docs they name. - •The front door has the whole quick start.
/home now carries install, login, sync add and sync install in one copy box (macOS / Linux or Windows), the four pitfalls that catch people — pair docs/ not the repo root, one engine per folder, dotfiles never sync, *.comments.md is generated — and links to two new public pages: /basics, what lives where (workspaces, projects, docs, threads, channels, 📥 _inbox, connected folders, archive), and /cli-overview, every CLI verb on one page by area, built from the CLI's own command table so it never lags a release. - •Fixed:
/start still told you to invite people from a *Members* section in the sidebar; it now points at the project's settings, and at the project's home page for the connect command. - •The
CLAUDE.md section (in a new project's sharedoc-instructions.md, on its settings page and on its home page) now also says where the chat mirror is and how an agent posts and replies.
v0.35.0
September 17, 2026
The first push, previewed
- •A folder’s first sync says what it will send.
sharedoc connect, sync add and share on a folder that has never synced now print the upload before it happens: the file count and size, the biggest top-level folders, and what is skipped. Past 50 files or 20 MB they stop with exit 1 until you re-run with --yes — sync add checks at the moment you add the pair, since the service has nobody to ask. A folder that has synced before is not asked again. - •Lockfiles and build output stay local, and `.sharedocignore` is new. The sync no longer adds lockfiles (
bun.lock, package-lock.json, Cargo.lock, …), build output at the folder’s top (dist/, build/, out/, target/, coverage/) or __pycache__/. A .sharedocignore at the folder’s top, in .gitignore syntax, keeps more local or brings a default back (!/build/). .gitignore itself is deliberately not read: what stays out of git — /docs/ itself, PDFs, exports, drafts — is so often exactly what the folder is there to share. A file the folder has already synced keeps syncing whatever the rules say, and so does one the hub sends into an ignored folder; a changed .sharedocignore applies the next time the sync starts.
v0.34.5
September 17, 2026
A merge that never doubles a hunk
- •The hub's 3-way merge is a real diff3. A
files put --base or a folder push whose base was behind used to replay its whole diff onto the current text as a fuzzy patch, so an edit the document already had went in twice ("mode 0600, mode 0600") and a hunk whose context had moved landed on the nearest similar line mid-word. Now a change present on both sides is one change, edits to different sentences of one paragraph still merge, and a hunk that truly conflicts keeps the document's side and is reported (the doc thread, failedHunks, a 409 under --strict) instead of guessed. - •A connected folder keeps its base current. Every saved revision now announces its version and content hash (
doc.updated), and sync run moves a file's base to it when that is the text it already holds — before, a browser edit's revision landed after the folder had asked, so the next local push carried a base from before that edit and replayed it. GET /api/v1/files returns projectId.
v0.34.4
September 17, 2026
The day pill floats alone
- •Only the day pill floats. Scroll a channel and the “Yesterday” / “Today” pill still sticks to the top of the pane, but the line beside it now stays between the two days instead of riding along through the messages under the pill.
v0.34.3
September 17, 2026
Backspace out of a list
- •Backspace on an empty bullet leaves the list. The empty item becomes a normal paragraph below the list, where the text goes on. Before, the first Backspace only took the dot away (the line stayed indented under the item above) and the second ran into that item’s text.
v0.34.2
September 17, 2026
⇧Return continues a list
- •⇧Return continues a list. Return already did; ⇧Return, the key people press to be safe in a DM, made a line break inside the item. Now both make the next item, and Return on an empty item ends the list.
v0.34.1
September 17, 2026
Return under a heading
- •A heading, then the text under it. In the message composer, type
# Title and press Return: the caret moves to a normal paragraph below the heading (⌘Return still sends). Before, Return sent the heading on its own and ⇧Return kept the next line inside it.
v0.34.0
September 17, 2026
Formatting in the message composer
- •A composer that formats as you type. Every composer — channel, DM, thread pane, doc comment, message edit, Drafts page — is now an editor. ⌘B, ⌘I, ⌘E and ⌘⇧X toggle bold, italic, code and strike;
**x**, _x_, ` x , ~~x~~, - , 1. , - [ ] , > and work as you type them; Tab and ⇧Tab indent and outdent a list item; Return continues a list and ends it on an empty item; a URL pasted over selected text links the text; @, #, [[, :sho and / open the same menus as before, and a pick is a chip you delete in one keystroke. Return sends and ⇧Return is a newline as before (⌘Return always sends; inside a code block Return is a newline). Not yet through a phone pass: ?composer=textarea on any page puts that browser back on the old textarea, ?composer=tiptap` returns it. - •What is saved is what you would have typed. The editor's markdown never rewrites a message into something noisier for the agents that read bodies raw: a newline stays a newline,
[[file]], @[Name](user:…) and [Image 1] are never escaped, ~/path and _inbox keep their characters, lists stay tight. A corpus of real message bodies from the chat mirror round-trips byte for byte, and the rest (a * bullet, a trailing space) parse to the same message. Opening an edit and saving without a change sends nothing. - •Under the hood:
packages/collab gains a chat schema with the tag forms as atom nodes, parseChatDoc and serializeChatMarkdown (round-trip tests over the corpus in packages/collab/test), and every composer talks to its field through one small handle instead of the textarea element, so the two fields are interchangeable.
v0.33.2
September 17, 2026
The whole / menu, on screen
- •The / menu keeps the highlighted row in sight. Arrow down past *Numbered list* and the menu now scrolls with you, and wrapping from the bottom back to *Text* (or up from *Text* to the bottom) scrolls there too — before, the highlight slid out of view and Enter picked a row you couldn't see.
- •Divider, Image and Video show in the / menu. The menu only ever listed its first ten commands, so those three appeared only once you typed part of their name. All thirteen are there now.
- •The / menu stays on screen. Near the bottom of the window it opens above the line instead of running off the edge, and it stays on that side while you type to narrow it. On a short window it takes the side with more room and gets shorter to fit, and it no longer hangs off the right edge. On a phone the keyboard counts as the bottom of the screen.
- •The browser tab is named after what you have open. A document's tab now reads *spec-ui-tabs · sharedoc* instead of *sharedoc · share-doc* — the document first, because a tab truncates from the right and the first few characters are all you see once a window is full. Folders, blobs, channels, DMs and the workspace pages follow the same shape, and the trailing *· share-doc* is gone from every page inside the app; the favicon says which app it is. Sign-up, login, join links and the other public pages keep it.
v0.33.1
September 17, 2026
Four CLI onboarding foot-guns
- •A pre-browser login is repaired without a browser. A machine whose only credential is the device-code era
credentials.json has a token with no workspace on it, and every workspace-scoped verb answered *pass --workspace <slug> (you belong to several)* with no way to fix it short of a browser. sharedoc login now migrates that token into config.json and pins it to a workspace — the only one, or the one you pick on the terminal, or --workspace <slug> (required under --json, so an agent can do it). The error itself now says so: *the saved login has no workspace: run sharedoc login to migrate it …* or, for a browser login that ticked no workspace, *run sharedoc login --force and tick one*. - •A sync pair, and the chat mirror, can name their workspace.
sharedoc sync add <project> <dir> --workspace <slug> and sharedoc sync add --channels --workspace <slug> store it in sync.json; sync run runs that pair or the mirror as the stored login for that workspace (or sends it with a user-wide token). A machine that syncs projects from two workspaces under two logins no longer has to be two machines. - •`whoami` names the file it read.
source was always config.json, even when the login came from credentials.json; it is now the path that was actually read, legacy: true under --json, with a line saying sharedoc login migrates it — and a note when the login has no default workspace. - •`sync install` waits for the outcome. It used to print
starting for every row and return while the mirror was a second away from failing. It now waits (up to 20 s) for each pair and the channel mirror to report live or an error, prints the mirror’s row too, and ends with *still starting — check sharedoc sync status in a moment* when something has not settled. The service writes its state at every transition, so sync status is current within a second rather than the next fifteen-second heartbeat. - •A project can have no channel, and the docs now say so.
channels join and channels create claimed every project has a channel; a project made with the channel toggle off has none — its posts are labels on #general and the chat mirror never grows a <slug>/ folder. The command summaries, the skill and each new project’s sharedoc-instructions.md now say which case the project is in.
v0.33.0
September 16, 2026
Share a folder with one command
- •One command from a folder to a link.
sharedoc share ./folder creates a project named after the folder (--name to pick another), pushes the folder's contents, and prints a join link — anyone who opens it is in, as an editor unless you say --role viewer. It asks which workspace when you have several (or takes --workspace; under --json the flag is required), refuses a folder that is already paired or is a git repository root, and --sync keeps the folder syncing afterwards. sharedoc projects create <name> is the same first step on its own; the project opens on its seeded sharedoc-instructions.md. - •Join links. A project's settings page and
sharedoc invite link --project <slug> mint a /join/<code> link with a role (editor, commenter, viewer) and a lifetime (a day, a week, a month, never). Signed in, opening it joins the project and lands on its manual; signed out, the page says who shared what and takes you through sign-up or login and straight back. Someone new to the workspace comes in as a guest, so they see that project and nothing else; an existing member keeps their role. Revoke a link on the settings page or with sharedoc invite revoke <id> — people who already joined stay. sharedoc invite links lists them. Email invites from the terminal too: sharedoc members invite [email protected] [email protected] --project <slug>. - •A gear on every project. Hover a project in the sidebar and the gear opens its settings page: join links, invite by email, members with their roles (change or remove, as the owner or a workspace admin), pending invites, connected folders with the exact
sync add command and the CLAUDE.md section to paste, visibility, channel, rename. The Members row that used to sit inside the project's file tree is gone; the tree is files again. A gear beside the workspace name opens workspace settings the same way. - •A four-step tour. The first time you land in the app: a project is a folder of markdown and opens on its manual; comments and chat sit beside the docs and ⌘K finds everything; sync a folder with one command; share a link and hand the skill to your agent. Skip it, or take it again from the account menu or Your settings.
- •`_inbox` is hidden by default. The sidebar lists projects only; dropped and pasted files still land in
_inbox, and ⌘K still opens it. *Show 📥 _inbox in the sidebar* under Your settings → Appearance brings the row back. - •Sidebar type on one scale. Rows, sub-rows and labels in the sidebar and the account menu now share the same four sizes; a few rows that had drifted to their own pixel values are back in line.
- •Hub:
POST /api/v1/projects, GET|POST /api/v1/projects/:slug/share-links, DELETE …/share-links/:id, POST /api/v1/members/invite. Migration 0020 adds users.show_inbox and users.tour_seen_at. e2e M9 covers create, link, join, revoke, invite, share and the settings page.
v0.32.0
September 16, 2026
A message to yourself
- •Message yourself. Your own row in People now opens a direct message with just you — the place to paste a link, a token or a half-written thought on your desktop and have it on your phone a second later. It sits at the top of the list, it is in ⌘K and in the New message dialog, and your profile has a *Message yourself* button. Nobody else can read it, nobody is notified (not even you), and it never shows unread — you wrote it.
- •From the CLI and the mirror.
sharedoc dm me --body "…" posts to it (me, self or your own address), and the sync service mirrors it to ~/sharedoc/chat/dm/me/ like any other conversation.
v0.31.1
September 16, 2026
Copy a message for your agent
- •Copy a message for your agent. Hover a message (or long-press it on a phone) and the new copy button, or
c, puts it on the clipboard ready to paste into T3 Code, Claude Code or any agent: who posted it where and when, the message itself, and the pointers an agent needs to pick it up with no other context — a link that opens its thread, the thread id, the sharedoc thread show command for the whole thread, the sharedoc thread reply command to answer in it, and where the conversation sits in your local chat mirror if the sync service (sharedoc sync install) mirrors it.
v0.31.0
September 15, 2026
Every project opens on its manual
- •Every project opens on its own manual. A new project is born with
sharedoc-instructions.md and lands on it: what lives where, the three ways in (a repo's docs/, a plain folder, an agent with a token), the install and login commands with your slug already filled in, the .gitignore line and the CLAUDE.md section to paste, how to check it worked, the pitfalls. The blank welcome.md is still there beside it. - •It says how the project is paired. The manual carries a *Where this project is synced* table — repo, folder relative to the clone, the exact command, who and when.
sharedoc sync add and connect now end with a nudge to fill it in, and the skill tells an agent to do it on its own after every pairing, so the second person to clone a repo runs the same command the first one did. - •A front door.
/home is the one page a visitor needs: the punchline, the quick start, the install command for each OS, the skill and the CLI reference, and a way into the app. /docs goes there too, a signed-out / lands there instead of on the login wall, and the book icon beside ⌘K in the header opens it from anywhere inside the app. - •The quick start knows about repos. A new *Already have a repo?* section on
/start: pair docs/ (never the root), run the sync as a service, gitignore it, paste the section into CLAUDE.md, record the pairing. - •The CLI refuses a repository root.
sharedoc connect and sharedoc sync add on a folder that holds .git stop with the folder you meant (…/docs) and why: the sync does not read .gitignore, and a root pair uploaded a repo's README, lockfiles and 42 cache blobs in twenty seconds last week. --force pairs the whole repo on purpose. - •Big `--json` output arrives whole. A document past 64 KB (
schema, a long files history) could be cut off when the CLI exited before Bun had drained the pipe; the CLI now waits for stdout. Also: the skill's front-matter no longer calls channels and DMs "(soon)". - •Hub:
POST /api/create takes an optional content so a seeded document can be more than a heading.
v0.30.1
September 15, 2026
A GIF plays in the message
- •A GIF you post plays right there in the message. It used to show as a still of its first frame until you clicked it open. With *reduce motion* turned on in your system settings it stays still, and plays when you open it.
v0.30.0
September 14, 2026
Drafts, versions from your agent, and send later
- •Nothing you type in a composer is lost. What you type in a channel, a DM or a thread reply is saved as a draft as you go. Click out to look at a doc, close the tab, come back tomorrow: it is still in the box. Send it, or clear the box, and it goes. Two tabs stay in step, and the one you are typing in is never rewritten under you.
- •Drafts in the sidebar. A Drafts row appears under Unread whenever you have something unsent. The draft in the composer you are looking at is not counted, so the row does not blink on and off as you type and send. Its page groups everything: Failed, To choose, Scheduled and Drafts. Edit any of them in place, with the same @, #, [[ and emoji menus as a composer, and send, schedule, reschedule or delete it. A channel or a person in the sidebar shows a pencil when you have a draft there.
- •Your agent can write you a few versions to choose from. Ask Claude Code for "a reply to Colin, a few options", and it runs
sharedoc draft create … --variants-file -. A strip above that composer then offers *Claude Code · 3 versions*, each labelled by how it differs (*short*, *with the date*). Hover a label to read that version as it would post. Use puts it in the box to edit, Send posts it as it is, and ⌥1–⌥6 switch versions from the keyboard. Whatever you had typed yourself is kept as a version called Yours, so nothing is lost when you switch. - •Attribution follows the words. An agent's version sent unchanged reads "Eric · via Claude Code". Change one word and it is simply yours. The agent can wait for your choice with
sharedoc draft set show <id> --wait: it learns which version you picked and whether you edited it. It never picks or sends for you. - •Send later. The chevron beside Send schedules a message: *Tomorrow at 9:00 AM*, *Monday at 9:00 AM* (on a Friday or Saturday) or *In 1 hour*, or a time you choose. It goes out as a normal post by you at that moment, and mentions notify when it is sent, not before. If it can no longer go (the channel was archived, or you lost access), it waits in Drafts marked failed and you get a notification saying why. From the CLI,
--at "mon 9:00" or --in 2h works on channel post, dm and thread reply. - •Drafts are private. Nobody else sees them, workspace admins included. A drafted @mention notifies no one until it is sent, and drafts are not searched, mirrored or logged.
- •CLI:
sharedoc drafts list; sharedoc draft create | show | edit | send | delete | pick; draft set show | dismiss; draft variant add | rm. --draft, --variant and --variants-file work on the post verbs. A new exit code, 7, means --wait ran out with nothing chosen.
v0.29.5
September 14, 2026
An HTML page brings its images and fonts
- •An HTML page shows the images, fonts and styles beside it. A page that loads
assets/logo.png or fonts/brand.ttf from its own folder — a brand board, an exported report — used to open with every picture broken, because the previewer couldn't follow the page's relative links. Now it opens the page from a link its neighbours resolve against, so what you see is what the page's author saw in their browser; Open in new tab gets the same. The page still runs in its sandbox, and it can only reach files in its own folder, for an hour, and only while you're still a member. An archived page, which has no such link, shows its source.
v0.29.4
September 14, 2026
A pasted picture looks like one
- •A file you paste into a message shows as a picture, not a path. Paste, drop or attach a screenshot and the box now says
[Image 1] where the caret was — not [[brightmotion-inbox/2026-09/eaf405a7-Screenshot 2026-09-14 at 2.42.26 PM.png]] — and a thumbnail of it appears under the text, with a spinner over it until it has uploaded. Videos are [Video 1], anything else [File 1]. × on the thumbnail takes it out (the token with it), and deleting the token drops the file. Send waits for an upload that is still going. The message posts exactly as before, with the file where the token was.
v0.29.3
September 14, 2026
A folded folder stays folded
- •A folder you fold in the file tree stays folded. Close
branding in a project and reload the page, or quit the installed app and open it again, and it is still closed — it used to spring back open every time. It is remembered per project, in this browser; a folder you have never touched starts open, as before.
v0.29.2
September 14, 2026
An HTML file opens as a page
- •An HTML file shows as the page it is. Open one from the file tree, a folder, or a
[[link]] in chat — a shared report, a generated graph — and the previewer renders it, scripts and all, instead of printing its source. The page runs in a sandbox: it can't see your session or anything else in the app, and a link inside it opens a normal tab. The </> button in the preview bar shows the source, as before; Open in new tab and Download are unchanged. .htm counts as HTML too.
v0.29.1
September 11, 2026
Push even while you're in the app
- •Get a push for every message, even while you are using the app. Browser notifications used to hold back while a tab of share-doc was open and in use, on the theory that the in-app toast had it covered — and it is easy to miss a toast in a tab behind other windows. Settings → Notifications now has Even while I'm using the app under Browser notifications: turn it on and every mention, direct message and followed-thread reply buzzes your devices the moment it arrives. Off by default; snooze and working hours still hold it. From the CLI:
sharedoc notify prefs --set pushAlways=true.
v0.29.0
September 11, 2026
Huddles
- •Talk, not type: huddles. Type
/huddle in a channel, a DM or a group — or press the headphones next to ☺ in the composer — and an audio call starts right there. A post goes up saying so, with a Join button on it, and it notifies people the way any post does: a DM or a group rings everyone in it (a push goes to a phone at once, not after your away minutes), and a channel lets its members hear about it at whatever level they have that channel on. So a bare /huddle in a channel on *Mentions only* is quiet — /huddle @colin brings Colin, and whatever you type after /huddle becomes the post's text. - •While it is on, the card shows a running clock and who is in it, a ring around whoever is talking, and a slash on anyone muted. The call you are in stays with you across the app, pinned to the foot of the sidebar (a strip across the top on a phone): where it is, how long, Mute, your microphone and speaker, and Leave. Replies to the post are its thread — the place for "can't hear you". One huddle per conversation:
/huddle where one is already going on joins it. Up to eight people. - •When it is over — a minute after the last person leaves — the post becomes the record: *🎧 Huddle · 23 min · Eric, Colin and Annie*, with everyone who joined. That is what the CLI, search and the chat mirror read, too.
sharedoc huddles list lists them. - •Calls go straight between browsers. There is no relay server yet, so two people who are *both* on strict networks — a phone on mobile data, some offices and hotels — may not be able to reach each other; when that happens the call says *couldn't reach Colin* rather than going quiet, and the notification settings page says the relay is not set up.
v0.28.1
September 11, 2026
Edit a message you sent
- •Edit a message you sent. Hover one of your own messages — in a channel, a DM or a thread — and the bar in its top-right corner has a pencil; on a phone, press and hold for the bar; with the message focused,
e does it too. The text opens in place, in the same box you wrote it in: Return saves (⌘Return where Return makes a new line), Escape leaves it as it was. Until now only the CLI could do this (sharedoc thread edit), and the web app showed the new text without saying anything had changed. - •An edited message says so. A small *(edited)* follows its text; hover it for when.
- •Everyone else sees an edit as it happens, and a deleted message goes for them as it happens too — both used to wait until the channel next reloaded for some other reason.
v0.28.0
September 11, 2026
The sync service on Linux
- •`sharedoc sync install` works on Linux. It was macOS only — on Linux it stopped with *run
sharedoc sync run under a systemd --user unit* and left you to write that unit yourself. It now writes it: ~/.config/systemd/user/sharedoc-sync.service, enabled so it starts when you log in and restarted if it dies, running the same sharedoc the command was run from. Its output goes to the journal, so sharedoc sync logs -f is journalctl --user -u sharedoc-sync and sync status shows systemd's view of the service next to the folders. sync uninstall stops it and removes the unit; the sync set and every folder stay. A user service stops with your last session, so sync install says how to keep it running headless (loginctl enable-linger). A unit you wrote by hand under that name is replaced, not refused. - •`sharedoc update` restarts it. The service runs the very bundle the installer replaces, and until now only the launchd one was restarted onto the new build. The systemd one is too, and reported the same way: *service restarted, pid 1234*. A service that is not running is left alone — one you stopped by hand stays stopped.
- •In
--json, the service is now reported as service: { manager: 'launchd' | 'systemd', installed, loaded, running, pid } by sync status, sync install and update, and sync install / sync uninstall say unit for the plist or unit file. On macOS the old launchd and plist keys are still there with the same values.
v0.27.5
September 11, 2026
A reaction pops when it lands
- •A reaction pops when it lands. Reacting to a message was a click and then a wait — the pill appeared whenever the hub's answer came back, and it appeared the way it would look a minute later, so it was easy to miss that anything had happened. Now the emoji springs onto the message the instant you click, a little too big and then settling, before the hub has answered; if the hub says no, the pill goes back. Everyone else's reactions do the same as they arrive, and the pill's count goes up — a channel used to only learn of another person's reaction the next time it fetched for some other reason. Each arrival pops once: opening a channel full of old reactions is quiet, and taking a reaction back is quiet too. Off with the system's reduce-motion setting.
v0.27.4
September 11, 2026
Chat stays put sideways on a phone
- •A channel or thread no longer slides sideways under your thumb. On an iPhone, a swipe that wasn't perfectly vertical dragged the whole message list left or right before it sprang back — there was nothing off to the side, but the list moved as if there were, which made scrolling a conversation feel loose. The list now only scrolls up and down. A wide table or code block in a message still scrolls sideways on its own.
v0.27.3
September 11, 2026
A thread opens at its latest reply
- •Opening a thread shows its newest reply. The thread panel opened at the root message, so a thread with twenty replies showed the first few, and on a phone — where the keyboard comes up for the reply box — barely one; the conversation you came to catch up on was several screens of scrolling away. It now opens at the bottom, the way a channel does, and stays there as late pictures and doc cards load and as the keyboard comes up. Scroll up for the root message; a reply that lands while you are reading further up leaves you where you are.
v0.27.2
September 10, 2026
Who reacted, without the wait
- •The names on a reaction show as soon as you hover. They were in the browser's own tooltip, which takes a second or more to appear and can't be hurried. They now have a tooltip of their own that appears after a brief pause, sits above the pill (below it on the first message of a list), and stays on screen at the edges of the window.
v0.27.1
September 10, 2026
Who reacted
- •Hover a reaction to see who left it. A reaction pill said *👍 3* and nothing more — to find out who the three were you had to ask. Hovering it now says: *You, Colin and Annie reacted with 👍*. You come first, then everyone else in the order they reacted; past ten names the rest are counted (*and 3 others*), as is anyone the page can't put a name to, such as a guest from another project. The same goes for the reactions on a doc comment.
v0.27.0
September 10, 2026
Updating the CLI is a command
- •`sharedoc update` updates the CLI. Keeping the CLI current meant going and finding the install one-liner —
curl -fsSL …/install.sh | sh — in the docs or on the /start page, every time. It is now a command. sharedoc update fetches that same installer from the server this CLI is pointed at, runs it, and says what changed: *updated ~/.share-doc/sharedoc.js (1.4 MB, was 1.4 MB)*, or that you were already up to date. A dev CLI updates from the dev hub rather than silently jumping to production, and run from a repo checkout it says so and points at git pull instead of quietly updating a different install. --dry-run shows what it would do. - •And it restarts the sync service onto the new build. The launchd service runs the very bundle the installer replaces, so until it was restarted it carried on running the old one — a fix could ship, be installed, and still not be running on the machine that installed it.
update restarts it and reports the new pid; --no-restart leaves it where it is. - •The installer now downloads the bundle beside the target and renames it into place. A connection that drops half way through can no longer leave a truncated bundle behind, and updating the CLI from the CLI swaps the name without touching the copy already running.
v0.26.6
September 10, 2026
A portrait picture shows whole
- •A picture in chat shows whole, in its own shape. A picture posted on its own sat in a 360 × 280 frame and was cropped to fill it, so a phone screenshot became a landscape strip across its middle — no status bar, no bottom of the screen, just whatever happened to be in between. It is now fitted inside 360 × 360 by its own proportions: a phone screenshot is a narrow tall tile you can read at a glance, a square is square, and a landscape picture looks as it did. A very tall one — a full-page screenshot — keeps a usable width and shows its top rather than its middle, as do portrait tiles in a grid of several. A picture with no stored size (one attached from the CLI or a synced folder) shows at its natural size, up to the same limit. Clicking still opens the full picture.
v0.26.5
September 10, 2026
A comment's time is the same on every machine
- •A `.comments.md` sidecar stamps its comments in UTC. The sidecar next to a doc with open threads was writing each comment's time in whatever zone the syncing machine happened to be in, with nothing to say which zone that was — so the same comment read *20:30* in one person's folder and *04:30 the next day* in another's, and a laptop that travelled rewrote every sidecar it synced. Stamps are now UTC and say so (
2026-09-04 16:14Z), and the header line says *times in UTC*. The file is byte-identical everywhere, which is also what an agent grepping it wants. The chat mirror is unchanged: it still renders in your machine's zone, and its README says which.
No more stray temp files in the tree
- •A synced folder stops turning editor temp files into documents. Almost everything that saves a file does it *atomically* — write a sibling temp, rename it over the target — and for the few milliseconds that temp exists it looked to the sync watcher like a new document. Every so often one got uploaded, and
issues/21-session-limits.md.tmp.16055.4954527a50be appeared in the project tree for everyone, empty, needing someone with the CLI to remove it. The watcher now knows the shapes editors use (*.tmp.*, *~, #*#, vim swap files, *.part, *.crdownload, the macOS and GNOME ones) and skips them, and — because the shape nobody thought of is the one that bites — it also waits a beat after any file appears and checks it is still there, at the same inode, before pushing it. A file that vanished in that moment was an atomic write's temp, whatever it was called. The same check means an atomically written file goes up whole rather than half-finished. A temp that was uploaded before this fix is no longer pulled back down onto your disk either — sharedoc sync run names any it finds on the server, with the sharedoc files rm to be rid of it.
A channel that opens at the newest post
- •Opening a channel lands on the last post, not a little short of it. Tapping a channel — coming back from a document, say — could leave the newest posts below the fold, with the scrollbar stopping a card's height from the bottom and nothing to say anything was missing. The list did scroll to the end; it just did it while the messages were still short. The cards under a doc link, pictures with no stored dimensions and code blocks all arrive a moment after the message they belong to and grow it *underneath* the scroll position, and the browser reports that growth as a scroll — so the channel decided you had scrolled back to read and stopped following. It now watches the height of the posts rather than each render, and only a scroll that actually moves the list counts as reading back. The channel stays on the newest post until you scroll away from it yourself — including when the composer grows under it, which used to slide the last message quietly out of sight — a message you send lands in view even when it carries an attachment, and a thread panel does the same once you are at the bottom of it or have replied.
A chip that stops hiding
- •An agent's post no longer hides under the one above it. Post as yourself and then post through the CLI a minute later and the second message joined the first as a continuation row — no name, and so no *via claude-code (opus-5)* and no project chip, because those are drawn in the header a continuation row does not have. The two things a reader most needs to tell apart, a person and an agent acting for them, were being run together on the strength of a shared name. Grouping now takes the whole byline into account, not just who the post is from: a change of agent, of model, or of the project a post is labelled with starts a new group with its own header. Consecutive posts that really do say the same thing still group as before.
Which model wrote it
- •An agent's post says which model wrote it. A message, comment or document write made through the CLI has always carried *via claude-code* beside the person it acted for. It can now carry the model too — *Eric · via claude-code (opus-5)* — everywhere the agent already showed: the chips in chat and in the thread panel, the history panel, search results, the unread list, the
.comments.md sidecars and the CLI's own tables. It is one more thing to weigh a post by: the same question answered by two different models is not the same answer, and the team can now see which one they got. Agents pass --as-model opus-5 alongside --as-agent claude-code (or set SHAREDOC_MODEL); nothing changes for an agent that doesn't, and a human posting from the browser is still just themselves.
Say what a post is about
- •A post can say which project it is about. A message in
#general — or a DM — now carries one optional project label: the small grey chip next to the author's name, linking to that project. A post in a project's own channel is labelled with that project already; the label is for everywhere else, where the work being discussed and the room it is discussed in are not the same thing. sharedoc channel post general --body "…" --project sharedoc sets it, and an agent posting from inside a connected folder gets it for free — the folder it is standing in is the project it is talking about. --project none posts without one, and sharedoc thread relabel <id> <project> fixes a post that went out wrong. - •Then find it again.
sharedoc channel history general --project sharedoc narrows a channel to one project's posts, and searching in:sharedoc now covers all three places that project is talked about: its docs, its channel, and any labelled post wherever it was made. The transcripts under ~/sharedoc/chat/ carry the label on the post line too. - •The label is a label, not a permission: it changes nothing about who can read a post or who was notified about it. It has to be a project everyone in the conversation could open for themselves — labelling a post with a private project is refused, because the label is visible to the whole room.
A refresh when a new version ships
- •The app tells you when it has been updated. A deploy replaces the code the servers run, but a tab you left open all afternoon keeps running the version it loaded — which can quietly disagree with the new one. A small strip now appears at the bottom of the left bar, above your name: *A new version is available*, with Refresh to reload the page and Not now to put it away until the next one. It comes from the live stream: the server names its build when a stream opens, and a deploy restarts that stream, so the tab hears about the new version within seconds without polling anything.
Readable code blocks in messages
- •A code block in a message stops fighting the column it landed in. Pasted output in a thread or a comment used to be a wall of monospace clipped at the right edge, with no scrollbar to say there was more, and tall enough to push the rest of the thread off the screen. Long lines now wrap by default — most of what gets pasted into chat is prose or terminal output, not code whose columns matter — and a block taller than about eighteen lines is folded, with *Show all N lines* to open it. Hovering a block shows a small bar above it: wrap on or off (a setting, remembered per browser, that every block on the page follows), copy, and open full width — a window-wide view, unwrapped, for a table or a diff that only reads properly wide. With wrapping off, the right edge fades where the text runs past it, so a clipped line looks scrollable instead of truncated.
Comments on disk
- •Comments land in the connected folder. A doc with open threads now gets a read-only
<doc>.comments.md next to it, written by the same sharedoc connect that syncs the doc — nothing to set up. It carries each thread's quote, the messages as they are (with via …, edits, deletions and reactions), a thread:<id> to reply to, and the line the quote is on in your copy (L41; L? when the text moved or repeats), re-rendered as the doc changes and as people comment. No open threads, no file; resolve the last one and it goes away. An agent that reads the folder now sees the review, not only the text. The sidecar is never pushed — the agent skips it, and the hub refuses *.comments.md as a document name everywhere — and --no-comments turns it off for a folder.
Sign in with Google
- •Sign in with Google. The login and signup pages have a *Continue with Google* button above the email and password fields. Clicking it and coming back is the whole flow — no password to choose, and the name and profile photo on the Google account become yours, so a new person lands in share-doc already looking like themselves.
- •If you already have an account, sign in and connect it. Clicking the Google button with an address that already has a share-doc account does not merge the two — it says so and sends you to log in with your password, after which *Your settings* connects Google to that account for good. Merging on the strength of the email alone would mean anyone who had signed up under your address first, which share-doc never asked them to prove, would quietly receive you into their account. Nothing about email and password changed otherwise: it works exactly as before, and the button only appears where the server has Google configured.
- •Connect or disconnect Google from your settings. *Your settings* has a Connected accounts section: connect Google to an account that has a password, or disconnect it again. An account that only ever signed in with Google has no password to confirm, so the password panel offers to *set* one rather than asking for a current one — and the last way into an account can't be removed, so disconnecting Google is refused until a password is set.
Notification sounds
- •A sound when a message lands. With share-doc open in a tab — even one behind another window — a mention, a direct message or a reply in a thread you follow now makes a short sound, where before the only sign was the badge. Pick it in *Your settings → Notifications → Sound*: Chime (the default), Bell, Marimba, Pop, or Off, with a Play button to hear each. The sounds are made in the browser, not downloaded. It stays quiet while you are looking at the very conversation it is about, while snoozed, and outside your working hours; two tabs make one sound, not two. The choice is per device, like a ringtone, so the phone and the desk can differ. A browser will not play audio until the page has been clicked once, so a notification that lands on a freshly opened tab is silent.
Highlights survive a CLI put
- •A `files put` no longer drops every comment highlight in the doc. Comment a line in the browser, then
sharedoc files put the doc from the CLI — or let a connected folder pick up a change to the file, or restore a version — and the highlight was gone: the card in the panel still showed its quote, and clicking the quote still selected the text, but nothing in the page was marked, for anyone, until the hub restarted. Every highlight in the doc went, not only the ones in paragraphs the put touched; a put of byte-identical markdown took them off too. The hub merges parsed markdown into the live document (updateYFragment), and markdown carries no marks — so every highlighted paragraph read as changed and lost its mark. The hub now carries the live document's highlights onto the parsed text before the merge, the way the raw view already does for its own typing: by position, so a highlight on the second of two identical lines stays on the second, with the quote as the fallback when the sentence itself was reworded; only a highlight whose text is gone is dropped, and its thread says so. - •Under the hood the raw view's position map and mark-carrying moved from the web app into
@share-doc/collab, with the character diff pluggable — the browser keeps CodeMirror's, the hub uses diff-match-patch's — so both merges share one implementation.
Full-screen drawer, larger type
- •The phone drawer is the whole screen. The left bar slid out over 86% of the width, with a sliver of dimmed page showing beside it. Every tap in it goes somewhere — a channel, a doc, a person, the ⌘\ button — so the sliver bought nothing; the drawer now fills the screen, and its colour runs to the edges — up under the status bar and the notch too, on the installed app, where the top used to be a grey strip above the page. Tapping the channel you are already in closes it too (it used to stay open, since nothing navigated), as does opening a profile or thread from it.
- •Everything one size larger. Every type size in the app — messages, the composer, the left bar, menus, labels — is up one pixel, and a document's default reading size is 17px (the ± in the page menu still sets your own).
- •Notify level moved into the channel's ⋮ menu. The *All posts / Mentions only / Nothing* select sat in the header, where on a phone it left the channel's name a few letters wide. It is the first section of the ⋮ menu now, with a check on the current one — the menu draws for everyone, not only the people who can manage the channel.
- •The @-mention pill covers the whole name. In the composer, the highlight under
@Justin PBE stopped a letter short of the name. The generic chip style had leaked into the pill and shrunk its text; the pill is now sized by the field's own text.
Opens where you left off
- •The app opens where you left off. Opening share-doc from your phone's home screen — or going to
/ — always landed on 📥 _inbox. Now it opens on the channel or document you last had open, in whichever workspace that was, with the thread or comments you had beside it; only when that place is gone (a deleted doc, an archived channel, a project you can no longer open) does it fall back to _inbox as before. The place is remembered as you move around, in a cookie the server reads at /, and checked against what you can open before you are sent there.
Emoji as you type
- •`:)` and `:D` become 🙂 and 😃. A text emoticon used to go out as the two characters you typed, and read in the channel as something the app forgot to render. Now the composer swaps it for the emoji the moment you type the space after it —
:) :-) :D :( ;) :P :O :| :/ :* :'( >:( XD — in the channel and DM box, the thread pane, a doc thread, a comment draft and the edit composer alike; a message that ends on one and goes out on Return converts it on the way. The swap happens in the composer, not at render time, so what you see before you send is what gets sent, and the emoji — not :D — is what lands in the day file on disk. - •`:tada:` and friends. The shortcode names people bring from Slack and GitHub work:
:tada: becomes 🎉 on its closing colon, and so do :+1:, :white_check_mark:, :eyes:, :rocket:, :fire:, :pray: and the rest of the reaction picker's table — one table, now with a name for every emoji, which the picker's tooltips show so the names are learnable. Type : and two letters for a menu of matching names — arrow keys, Return or Tab to pick, Escape to dismiss — the same menu @, # and [[ open. - •Where nothing is rewritten. Inside a code span or a fenced block
:) stays :). https://…, 10:30:, C:D and the tag forms ([[thread:…]], @[Emily](user:…)) are left alone: a token has to start the text or follow a space (or an opener like (, *, ") to count. An emoticon converts only when you type the space after it, so :Dave and :pray: are never cut short; and only faces that mean nothing else are on the list — 8), B) and <3 stay as typed ((see step 8), option B), latency <3 ms), with :sunglasses: and :heart: as the names. One ⌘Z gives the typed text back, and a send after that leaves it as you typed it.
A calmer left bar
- •People sit right under the workspace switcher, above Projects. They came after the projects, and once a project or two was expanded the People list — which is also your direct messages — was off the bottom of the page on every screen. The order is now Unread and Channels, People, Projects, then the connected folders. People stays short so it does not push the projects down in turn: everyone online and anyone with an unread message always shows, plus the first few others, and the rest fold into one *5 more…* row — click it for everyone, *Show fewer* to fold them back; remembered per workspace.
- •People rows are the same size as everything else. A person who was a link (to their DM) or a button rendered at 16px while the project and file rows beside them were 13px — one style rule reset the size after another had set it — so the People list read louder than the projects next to it. The whole left bar now uses one type scale: the workspace name, then every row — channel, person, project, file, folder — at one size, with counts, roles and section heads a step smaller.
- •Connected folders are one line. Every synced folder, with its dot and its project, was a permanent block at the bottom of the left bar — status worth a glance, not a panel. It is one row now: *2 folders syncing* with the health dot (hollow when nothing is), the folders themselves in the tooltip, and the list — plus, on a project page, *Connect a folder to …* with the command to copy — one click away. Open or closed is remembered, and the row follows folders as they connect and disconnect.
- •A project's file tree no longer has an inner scrollbar of its own (the old 44vh cap): the middle of the sidebar is the one thing that scrolls, and a long tree pushes only the projects below it, which fold.
The document as markdown
- •The document as markdown, in the app. The markdown *is* the document — it is what sits on disk, what syncs, what an agent reads and writes — and until now the browser only showed the rendered page. A Raw button in the doc header (and ⋯ → Raw markdown) swaps the page for its source: monospace, line-numbered, the markup drawn quietly and the text loud, in light and dark alike. It is the very text
sharedoc files cat prints — the same serializer, byte for byte — so the fastest way to see why something renders the way it does is to open it. Copy in the corner puts the whole document on the clipboard. It stays live: someone typing in the rich editor, a CLI files put, a restore, an agent's write — the source updates in place as they land. - •Editing the source, together. The raw view is an editor for anyone who can write the doc — a viewer or commenter reads it, an archived doc says *Archived — read-only* until it is reopened. What you type is merged into the shared document on a typing pause, not on a save button: the hub already merges a file that changed on disk under people editing in the browser (
updateYFragment), and the raw editor is one more writer of that kind, with a faster loop. Nothing is locked and there is no second copy of the text — two people in the raw view, or one raw and one rich, converge on the same document, with their own edits and cursors intact, the way two rich editors do. Undo in the raw view takes back your typing, never someone else's words. - •Your text is not rewritten under your hands. The serializer has a canonical form —
- for a * bullet, a \ before a literal * or [, a table cell folded onto one line — and every apply is markdown → tree → markdown. The raw editor never rewrites your buffer on its own applies; what you typed becomes canonical when you leave the editor (blur), and that rewrite is an undo step of its own, so ⌘Z first gives you back exactly what you typed. Someone else's change arriving mid-sentence is rebased over your unsent typing and applied as a change set, so the caret stays where it was. - •Cursors cross the boundary. People in the raw view see everyone's caret and selection at the character, in their colour, and people in the rich editor see the raw editors' the same way — one awareness field, one shape, mapped through a position map the serializer now records (
serializeMarkdownWithMap: where each block landed in the text, and a character alignment within it). Exact wherever there is text; inside markup — a **, a - , a fence line — it snaps to the nearest character that has a position. - •Under the hood the rich editor's cursor plugin is ours now (
PresenceCursors, replacing @tiptap/extension-collaboration-cursor): the stock one clears the shared cursor whenever its view updates without focus, which is right for one editor per document and wrong the moment the raw view publishes into the same field. Same markup, same styles, same updateUser command.
Revision history in the doc
- •A doc's revision history, in the web app. Every save has been recorded for a long time — a debounced editor save, a
sharedoc files put, an agent's write, a merge — and only the CLI could see it. Open a document, then ⋯ → History, and the panel on the right lists every version, newest first: who made it (their avatar and name, with *via Claude Code* beside them when an agent acted for them; the agent or the source when nobody is recorded), how long ago, how much the text grew or shrank, and the note the writer left with --message where there is one. The list is the same one sharedoc files history prints, from the same route. - •Click a version to see what it changed. The diff against the version before it — added lines green, removed lines red, the sign column kept so a copied selection still pastes as a diff — exactly what
sharedoc files diff --from --to prints, so the CLI and the browser never disagree about what happened. Shift-click a second version to see everything that changed between the two. A Document tab beside Changes shows the whole doc as it stood at that version, rendered the way the live one is, read-only. - •Restore this version. Below the diff, for any version but the current one, when you can edit the doc. Restoring writes that version's text as a *new* revision — history is never rewound, the row you restored from stays put, and undoing a restore is restoring the version before it. It goes through the same path a CLI
files put takes, into the live document: every tab that has the doc open follows along, what the doc said a moment ago is replaced — that is what a restore is — and a comment finds its text again by quote, the way it does after a CLI put. A version whose text already matches the current one says so instead of offering the button. The new row says *Restored version 6*. Archived docs do not offer it — Reopen is the way back in. - •History keeps up. A save that lands while the panel is open — yours, someone else's, an agent's — appears at the top without a reload. It takes the place of the comments panel while open, the way a person's profile does, and comes back the same way.
- •Who, not just which id.
files history — the API and the CLI table alike — now carries author: { id, name, email } for each revision, resolved on the hub, so a departed member still reads by name and a list never has to look people up one at a time. authorUserId stays for scripts that read it. A restore is recorded as source: restore, its own kind of write like merge, so the first keystrokes after one are not folded into the row that says what was restored.
A quieter Archive button
- •Archive in the doc header is a plain button now, not a filled one. It was drawn as the accent-coloured primary button — the loudest thing in the header, on every doc, all the time. It was put there on purpose, the way GitHub puts *Close issue* one click away, and it stays there: same place, same one click to the *Archive this doc?* confirm, still in the ⋯ menu too. It just wears the bordered secondary style the confirm's Cancel already uses, in light and dark alike. The confirm's own Archive — the button that actually archives — keeps its fill, and so does Reopen on an archived doc, where it is the only action in the header.
Markdown in chat messages
- •Markdown in chat messages. A message used to be plain text with a few inline marks: a list showed its dashes, a fenced code block its backticks, a quote its
>, a heading its #. Messages are markdown — the same markdown sharedoc sync writes to the day files — so they now render the way a doc does: bullet and numbered lists (nested too), - [ ] task lists, > quotes, fenced code with its language shown above the block and indented code, headings, --- rules, tables, and a picture for an image with a full URL. A single newline is a line break, the way Slack reads one; a blank line starts a new paragraph. In a channel, a thread, a DM and a doc's comment thread alike. - •Inline markdown is more correct, not just more complete. Bold, italic, ~~strike~~,
code and links parse by CommonMark's rules now, so snake_case_name is never italic, a stray * is a *, and a [label](url) inside a bold run keeps both. @people, #channel and [[file]] chips, bare @names and bare URLs still work — inside a list item or a quote too — and inside code a tag is shown as the text that was typed. - •Nothing typed in a message can run as code. Raw HTML is text (
<script> shows as <script>), a javascript: or data: link is not a link, and the renderer builds elements rather than HTML. Task-list checkboxes are drawn but disabled — ticking one would mean editing the message. - •Headings in a message are modest. A
# line renders one step up from the body, not as a banner: the same message reads as a section heading in the mirrored day file, so it is de-emphasised rather than encouraged. A long code block or a wide table scrolls sideways inside the message instead of stretching the pane, which matters in the 340px comment panel and on a phone. - •Snippets read cleanly. The one-line preview in the unread list, a notification, an email and a thread row drops list markers, heading hashes, quote bars, fence lines and table pipes —
- [x] hub deployed reads *hub deployed* — instead of showing the markup.
The composer is one card
- •The message box is one card, drawn the way Slack draws it. It used to be a form field with a paperclip and a send arrow standing beside it. Now a single bordered card holds everything: the text is the body of the card, starting one line tall and growing with what you type up to about 40% of the pane, then scrolling inside; a toolbar runs along the bottom edge inside the border — 📎 (and 📷 on a phone), then ☺ — with Send at the bottom-right corner. The card, not the field, takes the focus ring. Upload progress chips sit inside the card, between the text and the toolbar. The same card in all five places you write a message — a channel or DM, the thread pane, a doc thread's reply, a new doc comment, and the box you get editing one of your own messages — so they look alike for the first time.
- •Send is an arrow, quiet until there is something to send. Return already posts where there is a real keyboard, so the button does not need to shout; it fills with the accent colour as soon as the box has text. On a phone, where Return is a newline, that filled arrow is the send. Cancel/Save and Cancel/Comment keep their words where a Cancel sits beside them.
- •An emoji from the composer. The ☺ in the toolbar opens the same picker the reactions use and puts your choice at the caret — then hands the caret straight back.
- •The @ / # / [[file]] menu opens where you can see it. In a channel it opened below the field — which is the bottom of the window, so the list was off the screen. A composer pinned to the foot of its pane now opens the menu upward, above the card; a comment draft or an edit in the middle of a list still opens it downward.
- •#channel suggestions appear. The hub has always answered
#gen with the matching channels; the web app dropped that part of the answer on the way in, so the # menu never had anything to show. It lists the channels now, and picking one inserts #general with its pill. - •Return sends and Shift+Return makes a newline exactly as before (⌘⏎ still sends too); on a phone Return is still a newline and the field stays at 16px so iOS does not zoom on focus.
Links between docs work
- •A relative link to another doc opens it. Docs on disk link to each other the way markdown always has —
[Features](./FEATURES.md), [the plan](../plan.md), [notes](sub/deep.md) — and in the web editor those links did nothing: a click placed the caret and that was all, so people pasted full app URLs instead. A link to a file in the workspace now behaves exactly as a /p/… link already did: it says whether the doc is open, archived or gone, previews on hover, and follows. While editing, a plain click still places the caret — ⌘/Ctrl-click or middle-click opens the link in a new tab. In a read-only (archived) document there is no caret to place, so a plain click opens it right there. A doc opens in the editor; a PDF or an attachment opens in its preview; a folder link (notes/) opens the folder. - •A `#heading` link scrolls to the heading, in this document or in the one it points at (
./deep.md#setup). The GitHub-style #setup finds the heading, as does the #sd-setup form a copied bookmark uses. - •An external link opens in a new tab, the way links elsewhere in the app do, instead of doing nothing.
- •A link to a file that is not there says so. It is drawn as missing, as before; hovering it now reads *Not in this project: links/nope.md*, and clicking it shows the same note instead of leading to an empty page.
- •
[Deep](sub/deep.md) and [Features](FEATURES.md) used to render with no href at all — the editor's link sanitiser mistook a plain relative path for something unsafe — so even the browser's *Copy link address* gave nothing. They carry their target now. And a link followed from an archived doc no longer reloads the whole app on the way.
The account row stays put
- •Your name at the bottom of the left bar stays there. The account row — the way to Your settings, Notifications → Snooze and Log out — scrolled away with everything above it, so in a workspace with a few projects expanded it sat below the fold and those three things became “scroll to the bottom of a long list first”. The whole sidebar was one scrolling column. Now only the middle scrolls — channels, projects, people, connected folders — and the workspace picker at the top and your account row at the bottom stay pinned however tall the list grows, on a short window as much as a tall one, and in the phone drawer.
- •The account menu still opens upward from the pinned row, and the drag-to-resize and ⌘\ collapse work as before.
Project names in any case
- •A project name works in the CLI however you type it. The website shows a project as
ShareDoc, but sharedoc files list ShareDoc answered *no project 'ShareDoc' you can open* — only the lowercase slug matched, and nothing said so. Every command that takes a project now accepts the slug or the display name in any case (ShareDoc, sharedoc, Share Doc all reach the same project), and so do a /p/ShareDoc link and the in:ShareDoc search filter. Whatever you typed, the file lands in the project's real folder on the hub. - •A typo gets a suggestion. When nothing matches, the error names the nearest project you can open —
no project 'sharedok' you can open — did you mean 'sharedoc'? — and points at sharedoc projects list --json when nothing comes close. The suggestion is also in the hint of the --json error envelope. - •
sharedoc sync add resolves the project the same way and stores the real slug, so the pair it writes is the one the hub knows.
Hover you can see in light mode
- •Hovering a row in light mode now shows. The highlight behind a hovered sidebar row, menu item, file, member or ⌘K result was a flat grey one shade off the white it usually sits on — and the same grey as the canvas, so in the chat a hovered message barely registered at all. It is now a translucent tint, the way dark mode has always done it, so it darkens whatever it sits on: plainly visible on the white sidebar and menus, and on the grey canvas too.
- •Buttons darken a little more on hover, and an emoji reaction stays a bubble on a hovered message. The bubble used to be lighter than the highlighted row under it, so it faded out exactly when you moved to click it. Dark mode is unchanged.
Archiving the doc you are reading
- •Archiving the document you are reading no longer blanks the app. Clicking Archive on an open document closed the file and then replaced the entire page — sidebar, chat, tabs and all — with a bare “An unexpected error occurred.” Only a reload brought the app back, by which point the document was, confusingly, archived exactly as asked. The archived banner now appears above the document the way it always did from a fresh page load, and the document switches to read-only in place.
- •A page that goes wrong takes only itself down. An error while drawing a document used to fall all the way to the root of the app, which draws over everything. It now stops at the page: the sidebar, the chat panel, the tabs and the rest of the workspace keep working, and the page itself offers a Reload.
Projects expand and collapse like folders
- •A project in the left bar expands and collapses like a folder, and more than one can be open. Opening a project used to expand its whole tree — every file, the Archived group, the Members list — and that was the only project you could see inside; there was no way to fold it back up short of opening a different one. So a workspace with a few projects became one very long column you had to scroll past to reach anything below it. Each project row now has its own chevron. Click it to fold a project away, or to open one you are *not* working in — its files are fetched and shown right there, so you can keep two projects side by side and work in either.
- •What you open stays open. Going to a project expands it, and it stays expanded after you move on to another project or to a channel. Folding one up is remembered too — per workspace, in this browser — and survives a reload and the background refreshes that happen while you work. A folded row keeps its
· 12 docs count, so you can still see how much is inside. - •Option-click a chevron for that project alone (⌥ on a Mac, Alt elsewhere) — everything else folds away, the way Finder does it. It is the quickest way back to a short sidebar after a morning of opening things.
- •The Archived group, the Members row and the + belong to the project the page is in; another expanded project shows its files.
A DM is named after the person
- •A direct message is named after the person you are talking to. The header read
Claude's workspace / #5844c28c-c01c-4e29-be88-f54e76cae759 — the conversation's internal id, prefixed with # as though a DM were a channel — and the browser tab said the same. Both now say the person's name (or, in a group, everyone else's), with their avatar next to it, the same disc their sidebar row shows. A channel is still #general. - •A
/c/<id> link to a conversation you cannot open no longer answers with the id in quotes; the empty channel page says the conversation is not here.
Return sends
- •Return sends a message; Shift+Return makes a new line. Every composer — a channel, a DM, a thread reply, a document comment, and the box you get when you edit one of your own messages — now posts on Return, the way Slack, Discord and iMessage do. ⌘⏎ (Ctrl+⏎) still sends, so nobody who learned that has been broken, and the placeholder tells you which one this keyboard is offering.
- •On a phone or tablet Return stays a new line — there is no Shift to hold on a soft keyboard, so the send button is still the send.
- •While the
@/#/[[file]] menu is open, Return picks the highlighted item rather than sending, and Return in the middle of an input-method candidate (Japanese, Chinese, Korean) belongs to the input method — it no longer posts a half-typed word.
Reinstalling the CLI fetches the current build
- •Reinstalling the CLI fetches the current build. The deploy that added the schema gate rebuilt the CLI, but the edge cache in front of the hub kept serving the previous bundle under its default four-hour rule for
.js URLs, so install.sh handed back the very build the hub was refusing and everyone who had installed from it was locked out. The hub now sends the bundle with cache-control: no-store and an x-sharedoc-schema header naming the schema it carries, and both installers download it with a cache-busting query. - •`sharedoc sync status` says `refused` when the hub is turning the daemon away. A pair whose every connection was refused (an expired login, or a build older than the hub's schema) read
live with no error, because the folder watcher was up and the refusals went only to the log. The state is now refused and the error column carries the reason and what to do. - •
sharedoc version prints the schema fingerprint next to the version, so it can be compared with the hub's header.
A stale tab can no longer erase what it cannot read
- •A tab left open across a deploy can no longer erase what it cannot read. The build that added checkboxes armed every browser tab opened before it: a tab whose editor had never heard of a task list did not skip the items, it deleted them from the shared document and everyone's copy followed — thirty items gone from a todo.md, attributed to someone who typed nothing. Every client now tells the hub which document schema it was built with, and the hub refuses one that differs *before* the first byte of the document is sent. A refused tab reloads itself into the current build (once; if that does not help it says so and offers a Reload button), and a refused
sharedoc connect prints that it needs to be reinstalled instead of syncing nothing. - •Bold around a code span in a table cell comes back whole. `
**ElevenLabs eleven_flash_v2_5 with-timestamps** in a cell was written back as **ElevenLabs ****eleven_flash_v2_5** with-timestamps — a pair per run, colliding, with the bold stopping short of the last words. Cells now go through the same mark serializer as the rest of the document, so a mark opens once and closes once. Side effect, one-time: a literal *, [, ` or \` in a cell is now escaped in the file the way it already was in a paragraph. - •Documents that already lost items are not repaired automatically: restore the file from git or an earlier revision and the next push keeps them.
Push notifications say what went wrong
- •A dead subscription no longer disappears in silence. When the push service rejects a device (404/410) the hub now logs which service and which browser before it removes the row, and a refused send logs its status. Before this the most common failure left no trace: the row was simply gone, and the settings page could only guess.
- •“Enable on this device” makes a fresh subscription when the hub has lost the old one. The browser kept holding the subscription the push service had just rejected, and enabling again re-saved that same dead one, so the device failed the same way every time unless the whole preference was turned off and on. It is now replaced.
- •The test notification goes to the browser you are looking at, and its answer says which of three things happened: delivered (if nothing showed, check the browser’s or the OS’s notification setting), the subscription is dead and has been removed, or the push service refused it and with what status. “Sent to 2 devices” used to count the phone.
- •No dialog is explained. A site that was already allowed shows no permission prompt; the page now says so instead of looking like a button that did nothing. A prompt closed without an answer — or Chrome’s quiet bell in the address bar instead of a dialog — gets its own hint rather than “blocked”.
- •Hub:
POST /api/v1/push/test takes { endpoint } and answers { sent, dropped, failed, statuses }.
Checkboxes survive sync
- •Task lists round-trip.
- [ ] todo and - [x] done used to come back from a sync as - \[x\] done — the brackets escaped, the checkbox gone, on disk and on the server — because the markdown bridge had no rule for the marker and treated it as text. The bridge now reads GFM task lists into real checkboxes and writes them back as - [ ] / - [x], nested lists included, and a list that mixes checkboxes with plain bullets keeps each item as written. In the editor, type - [ ] or pick Task list from the / menu; click a box to tick it. Task markers on numbered lists (1. [ ]) are still plain text. - •Synced files end in a newline. Every file the sync wrote stopped after the last character, which put a
\ No newline at end of file diff on every file in a folder that is also tracked in git. Canonical markdown now ends in exactly one newline; expect a one-time rewrite of each synced file to add it. - •Files that already lost their checkboxes are not repaired automatically: restore the file from git (or retype the markers) and the next push keeps them.
Profile photos
- •Upload a picture of yourself. Your name at the bottom of the sidebar now has Your profile, which opens your own profile in the right panel — the same one that opens when you click anyone else. Hover the big avatar for a camera button: pick a photo, drag and zoom it inside a circular crop, and save. It replaces the initials disc everywhere at once — the sidebar, People, message gutters, reply stacks, doc presence, the members table — for everyone, not just you. Remove photo goes back to initials.
- •Photos are cropped square in the browser, so what you frame is what you get, then stored at two sizes and served with a hash in the URL: changing your picture is instant for you and cached forever for everyone else, with no stale copies to clear.
- •Other people's browsers pick up your new photo the next time their page loads its shell, not the instant you save it.
A project's own settings
- •New project now asks two questions instead of assuming. The + beside Projects opens a dialog: Workspace (everyone in the workspace can open and edit it) or Private (only you, and anyone you add), and a checkbox for the
#slug channel it used to create whether you wanted one or not. - •A project's owner can change its visibility. Workspace settings → Projects lists every project for an owner or admin, and the ones *you own* for everyone else — before this the section was admin-only, so a member who created a project could not make it private. The Channel column links to the project's channel, or offers to create one for a project that has none.
- •Archive or delete a channel from the channel itself. The ⋯ in a channel header offers Archive channel (hidden for everyone, posts kept) and Delete channel (permanent, and it says how many posts go with it) — for the channel owner, the owner of its project, or a workspace admin. A project channel deleted this way stays deleted.
sharedoc channels delete <name> --yes does the same from the CLI. - •Going private now takes the project's channel out of everyone else's sidebar. It used to linger there — unopenable, but still listed.
Connected folders, all of them
- •The sidebar's Connected folders lists every folder synced to the workspace, whichever project is open — it used to show only the open project's, so a second
sync add pair looked as if it hadn't registered. Each row names its project and opens it; the list updates live as folders connect and disconnect, on every page.
The sync set: many folders, chat on disk, a service
- •`sharedoc sync add <project> <dir>`, as many times as you like, then `sharedoc sync run` keeps every folder ⇄ project pair live in one process.
sync run --once reconciles everything and prints a table; sync status shows each pair's state, last push and pull, and any error. sync add / sync rm while it runs take effect without a restart. - •Channels as markdown on disk.
sharedoc sync add --channels mirrors every channel you can see (DMs only with --dms) under ~/sharedoc/chat/: one folder per conversation, one file per day, replies nested under their post, the thread:<id> on every post line — so a local agent can read the discussion around its files and reply with thread reply. Read-only; never marks anything read. - •A service on a Mac.
sharedoc sync install runs it as a launchd user agent — starts at login, restarted if it dies — with sync logs, sync status and sync uninstall.
Snooze and working hours
- •Your name at the bottom of the sidebar now opens a menu — Your settings, Notifications, Log out. Under Notifications → Snooze for…: 30 minutes, 1 hour, 2 hours, until tomorrow, until next week, or a custom time. A snooze holds browser notifications and email on every device until it ends; the badge, Unread and the live stream carry on, so nothing is missed.
- •Working hours (Your settings → Notifications, or the menu): allow notifications Every day or Weekdays, between two times — 8:00 AM to 9:00 PM by default. Outside the window nothing buzzes or emails you. The hours follow the time zone your browser reports.
- •Other people can tell. Someone with notifications snoozed gets a small moon where their presence dot is. A direct message with them shows a banner — *Alex has notifications snoozed until 3:45 PM* — with Notify anyway for the message that cannot wait.
Media from a phone
- •A 📷 beside Send on a phone opens the camera straight away; the 📎 opens Photos or Files. The document bar gets both too, since a phone has no paste and no drop. A tap on a picture in chat opens the lightbox with Download and Open in folder.
- •iPhone photos arrive as JPEG. A HEIC is converted in the browser before upload, so it renders everywhere and gets a thumbnail; a photo over 20 MB or longer than 4096 px on a side is downscaled first. The original is not kept.
- •The drag-and-drop overlay no longer appears on a phone.
Video
- •Drop a video into a document (or
/Video, or Insert video… in the ⋯ menu) and it plays right there, with a poster. The markdown holds a plain link to the file, so GitHub and any editor still get a working link; share-doc draws the player under the paragraph. - •Posters are made in the browser as the video uploads: a frame half a second in, pinned on the file. The folder view and chat attachments show it. A video that arrives from the CLI or a synced folder has no poster until someone uploads one from a browser.
- •A video this browser cannot decode (an HEVC
.mov in Chrome) says so and offers the download instead of a black box. - •For agents:
sharedoc files links <project> <doc.md> lists every image and link in a document resolved to project paths, and files cat --with-media appends the same list after the text.
Pictures in chat
- •Paste, drop, or attach a file in any chat composer — channel, thread, DM, and doc comment — and it shows up under the message as a picture or a video player, not a card with a file icon. A 📎 beside Send opens the file picker. Several attachments tile two-up; more than four fold behind a +n.
- •Click a picture for the lightbox: full size on a dark backdrop, ← → through the message’s pictures, download, open in folder, Esc to close. Videos play in place with a poster when there is one.
- •CLI:
sharedoc channel post general --body 'The whiteboard' --attach ./whiteboard.jpg (also thread reply, thread create, dm). File references in thread show --json now say what the file is — mime, size, width, height, thumbUrl — and files cat --thumb returns the small version, --out <file> writes to disk.
Pictures that stay in the document
- •An image pasted or dropped into a document now lives beside it. The file lands in a
media/ folder next to the doc and the markdown gets a plain relative link —  — so it is right there in a connected folder, GitHub renders it, and it never expires. Until now the editor wrote a signed storage URL that died five minutes later, in the .md on disk and for every reader. - •Drop a file onto the page. Images go into the doc where you dropped them; anything else goes to
_inbox with a link where the drop landed. A chip holds the spot while the upload runs. /Image in the slash menu and Insert image… in the ⋯ menu open a file picker. - •Images in synced folders show up. A doc that says
 — written in any editor, synced with sharedoc connect — renders the picture. The editor resolves relative and project-root paths when it draws, so the document keeps the path and only the screen gets a URL. - •Fixed: markdown images vanished on load. The bridge tried to put a block image inside a paragraph, failed, and dropped the whole paragraph. Images now parse to block level and serialize byte-stably.
- •Repair for existing docs: a script finds every signed URL in a document, moves the file into the doc’s project at
<folder>/media/<name>, and rewrites the link; dry run by default, idempotent.
v0.12.12
September 3, 2026
Seven things the last few days found
- •People are the direct messages. The sidebar’s People list is now where you open a DM: tap a person to go to your conversation with them (or start one), see their unread dot or mention count right there, and use the + on the People header for a new or group message. The separate Direct messages section is gone — and with it the green dot that was always green, whether or not the person was online.
- •The green dot stays on. Presence in the People list no longer blinks off when the live stream hiccups, and an open tab comes back online on its own after the hub restarts instead of going dark until reload. A closed tab still goes offline within seconds.
- •Archiving the doc you are reading leaves you on it, closed. The page stays put and turns read-only under the *Archived by you · just now · Reopen* banner — no error page, and no bounce back to open. A doc archived right after you typed in it no longer reopens itself a moment later.
- •Going to a channel no longer closes the project you had open in the sidebar. Its tree stays expanded until you open another project.
- •A + on each folder in the sidebar, on hover, starts a new doc inside it with the folder’s path filled in for you.
- •iPhone and iPad: a one-time strip says to add share-doc to the Home Screen to get notifications (Share → Add to Home Screen). It is not shown in the installed app, and Got it dismisses it for good in that browser.
- •The reply box in a document comment thread fills the panel’s width instead of stopping halfway, so the placeholder sits on one line.
v0.12.11
September 3, 2026
Reactions you can read at a glance
- •Emoji reactions are solid bubbles — grey until you have reacted, the accent colour once you have. They used to be outlined chips whose "you reacted" state was a faint tint you had to look for. The + stays an outline, since it is not a reaction.
v0.12.10
September 3, 2026
Links that say what they point at
- •A link to another document tells you whether it is still open. Inside a document, a link to a doc here is drawn by what it *is*: open, archived (muted and struck through, the way a closed issue reads), or missing (red and dashed — a typo, or a doc deleted out from under the link). A master TODO doc full of links reads like a list of open and closed issues, with nothing to click.
- •Hover one for the detail: a small panel with the title, the status,
Project / folder, who last edited it and when, and Open. It waits for you to rest on the link, and stays put while you move onto Open. - •Three ways through a link, since a document is a text editor and a plain click still places the caret: the panel’s Open, ⌘/Ctrl-click, or a plain click in an archived doc. On a phone a tap raises the panel instead, and a tap elsewhere puts it away.
Two things a phone found
- •Your settings now says whether notifications are on for this device. A real Notification settings button, and beside it what this browser is actually doing — on, off, blocked, or, on an iPhone, "add share-doc to your Home Screen to get notifications on this device". Reaching that page used to mean spotting an unstyled link in the middle of a sentence.
- •The chat composer no longer falls off the bottom of a phone screen. The frame sized itself to the viewport at that instant, which on iOS can be measured while the browser’s toolbars are retracted; it now sizes to the viewport with them showing, and the keyboard shrinks the page rather than sliding over the composer.
Someone is typing
- •"Colin is typing…" above the composer in channels, DMs and chat threads, with three bouncing dots. It names up to three people, then says "Several people are typing…". A thread’s indicator stays in the thread.
- •It stops when they stop. The line fades a few seconds after the last keystroke and disappears the instant that person’s message lands — nobody is left reading "Colin is typing…" after Colin has shut his laptop.
- •Nothing is stored. Typing is a live frame on the same stream that already carries notifications: no event row, no database write, and nothing replayed when a browser reconnects. A public channel’s frame goes to the workspace; a DM’s or a private channel’s goes only to its members.
A phone-shaped share-doc
- •One screen at a time on a phone. Below 720px the sidebar, page and right panel stop sharing the width. The page fills the screen; the sidebar is a drawer behind ☰ in the header that closes when you pick something, tap outside, swipe it left or press Escape.
- •Threads, profiles and comments open full screen, with a Back bar to return to what you were reading.
- •Documents get the whole width. The sheet loses its desktop margins and border, and the document bar keeps the name, comments, Archive and ⋯ — scrolling sideways rather than piling up.
- •Reach a message’s actions with a long press. Where there is no hover, press and hold a message for its react and reply buttons; touch anywhere else to put them away.
- •Details that stop the small annoyances. The header keeps only the last breadcrumb and turns ⌘K into a magnifier, the folder toolbar fits two rows with the preview under the grid instead of beside it, settings tables scroll instead of clipping, no page scrolls sideways, and every field you type into is big enough that iOS does not zoom the page on focus.
Notifications that reach you
- •Browser and phone notifications. Turn on Browser notifications in *Your settings → Notifications* and mentions, direct messages and replies in threads you follow arrive as system notifications on that device — even with the tab closed. Clicking one opens the right channel or thread. They go out only when you are away from the app (no tab open, or none in front for your "away" minutes); while you are looking at a tab, the in-app toast and badge do the job. Turning the preference off stops every device.
- •A one-time offer. The first time you use share-doc in a browser that can do this, a strip under the header asks whether to turn it on — Turn on or Not now — and never asks that browser again.
- •Installable. Add share-doc to your Home Screen or Dock (Chrome’s install button, or Share → Add to Home Screen on iOS); the installed app shows the unread count on its icon. On iPhone and iPad, notifications work only from the installed app.
- •Per device. Each browser or installed app is its own device: a second one shows Enable on this device in settings, and Send a test notification checks it is wired up.
Archive, profiles, doc cards, presence, unread done right
- •Archive means closed, not gone. Every document header has an Archive button (also in the ⋯ menu and the file tree’s right-click menu); confirm inline, no modal. An archived doc stays at its URL, read-only, with a banner — "Archived by Emily · 2 days ago · Reopen" — and its comments still open for replies. The sidebar shows a dimmed Archived (n) group at the bottom of the project; search skips archived docs unless you say
is:archived. Editing an archived doc from the CLI or a connected folder reopens it and posts a system message in the project channel instead of dropping the write. CLI: files archive / files reopen (rm and restore still work). - •Click a name, see the person. Names and avatars in messages, the People list and a project’s Members row open a profile in the right panel: avatar, name, email, online status, workspace role, and a Message button that lands in the DM.
- •Doc links unfurl. Paste a doc URL or a
[[project/path]] chip in a channel, thread or DM and a card renders under the message with the title, project / folder, who last edited it and when, and Open. Archived or missing docs show a muted "archived" / "not found" card. - •Who has this doc open. Stacked avatars in the editor bar, one per person other than you, in their cursor color; hover for the name,
+n past five. Two tabs from one person count once. - •Unread works like Slack. A channel’s dot means unread top-level posts only; thread replies dot the Threads row and Unread instead, and opening the thread clears that thread. Opening the channel no longer clears replies you haven’t seen. Your own posts and replies never count. The
manual mark-read preference is honoured: nothing auto-clears, and a Mark read action appears in the channel and thread headers. - •Collapsed projects show their size. Sidebar rows read
homa-legal · 50 docs (0 docs too, _inbox included), refreshed within a moment of a create or archive.
The frame stays put
- •Clicking around no longer feels like page loads. The sidebar, header bar, right panel and ⌘K palette are rendered once and kept across navigation: moving between a channel and a document swaps only the page. The sidebar keeps its scroll and expanded rows, the live stream stays connected, and presence dots and unread counts no longer blink on every click.
- •The shell is fetched once per workspace. Your workspaces, the current one, its projects and members are loaded once and re-fetched only after a form post or when you move to another workspace. Opening another document inside the same project makes no server request at all.
- •Clicks answer at once. The row you clicked lights up while its page loads, and a hairline crawls along the top of the window if that takes longer than a beat. Hovering a sidebar row, a tree entry or a tab prefetches its page.
- •Channels and threads come back instantly. What a channel or thread showed last time is painted first; the fresh fetch replaces it in the background.
People, online
- •Who’s online. Everyone in the sidebar’s People list carries a presence dot: filled green while they have share-doc open, a hollow ring when they don’t. Online people sort first, you are marked "(you)", and the header counts them. Live, no refresh.
- •People is the whole workspace, on every page. Opening a project no longer swaps the list for that project’s members — it stays your team, Slack-style. Its invite button invites to the workspace.
- •A project’s members live inside the project. The open project’s tree ends with a Members row; expand it for that project’s members, pending invitations with resend, and Invite to project….
Links inside code spans
- •Fixed: a link whose text is code no longer loses its link. Writing `
[PLAN.md](./PLAN.md) used to come back as a plain PLAN.md with the link gone — and since the file on disk is rewritten from the live document, the loss reached your .md` file the first time anyone edited the doc. Re-sync an affected file to repair it; the mangling does not recur.
Messages, Slack layout
- •Message rows. Avatar gutter, name and time on one line; consecutive messages from the same author collapse into continuation rows; a sticky "Today" pill marks each day.
- •Hover actions. A floating bar on each message: Add reaction (picker with search) and Reply in thread.
+ and r from the keyboard. - •Reactions show only when someone reacted. Reply summary under a post shows who replied, the count, and the last reply time; it opens the thread on the right.
Chat and Docs tabs
- •Two views, one workspace. Everything right of the sidebar sits under Chat and Docs tabs in a new header bar (
⌘1 / ⌘2). Each tab remembers where you were, so switching round-trips to the same channel or document. - •Right panel. A post’s thread and a document’s comment threads open in a panel on the right (resizable, remembered,
⌘. closes it) instead of inline or beside the editor. - •Header bar with a breadcrumb and the ⌘K search box, which leaves the sidebar. The chat dock is gone: conversations always open on the Chat tab.
Dark mode
- •Dark mode. The app follows your operating system’s light/dark setting by default; pin it either way under Your settings → Appearance. The choice is saved on your account, so it follows you across devices. Light remains the default when the OS has no preference.
Search
- •Search everything. ⌘K now searches message bodies, threads, file contents, channel names and people — not just file paths. Full-text with highlighted snippets, typo-tolerant names, and only what you can open. A hit opens the thread in place; picking a person opens the DM.
- •Filters in the query:
in:#general, in:project, in:dm, from:me / from:[email protected] / from:agent, is:unread, has:file, before:2026-09-01, after:7d. Quotes for phrases, -word to exclude. A filter that names nothing you can see returns nothing (and says so). - •CLI:
sharedoc search "<query>" [--scope all|files|messages|threads|channels|people] with --in/--from/--unread/--has-file/--after/--before; --json returns grouped, ranked hits with a where and threadId.
Archived channels come back, prod test run
- •
sharedoc channels create <name> on a channel that sits in the archive restores it instead of handing back the archived one. - •Local dev: redirects through the hub’s combined server no longer hang.
- •The e2e suite (121 checks) runs against production as well as the local hub.
Channels, direct messages, Unread
- •Channels. Every workspace has
#general and one channel per project, from day one. Create more (public or private), post, react, and reply in threads that expand inline. A channel post is a thread, so everything that works on a doc comment works here. - •Direct messages and group messages: pick people from the sidebar’s +, or
sharedoc dm [email protected] --body "…" from a terminal. - •The chat dock. On any document, ⌘. (or the Chat button) opens a resizable panel beside the doc with the conversation you were in. Full-width channel pages live at
/w/<workspace>/c/<channel>. - •Unread. Mentions, DMs, replies in threads you follow, and new threads on docs you follow land in one page with filters, keyboard navigation, and a live badge in the sidebar. Tag people with
@, channels with #, files with [[. - •Notification preferences (
/settings/notifications): what you hear about, per-conversation overrides, and when you get email — mentions, DMs, and followed-thread replies are emailed once you have been away for ten minutes (configurable). - •CLI:
channels list/create/join/leave/archive, channel history/post, dm, unread (with --watch), unread read/ack, notify prefs, and thread create --channel.
Composer pills, steadier editor, dev fixes
- •`@` now finds files too: one autocomplete over people and files (
[[ still lists files only). Picked people and files show as pills in the composer before you post. - •Drafts no longer vanish: the editor rebuilt itself on every sidebar refresh (a re-issued hub token), dropping an in-progress thread and the selected thread. The token is now stable for its lifetime.
- •Forgot password on localhost shows the reset link on the page (and in the server log) outside production.
- •Local dev: the hub listens on :3273 now (was :3200); the hub passes Vite's hot-reload socket through to the web app in combined-server mode.
Files in S3, _inbox, folder view, uploads, merge
- •Every file now lives in cloud storage; the server's disk and your connected folders are caches. Existing files are migrated automatically.
- •`_inbox`: every workspace gets a shared inbox folder. Paste an image or drop a file into any thread, the editor, or the page and it lands there — and your Claude can read it with
sharedoc files list _inbox --since 1h. - •Folder view: click any folder for a thumbnail grid with a quick-preview pane, Upload, drag-and-drop, Copy
[[path]], Move to…, and Archive. - •Safe writes from the CLI:
sharedoc files put --base <version> 3-way merges into the live doc so an agent never clobbers someone typing; --strict refuses on conflicts. files mv/rm/restore/diff/url too. - •`sharedoc connect --once` syncs a folder and exits;
--reset re-seeds after backing up; --strict makes conflicts a non-zero exit. - •Previews use short-lived signed URLs; image thumbnails are generated on upload.
Threads everywhere
- •Comments are now threads. Every comment on a doc is a thread with replies, reactions, follow, resolve/reopen, and edit/delete — the same model that will power channels and DMs next. Existing comments were migrated automatically.
- •Tag anyone or anything in a message:
@Emily, [[homa-legal/contract-v3.md]] (optionally #L12-L20), or [[thread:…]]. Tags become links and show up as backlinks in the doc header. - •Autocomplete in the composer for
@ people and [[ files; Cmd/Ctrl+Enter sends. - •Agents in threads: messages posted through the CLI carry a "via Claude" chip.
- •CLI:
threads list, thread show/create/reply/resolve/reopen/follow/unfollow/edit/delete, react, files backlinks — see sharedoc help or /skill.md. - •Revision history now records who edited;
events tail includes your own account events.
Postgres is the source of truth, new CLI login, agent-ready CLI
- •Documents now live in Postgres. The live CRDT state, a revision history, and a manifest are stored in the database; the server's disk and your connected folders are caches that can be rebuilt. Existing docs migrate the first time they are opened.
- •An append-only change log records every create/save/upload/archive/comment/invite/member change and streams live.
- •New `sharedoc login`: opens the browser, you pick workspaces and scope, and the token lands in the CLI automatically (or paste a one-time code with
--no-browser). Tokens are listed and revocable in Settings, where you can also mint one for headless agents. Every new token emails you. - •The CLI is built for agents:
help --json, schema, whoami --json, workspaces/projects/members list, files list/cat/history, search, events tail --follow, a strict --json contract and exit codes. The server publishes a Claude skill at /skill.md and docs at /docs/cli. - •A welcome email on signup.
Workspaces, ⌘K search, settings
- •New workspace layer above projects: a workspace is the people (members, roles, settings); projects live inside it. Your existing projects were moved into a workspace of your own without changing who can see them.
- •Workspace picker top-left, and a workspace settings page: every member with role, who invited them, when they joined, last active — plus invite (with role and optional project), change role, remove, resend/revoke invites, and per-project visibility (workspace-wide or private).
- •⌘K / Ctrl+K search across every file in every workspace you belong to, plus projects, workspaces, and settings. Arrow keys + Enter to open.
- •A Your settings page: display name, password, the CLI tokens minted by
sharedoc login (revoke any), and your workspaces. - •The sidebar now fills the full height, is resizable by dragging its edge (double-click to reset), remembers its width, and lists the projects of the current workspace with the open project's files inline. ⌘\ collapses it.
- •share-doc now deploys from its own repo and Railway project; a push to
main ships automatically.
Archive on delete + Windows path fix
- •Deleting a file in a connected folder now archives it instead of leaving it stranded on the server — nothing gets silently stuck anymore.
- •New Archived section in the sidebar: see everything that was removed, when, and restore it with one click.
- •Archived files stay previewable (read-only) from the web.
- •Fixed connecting Windows folders whose path contains spaces (e.g.
C:\Users\you\Corporate - Documents\Vault).
File browser + universal previews
- •The sidebar is now a full Explorer-style file tree showing every file — not just markdown — with folders and per-type icons.
- •Preview any file from the web: images, SVG, PDF, video, audio, and code/text, with a download fallback.
- •The sync agent now uploads all files in a connected folder, not only
.md.
Windows + Linux CLI
- •One-line install on Windows (PowerShell) and Linux, matching macOS — the same
sharedoc command everywhere. - •Nested files now sync consistently across Windows and Mac/Linux.
CLI login, installer & editor polish
- •Browser-based
sharedoc login (device authorization), a one-line installer, and a quick-start page. - •Slugged document URLs and a page menu — collapse all, copy contents, copy link, print — plus a right-click section menu.
- •Comments hidden by default, @-mentions in comments, adding a comment without selecting text, and resend-invite.
- •Polished, branded invite emails.
- •Moved to the sharedoc.brightmotion.io domain.
First release
- •Real-time collaborative markdown editing (live cursors, Yjs + Tiptap) on plain
.md files. - •Projects, members, and email invites; email/password accounts.
- •The
sharedoc connect agent two-way-syncs a local folder with a project. - •Inline comments and replies.