Skip to content

v0.2.0

Latest

Choose a tag to compare

@github-actions github-actions released this 16 Sep 16:29
· 294 commits to main since this release
c2068c2

Stoop 0.2.0 is still a beta: the API and schema may change between minor
versions. It upgrades in place from 0.1.0 and can be rolled back to 0.1.0
by putting the previous image tag back.

What's new. Message search. Pinned messages. Group DMs, and closing a
conversation to take it off your own list. Integrations: incoming
webhooks that post into a channel, outgoing webhooks signed with a
per-hook secret, bots, and personal and bot access tokens for the API.
People can delete their own accounts. Do not disturb is stored on the
account, and presence has a shape for each state. A live indicator shows
when your microphone, camera or screen is being captured, and a device
plugged in mid-call is offered without reconnecting. Seventeen new
themes with a filtered picker. GET /version reports the running build.
A long list of fixes to Markdown, emoji shortcodes, link previews and
realtime presence is in the list below.

For operators.

  • Every variable in .env now reaches the server. The compose file
    gained env_file: .env, so any setting in
    docs/self-hosting.md → Configuration reference
    can be set there. Fetch this release's docker-compose.yml rather than
    editing the tag in your old one, or add that line yourself.
  • Webhooks are on by default. STOOP_WEBHOOKS=false turns them off
    without deleting anything. Outgoing webhooks refuse LAN targets until
    an admin ticks Allow private targets under Server admin →
    Integrations; cloud metadata and link-local addresses are never
    reachable. New tunables: STOOP_WEBHOOK_RATE_LIMIT (60),
    STOOP_WEBHOOK_DELIVERY_RETENTION (168h), STOOP_SEARCH_RATE_LIMIT (30).
  • People can delete their own accounts by default. Untick People can
    delete their own accounts
    under Server admin → Accounts to leave that
    to admins.
  • Backups: docs/self-hosting.md → Backups
    now has a restore runbook, written from a drill.

Schema. Migrations 00029 to 00037 run at startup. All of them only
add; none is a contract migration, so the schema floor does not move and
0.1.0 still starts against a 0.2.0 database.

Pinned alongside this release: LiveKit v1.13.6 and Postgres 16, both
unchanged from 0.1.0.

Known issues: none known at release. What turns up goes in
GitHub issues; security
problems go through
private reporting.

The list below is every change merged since 0.1.0.

Changelog

Changes

  • 1eadbce: Merge pull request #20 from getstoop/release-env-asset-name (@Jhut89)
  • 87cced1: self hosting doc updates (@Jhut89)
  • 09308d6: Merge pull request #21 from getstoop/sh_doc_updates (@Jhut89)
  • 3a69cf0: Docs: message search proposal (STOOP-176) (@Jhut89)
  • a1f887c: Message search: schema, query and SearchMessages RPC (STOOP-177) (@Jhut89)
  • 789cc35: Search: no empty tsquery branch (@Jhut89)
  • 3ba1822: Message search: header entry and results page (STOOP-178) (@Jhut89)
  • 181e178: Search: rows fade in under the scope chips (@Jhut89)
  • a858827: Merge pull request #22 from getstoop/docs/message-search (@Jhut89)
  • 1ecc578: Merge pull request #23 from getstoop/search-server (@Jhut89)
  • 3d7c2b6: Merge pull request #24 from getstoop/search-web (@Jhut89)
  • c02f64c: Search: review follow-ups from #23 (@Jhut89)
  • ef946a8: Merge pull request #25 from getstoop/search-review-fixes (@Jhut89)
  • a9a5bf1: E2E: message search spec (STOOP-178) (@Jhut89)
  • 7f7ff6d: Merge pull request #26 from getstoop/search-e2e (@Jhut89)
  • 6fe1267: Desktop client proposal (STOOP-180) (@Jhut89)
  • 341598f: Desktop proposal: note the design page (@Jhut89)
  • 6e503f2: Web: one origin helper for every server URL (STOOP-181) (@Jhut89)
  • 5d09cc4: Server: GET /version for clients that check before login (STOOP-185) (@Jhut89)
  • d769313: Web: platform seam and the desktop badge (STOOP-182, STOOP-183) (@Jhut89)
  • a0a2dfe: Web: PWA manifest and icons (STOOP-184) (@Jhut89)
  • f1ce57b: Web: the stoop mark as drawn (STOOP-184) (@Jhut89)
  • 4d35d12: Web: file links stay paths (@Jhut89)
  • 80f89b1: Docs: the desktop contract (STOOP-186) (@Jhut89)
  • 26c198b: Version test: assert Cache-Control (@Jhut89)
  • 39ee832: Manifest: splash and chrome follow the Brownstone canvas (@Jhut89)
  • 230afa3: Merge pull request #27 from getstoop/desktop-client-proposal (@Jhut89)
  • 37aa1cf: Merge pull request #32 from getstoop/stoop-186-desktop-doc (@Jhut89)
  • 4d63395: Merge pull request #30 from getstoop/stoop-182-platform-seam (@Jhut89)
  • bb3e610: Merge pull request #28 from getstoop/stoop-181-origin-helper (@Jhut89)
  • 3f72f66: Merge pull request #29 from getstoop/stoop-185-version-endpoint (@Jhut89)
  • e9462e5: Merge pull request #31 from getstoop/stoop-184-pwa-manifest (@Jhut89)
  • d26c8d2: Web: the title strip and theme-color follow the picked theme (STOOP-202) (@Jhut89)
  • 3a5d134: Merge pull request #33 from getstoop/web-titlebar-theme (@Jhut89)
  • 95d418a: Docs: the theme tokens the desktop shell reads are part of the contract (@Jhut89)
  • fe73c9d: Web: thin scrollbars in the theme's colours (STOOP-209) (@Jhut89)
  • ec55333: Merge pull request #34 from getstoop/docs/shell-theme-tokens (@Jhut89)
  • d73d593: Merge pull request #35 from getstoop/feat/theme-scrollbars (@Jhut89)
  • 07f1e41: Docs: propose a server switcher the shell draws itself (STOOP-210) (@Jhut89)
  • f682966: Docs: the theme belongs to the viewer, not the server (@Jhut89)
  • 9204399: Docs: finish the correction through the rest of the switcher proposal (@Jhut89)
  • 28bf941: Docs: the switcher's decisions, taken (@Jhut89)
  • 3ef9973: Merge pull request #36 from getstoop/docs/desktop-server-switcher (@Jhut89)
  • 1511049: Dev: one live origin at :8091, and make dev says what it runs (@Jhut89)
  • 15bc5c9: Merge pull request #37 from getstoop/dev/uniform-start (@Jhut89)
  • 1c9fda8: Desktop: bridge 2 hands the shell's theme to the page, whole (@Jhut89)
  • 45f16d5: Merge pull request #38 from getstoop/desktop-theme (@Jhut89)
  • 0215601: Desktop: provider sign-in leaves for the system browser and comes back (@Jhut89)
  • d20a683: Desktop: a failed provider sign-in comes back to the app too (@Jhut89)
  • be7a87d: Desktop: the return page is a client route, not HTML from Go (@Jhut89)
  • 79bb2fd: Desktop: the return page offers a way on, not just a way back (@Jhut89)
  • fcfe47c: Merge pull request #39 from getstoop/desktop/provider-signin (@Jhut89)
  • f115ef9: Desktop: connecting a provider leaves for the system browser too (@Jhut89)
  • befad0b: Desktop: one start per attempt, and a person confirms a link (@Jhut89)
  • 9187459: Merge pull request #40 from getstoop/desktop/link-provider (@Jhut89)
  • 960f28c: Web: an invite link can open the app instead of the browser (@Jhut89)
  • 4687e17: Web: the invite landing reaches for the app on its own (@Jhut89)
  • 09e271e: Web: the invite landing is a handoff, not a login form (@Jhut89)
  • 31fd326: Web: the invite handoff remembers nothing (@Jhut89)
  • 186cbab: Web: the invite landing keeps its form where there is no handoff (@Jhut89)
  • d9df4c3: E2E: arrive at an invite through the handoff (@Jhut89)
  • 04ffb98: Web: an invite link asks before anything touches the invite (@Jhut89)
  • b5fed7a: Desktop: the app lands where the server says, as the browser does (@Jhut89)
  • bde162a: Merge pull request #41 from getstoop/desktop/invite-open-in-app (@Jhut89)
  • ad177c6: Merge pull request #42 from getstoop/desktop/setup-landing (@Jhut89)
  • 24b3dbf: Web: every shared link asks, not just invites (@Jhut89)
  • ffc2798: Deploy: settings in .env reach the server (@Jhut89)
  • cac321d: Merge pull request #44 from getstoop/deploy/env-file-passthrough (@Jhut89)
  • 3c14a0d: Merge branch 'main' of https://github.com/getstoop/stoop into desktop/shared-links-open-in-app (@Jhut89)
  • 201255e: E2E: take the way past the gate on any shared link (@Jhut89)
  • 49f605a: Merge pull request #43 from getstoop/desktop/shared-links-open-in-app (@Jhut89)
  • 481847f: Voice: a shared screen's audio is captured for what it is (@Jhut89)
  • 28b9fa3: Merge pull request #45 from getstoop/voice/screen-share-audio-constraints (@Jhut89)
  • d911e67: E2E: assertions wait for the condition, not the clock (@Jhut89)
  • 718c880: E2E: keep the settling sleeps, poll only the assertions (@Jhut89)
  • 0d7cab9: Merge pull request #47 from getstoop/e2e/poll-instead-of-sleep (@Jhut89)
  • 070dce6: Web: unit tests, and five bugs they found on the way in (@Jhut89)
  • 45dbb5c: Merge pull request #48 from getstoop/test/web-unit-vitest (@Jhut89)
  • 31127cd: E2E: one harness, not 38 copies of it (@Jhut89)
  • 7a1e4f2: Merge pull request #49 from getstoop/e2e/one-harness (@Jhut89)
  • f5bc145: E2E: drop the sleeps that polling made redundant (@Jhut89)
  • 5e8dd8f: Merge pull request #50 from getstoop/e2e/drop-redundant-sleeps (@Jhut89)
  • 99c2174: E2E: seed the instance over RPC instead of driving the signup wizard (@Jhut89)
  • 747234d: E2E: seed the bootstrap across the suite (@Jhut89)
  • e3f799f: Merge pull request #51 from getstoop/e2e/seed-the-bootstrap (@Jhut89)
  • f016479: E2E: the Playwright runner, and the first four specs (@Jhut89)
  • b9869a1: E2E: the dms flake is focus, not a timeout (@Jhut89)
  • 24f1601: Merge pull request #52 from getstoop/e2e/playwright-first-batch (@Jhut89)
  • 0ab2c04: E2E: port 27 more specs to Playwright (@Jhut89)
  • 0a9f9e9: E2E: the seeding suite needs the auth rate limit off (@Jhut89)
  • 3738ae1: Docs: the rate-limit env gap is about any suite server, not just a hand-started one (@Jhut89)
  • 029926c: Merge pull request #53 from getstoop/e2e/playwright-bulk (@Jhut89)
  • 30fa510: E2E: port presence, composer-styling, window, mobile and mutes to Playwright (@Jhut89)
  • 5b6d477: Merge pull request #54 from getstoop/e2e/playwright-batch3 (@Jhut89)
  • acf7b7b: CI: run the browser suite in one job instead of four shards (@Jhut89)
  • fee906b: E2E: the mutes rail locator clicks Join while the spaces load (@Jhut89)
  • 77d26b2: E2E: unreads needs the front page to mark anything read (@Jhut89)
  • 031b6af: E2E: the space-menu label has to be polled, not read once (@Jhut89)
  • d4f6518: Merge pull request #55 from getstoop/ci/collapse-e2e-shards (@Jhut89)
  • 51669c6: CI: run the voice E2E spec, and fix the two assertions that had rotted (@Jhut89)
  • 2fdf479: CI: LiveKit wants its key file private, and a failure that says so (@Jhut89)
  • 630c2d6: CI: give the voice workflow an explicit permissions block (@Jhut89)
  • a2c610a: Merge pull request #56 from getstoop/ci/voice-e2e (@Jhut89)
  • 10df0c0: E2E: port attachments to Playwright (@Jhut89)
  • f1601ec: E2E: wait for focus rather than asking for it, and stop racing a re-render (@Jhut89)
  • 0441ebc: Merge pull request #57 from getstoop/e2e/port-attachments (@Jhut89)
  • febbb3c: Web: unit tests for thirteen pure modules, and two bugs they found (@Jhut89)
  • ed54b59: Merge pull request #58 from getstoop/test/unit-pure-modules (@Jhut89)
  • 9e5ac7c: Web: typecheck and lint the browser specs, which nothing was checking (@Jhut89)
  • 763ce60: Merge pull request #59 from getstoop/test/typecheck-e2e-specs (@Jhut89)
  • 915e9da: Web: unit tests for the last four pure modules, and a voice-channel landing (@Jhut89)
  • 72cf4c4: Merge pull request #60 from getstoop/test/unit-formatting-mutes (@Jhut89)
  • 3721804: E2E: port voice to Playwright and delete the puppeteer suite (@Jhut89)
  • af8b238: Merge pull request #61 from getstoop/e2e/port-voice-drop-puppeteer (@Jhut89)
  • 3666b8d: Docs: a design proposal for pinned messages (STOOP-219) (@Jhut89)
  • e8746c8: Merge pull request #62 from getstoop/docs/pinned-messages-proposal (@Jhut89)
  • 98a53df: Pinned messages (STOOP-219) (@Jhut89)
  • 00f9e83: E2E: the owner's message toolbar now offers Pin (@Jhut89)
  • e45670a: E2E: a browser spec for pinned messages (@Jhut89)
  • 83ba503: Merge pull request #63 from getstoop/feat/pinned-messages (@Jhut89)
  • b516919: Docs: a design proposal for group DMs (STOOP-220) (@Jhut89)
  • cdb0b85: Docs: DirectMessage needs one field after all (@Jhut89)
  • 4dc82a2: Group DMs (STOOP-220) (@Jhut89)
  • dfe6c3a: E2E: the DM list only exists on /dm (@Jhut89)
  • 3e52507: A 1:1's members can't be changed at all (@Jhut89)
  • 9a0fae7: A conversation is its people (@Jhut89)
  • 9ea9fb0: Web: the new-conversation button sits beside the heading (@Jhut89)
  • 667c71d: Blocking clears the alerts it is meant to silence (@Jhut89)
  • b2b81b2: Web: the DM pill counts what the rows count (@Jhut89)
  • 982b1bc: E2E: the DM pill assertion was the old behaviour (@Jhut89)
  • d277489: Merge pull request #65 from getstoop/feat/group-dms (@Jhut89)
  • 77d7463: Two small corrections found while testing group DMs (@Jhut89)
  • aee4f65: Merge pull request #66 from getstoop/fix/block-wording-and-pins-race (@Jhut89)
  • 6ff28cb: Web: a status can belong to whatever is hosting the page (@Jhut89)
  • d573d32: Web: Muted is a section of its own (@Jhut89)
  • 9b8a0f7: Merge pull request #67 from getstoop/feat/muted-section-and-shell-status (@Jhut89)
  • a881228: Access model: action vocabulary, procedure registry and credential gate (@Jhut89)
  • 2927548: Merge pull request #68 from getstoop/feat/access-vocabulary (@Jhut89)
  • 18110f3: Merge pull request #46 from getstoop/dependabot/github_actions/actions-dfc3086b10 (@Jhut89)
  • 109b803: Access model: the credentials table, bounds and users.kind (@Jhut89)
  • d6cb72e: Merge pull request #69 from getstoop/feat/access-credentials (@Jhut89)
  • 36519fd: Access model: permissions on the wire, not in the client (@Jhut89)
  • f3fe739: Merge pull request #70 from getstoop/feat/access-permissions-wire (@Jhut89)
  • 6352def: Access model: personal access tokens (@Jhut89)
  • 2309898: Merge pull request #71 from getstoop/feat/access-personal-tokens (@Jhut89)
  • 8211a72: Access model: bearer credentials on /ws and /files, filtered per credential (@Jhut89)
  • 2b5c922: Merge pull request #72 from getstoop/feat/access-ws-files (@Jhut89)
  • 41c3bb3: Access model: close five gaps found reviewing the epic (@Jhut89)
  • dcd0ec0: Merge pull request #73 from getstoop/fix/access-review (@Jhut89)
  • df364fc: Webhooks: commit the proposal (STOOP-257) (@Jhut89)
  • 28fdaf1: Merge pull request #74 from getstoop/docs/webhooks-proposal (@Jhut89)
  • 9b15037: Webhooks: fold in the four settled decisions (@Jhut89)
  • 0784f35: Integrations: the module scaffold, migration 00033, protos, policy (STOOP-258) (@Jhut89)
  • 2853680: Merge pull request #75 from getstoop/docs/webhooks-decisions (@Jhut89)
  • 0d7a80f: Merge pull request #76 from getstoop/feat/integrations-module (@Jhut89)
  • 1ffd61b: Integrations: incoming webhooks, vendor adapters, bots (STOOP-259) (@Jhut89)
  • 8cc9c8d: Integrations: sweep orphaned hook credentials; refuse work on a dead bot (@Jhut89)
  • 9e9f4a7: Merge pull request #77 from getstoop/feat/integrations-incoming (@Jhut89)
  • de99b08: Integrations: bot API tokens (STOOP-266) (@Jhut89)
  • 47eb037: Integrations: outgoing webhooks and the egress guard (STOOP-260, STOOP-261) (@Jhut89)
  • be392c5: Merge pull request #78 from getstoop/feat/integrations-bot-tokens (@Jhut89)
  • 0b3f452: Instance: the three webhook switches on status and settings (STOOP-262) (@Jhut89)
  • 959b477: Integrations: the outgoing switch stops deliveries, not only creation (@Jhut89)
  • 7d93779: Web: the Integrations sections (STOOP-263) (@Jhut89)
  • 862085c: Web: the checkbox hint in the new-hook modal gets its own line (@Jhut89)
  • 03e1043: Merge pull request #79 from getstoop/feat/integrations-settings (@Jhut89)
  • 67ca34c: Merge pull request #80 from getstoop/feat/integrations-web (@Jhut89)
  • 63885f6: Docs: integrations.md, the operator's webhook recipes, registrations (STOOP-264) (@Jhut89)
  • c850c92: Merge pull request #81 from getstoop/feat/integrations-docs (@Jhut89)
  • 47bf875: Bots on the wire: IdentityKind, and what a bot is refused (STOOP-286) (@Jhut89)
  • 10e213d: Merge pull request #83 from getstoop/feat/bots-on-the-wire (@Jhut89)
  • 1555470: Bots marked everywhere a name renders (STOOP-286, 2/3) (@Jhut89)
  • ba9f25f: Merge pull request #84 from getstoop/feat/bots-marked (@Jhut89)
  • 1844b05: A bot's avatar and bio, set by an instance admin (STOOP-286, 3/3) (@Jhut89)
  • e06f04c: New bot takes an avatar and a bio too (@Jhut89)
  • 1eb4b13: The bot face is a bot's default avatar (@Jhut89)
  • 2336906: The bio field has no placeholder (@Jhut89)
  • 5250515: Merge pull request #85 from getstoop/feat/bot-avatar-bio (@Jhut89)
  • 8c2f085: Bot membership lives on the bot (STOOP-287, 1/3) (@Jhut89)
  • 00a19f0: Merge pull request #86 from getstoop/feat/bot-membership (@Jhut89)
  • 9d7ed25: Bot spaces in the bot dialogs; bot tokens lose the space limit (STOOP-287, 2/3) (@Jhut89)
  • c478dc8: The space picker is indented only under its radio (@Jhut89)
  • 2551dbe: A bot can't widen its own membership (@Jhut89)
  • a657568: Merge pull request #87 from getstoop/feat/bot-spaces-ui (@Jhut89)
  • cc017c3: Merge pull request #88 from getstoop/fix/bot-self-widening (@Jhut89)
  • 814ae04: Personal tokens lose the space limit (STOOP-287, 3/3) (@Jhut89)
  • fc1abf6: Merge pull request #89 from getstoop/feat/tokens-no-space-limit (@Jhut89)
  • 8650233: A removed bot's hooks read and are stored as off (STOOP-289) (@Jhut89)
  • 92addcf: The bot token picker speaks for a bot (STOOP-288) (@Jhut89)
  • a31d22f: Merge pull request #91 from getstoop/feat/bot-token-picker (@Jhut89)
  • a18f839: Merge pull request #90 from getstoop/fix/removed-bot-hooks (@Jhut89)
  • 5067636: A bot never holds the instance admin role (@Jhut89)
  • 21e1ab4: No demote step: nothing to upgrade (@Jhut89)
  • 0df188a: An activity item needs the grant its preview needs (STOOP-280) (@Jhut89)
  • aafd310: Tokens: no bounds, read activity needs a read, leaving needs the app (STOOP-279) (@Jhut89)
  • f824437: Activity needs both reads, as one check (@Jhut89)
  • 4a48ddc: Read activity needs both reads (@Jhut89)
  • 02785bf: Merge pull request #92 from getstoop/feat/no-admin-bots (@Jhut89)
  • 6d49099: Merge pull request #93 from getstoop/fix/activity-previews (@Jhut89)
  • 1b0b85c: Merge pull request #94 from getstoop/feat/token-cleanup (@Jhut89)
  • 4ba1892: The last-admin guard is one step (STOOP-283) (@Jhut89)
  • d681f7d: End-to-end tests over HTTP: the harness, bots and tokens (STOOP-265) (@Jhut89)
  • 7845926: Merge pull request #96 from getstoop/test/api-harness (@Jhut89)
  • 621b796: End-to-end tests over HTTP: webhooks in (STOOP-265, 2/3) (@Jhut89)
  • 7c50b5e: Name the adapter cases by their body shape (@Jhut89)
  • 21bd378: No competitor names in code, copy or architecture docs (@Jhut89)
  • 823403f: Merge pull request #95 from getstoop/fix/last-admin-lock (@Jhut89)
  • 6b02952: End-to-end tests over HTTP: webhooks out (STOOP-265, 3/3) (@Jhut89)
  • 42cdc20: Merge pull request #97 from getstoop/test/api-webhooks-in (@Jhut89)
  • dfdb29e: Merge pull request #98 from getstoop/chore/no-competitor-names (@Jhut89)
  • 144ddf1: Merge pull request #99 from getstoop/test/api-webhooks-out (@Jhut89)
  • 22152c5: Themes: fifteen new palettes and a filtered picker (@Jhut89)
  • 32f83c9: Merge pull request #100 from getstoop/feat/theme-picker-filters (@Jhut89)
  • ffe8de4: Themes: Scaffolding and Sidewalk Chalk, two more dims (@Jhut89)
  • e4da974: Merge pull request #101 from getstoop/feat/themes-two-more-dims (@Jhut89)
  • c5d47df: Desktop: round the sidebar's corner into the rail and strip (@Jhut89)
  • db1764f: Merge pull request #102 from getstoop/feat/shell-sidebar-corner (@Jhut89)
  • f62ff7c: Docs: a design proposal for the live capture indicator (STOOP-254) (@Jhut89)
  • a29bef9: Docs: the desktop app draws the voice popover; the indicator moves once (@Jhut89)
  • 66b276a: Web: say when the mic, camera or screen is live, on every page (STOOP-254) (@Jhut89)
  • 1c2645f: Web: the live indicator moves once per call, and the camera can come back on (@Jhut89)
  • 5b428de: Web: the live popover escapes the rail, and the pills animate out (@Jhut89)
  • c9cc109: Web: animate the live indicator on the compositor, so a busy join can't stall it (@Jhut89)
  • 513d25d: Web: reduced motion really stops the live indicator's animations (@Jhut89)
  • f865a4d: Web: moving between voice channels doesn't replay the live indicator; a smoother exit (@Jhut89)
  • 5a553f5: Web: report voice to the desktop shell, and take its actions (STOOP-254) (@Jhut89)
  • df7894f: Web: the shell draws the voice popover; the page only takes actions (@Jhut89)
  • 4a2fcdf: Web: moving channels doesn't make the desktop strip exit and arrive again (@Jhut89)
  • bc2d4b7: Merge pull request #103 from getstoop/docs/live-indicator-proposal (@Jhut89)
  • 98b2b8b: Merge pull request #104 from getstoop/feat/live-indicator (@Jhut89)
  • 45f9ff4: Merge pull request #105 from getstoop/feat/live-indicator-bridge (@Jhut89)
  • 2e46482: Web: a leave voice action, so the desktop app keeps one call at a time (STOOP-255) (@Jhut89)
  • 57ff53c: Merge pull request #106 from getstoop/feat/voice-leave-action (@Jhut89)
  • 82818f3: Docs: presence is online or offline; do not disturb is the one choice (@Jhut89)
  • 2a0de1c: Docs: every device follows do not disturb, and connecting never clears it (@Jhut89)
  • 46223d4: Docs: silencing one device is a separate, later idea (@Jhut89)
  • 323ee8e: Do not disturb is stored on the account (STOOP-291, slice 1) (@Jhut89)
  • 0df1da0: Presence is online or offline; do not disturb comes from the account (STOOP-291, slice 2) (@Jhut89)
  • bc011d7: Web: a do not disturb change doesn't restart the realtime connection (@Jhut89)
  • 25197a6: Web: the desktop app's do not disturb switch sets this server (STOOP-291, slice 3) (@Jhut89)
  • b439e40: Web: do not disturb is a menu with an end (STOOP-291, slice 3) (@Jhut89)
  • be2e030: Merge pull request #107 from getstoop/docs/presence-and-dnd (@Jhut89)
  • 178145a: Merge pull request #108 from getstoop/feat/dnd-storage (@Jhut89)
  • e053645: E2E: the account page and do not disturb specs follow the new section (@Jhut89)
  • 6d9431d: Merge branch 'feat/presence-dnd' into feat/dnd-bridge (@Jhut89)
  • 5ffc413: Merge pull request #109 from getstoop/feat/presence-dnd (@Jhut89)
  • 58a1be9: Merge pull request #110 from getstoop/feat/dnd-bridge (@Jhut89)
  • b9d1f12: Point agents at the PR template and ban private links in PR bodies (@Jhut89)
  • 2b01c61: Merge pull request #111 from getstoop/docs/pr-template-fixes (@Jhut89)
  • 4e28ab0: Realtime: joining a space while connected sends its presence and voice (STOOP-237) (@Jhut89)
  • 6ae43ac: E2E: the app refetches what its socket could not hear, and the suite waits for it (@Jhut89)
  • 80dd6fe: Merge pull request #112 from getstoop/fix/presence-on-join (@Jhut89)
  • 1f67f7f: E2E: live() accepts the login page and the gate, and an upload is a 201 (@Jhut89)
  • c9a518b: Markdown: a trailing space no longer breaks bold, and a URL keeps its closing paren (STOOP-230) (@Jhut89)
  • 2bdd434: Web: 🌮 is a taco, ❌ converts, and 10💯45 stays a time (STOOP-229) (@Jhut89)
  • a26bd6e: Merge pull request #113 from getstoop/e2e/harden-suite (@Jhut89)
  • 1088437: Merge pull request #115 from getstoop/fix/emoji-shortcodes (@Jhut89)
  • 4947cb9: Merge remote-tracking branch 'origin/main' into fix/markdown-bold-and-parens (@Jhut89)
  • c0ba5a5: Merge pull request #114 from getstoop/fix/markdown-bold-and-parens (@Jhut89)
  • fc30e2e: E2E: one case per wiring in mutes, formatting and shortcodes (STOOP-235) (@Jhut89)
  • 0859826: Link previews: a direct image gets the image cap, and an animated GIF stays animated (@Jhut89)
  • 9b7c852: Realtime: a first load in flight is fetched again once it lands, not on top of it (@Jhut89)
  • 449a8c4: Docs: why the Ready refetch waits for a load in flight (@Jhut89)
  • d8cd12e: Merge pull request #116 from getstoop/e2e/thin-matrix (@Jhut89)
  • 8f682a0: Merge pull request #117 from getstoop/feat/animated-link-previews (@Jhut89)
  • 0523edd: Merge pull request #118 from getstoop/fix/first-load-refetch (@Jhut89)
  • fccfdca: Presence: offline goes to every space the person was seen in (STOOP-282) (@Jhut89)
  • 5b49116: Merge pull request #119 from getstoop/fix/offline-union (@Jhut89)
  • 260d898: Self-hosting: the backup and restore runbook, from a drill (STOOP-86) (@Jhut89)
  • 5f72020: Merge pull request #120 from getstoop/docs/restore-runbook (@Jhut89)
  • 1811859: README: the browser suite is Playwright, and voice runs with it (STOOP-246) (@Jhut89)
  • 32621e9: Docs: stop promising an object-storage backend (STOOP-221) (@Jhut89)
  • 532131a: Previews come from the client's parser, ported to Go (STOOP-231) (@Jhut89)
  • c7b6316: Drop a tracked editor swap file (@Jhut89)
  • e765f2c: Merge pull request #121 from getstoop/docs/readme-e2e (@Jhut89)
  • c75fab3: Merge pull request #122 from getstoop/docs/s3-not-promised (@Jhut89)
  • e45e8ed: Merge pull request #123 from getstoop/fix/server-plaintext (@Jhut89)
  • c475921: Merge pull request #124 from getstoop/chore/drop-swap-file (@Jhut89)
  • d422d70: Voice: a device plugged in mid-call is offered without reconnecting (STOOP-295) (@Jhut89)
  • 6788abc: Presence: a shape for each state, and a name (STOOP-278) (@Jhut89)
  • 3174573: Accounts: a person can delete their own, server side (STOOP-222, 1/2) (@Jhut89)
  • e80e449: Accounts: delete your own, on the page (STOOP-222, 2/2) (@Jhut89)
  • 2e07bd8: A deleted account signs in like a wrong password, and the login path says so (@Jhut89)
  • dccec94: Merge branch 'feat/delete-account' into feat/delete-account-web (@Jhut89)
  • 64043b7: A removed member's messages are fetched again, so a deleted author reads as one live (@Jhut89)
  • 52f1499: E2E: the pins spec waits for its first message before sending the second (@Jhut89)
  • e9e683e: The departure is announced once the account reads as deleted (@Jhut89)
  • 900756c: Merge branch 'feat/delete-account' into feat/delete-account-web (@Jhut89)
  • da8b469: The delete-account card's cancel is a chip, and its two answers sit apart (@Jhut89)
  • af8dca3: The delete-account form says in red that it cannot be undone (@Jhut89)
  • 87a0884: The delete-account card's last sentence is the red one (@Jhut89)
  • d3d9eb4: Merge pull request #125 from getstoop/feat/device-hotplug (@Jhut89)
  • 6b529b1: Merge pull request #126 from getstoop/feat/presence-shapes (@Jhut89)
  • d765869: Merge pull request #129 from getstoop/e2e/pins-order (@Jhut89)
  • 730ded7: Merge pull request #127 from getstoop/feat/delete-account (@Jhut89)
  • 2f67a2b: Merge pull request #128 from getstoop/feat/delete-account-web (@Jhut89)
  • 44e6f98: Conversations: close one to take it off your own list (STOOP-249) (@Jhut89)
  • 26f63e1: Merge pull request #130 from getstoop/feat/close-dm (@Jhut89)
  • c2068c2: Merge pull request #131 from getstoop/chore/release-0.2.0 (@Jhut89)