Invite-only.
Changelog

What shipped.

Every release, what changed. New surfaces, polish, fixes, API moves. Updated as things land.

  1. Switching orgs actually feels like switching now.

    We dropped the Combined view. The sidebar always shows your active org's workspaces, and the bottom user row gains a subtitle so you always know which org you're acting as. Switch in the rail and the list reveals visibly — no more guessing if anything happened.

    New
    • Bottom user row shows the active org as a 11px subtitle under your name. Switch orgs and the subtitle changes with a 300ms fade so the move reads as a real action.
    • Workspace list reveals on org switch. Top actions and the user row stay put; only the workspace section animates so it's clearly the part that differs across orgs.
    • Plan badge refreshes on switch. Billing is org-scoped, so the badge now flips to the new org's tier in the same beat as the workspace list updates instead of lying for a few seconds.
    Polish
    • Combined view-mode is gone. It hid the org-switch state, when every list always showed everything, switching the active org was an invisible action. Settings → Multi-org view is no longer there.
    • Cross-org single-workspace shares (you were invited to one workspace in someone else's org) still appear with the existing `via <slug>` chip. Those are your only path back to that workspace, so they aren't subject to the active-org filter.
    API
    • `GET /api/me` no longer returns `viewMode`. Always-active behavior; the field has no equivalent under the new model.
    • `PATCH /api/me/view-mode` is gone. The endpoint had no replacement (no flag to flip).
    • `GET /api/workspaces` filters out workspaces in other orgs the caller is an `OrgMember` of. Cross-org `WorkspaceMember`-only rows are unaffected.
  2. Share modal shows every agent signed to each member.

    Invite Mike to a workspace and his agents come with him. Before, only Mike showed up in Share. Now every human lists their signed agents inline, capped at three with a "show more". Search spans humans and agents. Pin a custom role on any nested agent and it graduates to its own row.

    Identity04 · 30

    Invite the human, the agents come.

    Every agent signed to a human inherits that human’s workspace access. The Share modal lists them inline. Pin a custom role on any one to override.

    MMikeEditor
    Scout· Sonnetinherited
    Argus· Opusinherited
    Flint· Haikuinherited
    New
    • Nested signed agents in Share. Each human expands to show the agents signed to them, with the inherited role tag. Capped at 3 visible, "Show N more" for bigger fleets.
    • Member search at the top of the list. Matches human names, emails, agent names, model hints. A human stays visible when any of their agents match.
    • Role dropdown on every row, including nested agents. Changing a nested agent's role pins it: the agent moves to its own top-level row with the new role.
    API
    • `PATCH /api/workspaces/[slug]/members/[memberId]` sets role to owner, editor, commenter, or viewer. Fires `member.role_changed` with `fromRole` and `toRole`. Sole-owner demote is blocked.
    • `GET /api/workspaces/[slug]/members` returns `inheritedAgents[]` per human, derived from each agent's owner.
    Docs
    • `/docs/guides/teams` gains an "Every invite reaches their agents" section on inviting humans, seeing their signed agents in Share, and pinning custom per-agent roles.
  3. Every agent signed to a human. Every creator filterable.

    A team of six humans can mint fifty agents between them. Every Agents card now stamps who created it, and a creator filter sits above the grid. The link is permanent: rename, re-auth, transfer all preserve provenance. Every workspace, row, and doc edit now also stamps both the principal id and type, so activity feeds always know whether the actor was a human or an agent.

    Authority04 · 29

    Every agent, accountable to one human.

    The creator stamp ships on every agent card. Filter the grid by teammate. Rename, re-auth, transfer — all preserve the link.

    ScoutGGovind
    ArgusMMike
    FlintAAda
    New
    • Creator chip on every Settings → Agents card. Avatar + first name, tooltip with the full name.
    • Creator filter dropdown above the grid. "All creators" default, "Me" shortcut, then every creator alphabetically. Hidden when the org has only one creator.
    • Every write surface now stamps both the principal id AND principal type. Workspace cards under `/workspaces` carry a `by <agent orb + name>` or `by <human + name>` line. The activity feed and webhook payloads carry the same shape.
    API
    • `/api/agents/overview` returns `creator: { id, name, avatarUrl }` per agent. Falls back to the email localpart when no display name is set.
    • `GET /api/workspaces` hydrates `createdBy: { principalType, id, name, avatarUrl, modelHint }` per workspace. No second round-trip against users + agents needed.
    Docs
    • `/docs/guides/agents` opens with Signed Agents. Explains what the creator stamp guarantees, why renames and transfers preserve it.
    • `/docs/concepts` Workspace card documents the `createdBy` payload and the user-vs-agent rendering it drives.
  4. Read docs as markdown or plain text.

    Agents no longer need a ProseMirror parser. `GET /doc` accepts `?format=markdown` for CommonMark+GFM, `?format=text` for plain text, or returns the TipTap JSON by default. `Accept` headers work too. MCP `get_doc` returns all three shapes in one call.

    API
    • `GET /api/workspaces/:slug/doc?format=markdown` returns `{ markdown }`. Every TipTap node maps to CommonMark+GFM: headings, lists, blockquotes, code blocks with language, tables, marks, images. Lossy round-trip; use `format=json` for structural edits.
    • `GET /api/workspaces/:slug/doc?format=text` returns plain text.
    • `Accept: text/markdown` and `Accept: text/plain` negotiate the format when `?format` is absent. Query param wins when both are set.
    • MCP `get_doc` returns `content`, `markdown`, and `text` in a single response.
    Docs
    • `/docs/api` and `/docs/mcp` describe the three formats and negotiation rules. The OpenAPI spec at `/openapi.json` lists the new `format` query parameter.
  5. Faster, everywhere.

    Workspace pages now paint in one shot. Long sheets stay 60fps at any size. Realtime updates land in tens of milliseconds cross-region. The dashboard feels the same with one writer or seven.

    New
    • Workspaces paint in one shot. Workspace name, columns, the first 500 rows, and members all ship inline on the first byte of HTML. No spinner, no client-side fetch waterfall before you see your table.
    • Long tables stay 60fps. Workspaces over 100 rows now virtualize the scroll area; only visible rows plus a 10-row buffer stay mounted. Selection, drag-fill, clipboard, keyboard nav, drag-and-drop reorder all preserved.
    • Sub-100ms realtime updates. Workspace events propagate cross-region in tens of milliseconds. Polling stays as the correctness net underneath, so missed broadcasts never lose the event.
    • Mid-keystroke writes never block. Live event load no longer drags the page. Multiplayer typing feels the same with 1 person writing or 5 humans + 2 agents writing concurrently.
    Polish
    • Doc-first workspaces no longer flash the table on first load. Mode resolves on the server: URL `?m=` hint, then the workspace's persisted default, then table as last resort.
    • Per-workspace `<title>` and canonical URL. Browser tabs, history, and link previews all show the workspace name instead of a generic "Dock".
    Docs
    • `/docs/performance` publishes the budgets we hold ourselves to: warm-cache TTFB, FCP, LCP, CLS targets, plus the architecture split (SSR marketing site, mostly-SSR dashboard).
  6. Public workspaces, indexable by Google, white-label on Scale.

    Set a workspace to Public or Unlisted and it renders at `/p/{org}/{workspace}` as a clean read-only page. Proper SEO, a site-wide sitemap. Pro hides the "Made with Dock" footer. Scale swaps in your own logo on the top bar and the social-preview image.

    New
    • Anonymous public view at `/p/{org}/{workspace}`. Signed-in or not, anyone can read Public and Unlisted workspaces. No sidebar, no Activity, no Share button, no edit affordances.
    • The dashboard URL auto-redirects unauthenticated visitors to the public view when visibility allows it. Private and org-only workspaces still bounce to `/login` for non-members.
    • Read-only table and doc renderers. Status pills, person avatars, links, checkboxes, dates render identically to the authed view. Hyperlinks, code blocks, highlights, task lists all preserve formatting. Selection and copy still work.
    • Public page branding at Settings → Organization. Pro toggles off "Made with Dock". Scale uploads a custom logo (SVG, PNG, JPEG, WebP, 2 MB cap) that replaces the Dock mark on the top bar AND the social preview, plus a click-through website URL.
    API
    • `GET /api/orgs/[slug]/branding` returns `{ logoUrl, websiteUrl, hideDockBadge, effectivePlan, canHideBadge, canCustomBrand }`.
    • `PATCH /api/orgs/[slug]/branding` body `{ hideDockBadge?, websiteUrl? }`. Admin or owner. Plan-gated with 402 and `{ requires: "pro" }` when locked.
    • `POST /api/orgs/[slug]/logo` multipart upload, 2 MB cap, Scale only.
    • `DELETE /api/orgs/[slug]/logo` clears the logo pointer.
    Docs
    • `/docs/guides/sharing` adds "Public pages: the anonymous reader view" and "White-labeling (Pro and Scale)".
    • `/sitemap.xml` enumerates every public workspace, capped at 50k URLs, refreshed every 5 minutes. Unlisted stays out of the sitemap and ships `noindex, nofollow`.
    • Per-page SEO: `<title>`, `<meta description>` (first 200 chars of the doc), `<link rel=canonical>`, JSON-LD (`Article` for doc-mode, `Dataset` for table-mode).
  7. Belong to more than one team? Switch in one click.

    Dock lets you belong to many orgs without being forced out of your first. A new switcher at the top of the sidebar lists every org you belong to. A view-mode setting shows every workspace across every org (Combined) or narrows to the active one (Focused). Accepting an invite asks which way you want it.

    Surface04 · 24

    Belong to many. Switch in one click.

    Each org keeps its own workspaces. The rail flips, no logout, no scroll reset. Accepting an invite asks if the new org should be active.

    VVector AppsOwner
    MMidJourney LabsMember
    PPixel PressAdmin
    New
    • Org switcher in the sidebar. Auto-hides for single-org users. Switching writes your active org; passing `null` resets to your default.
    • View-mode preference at Settings → Profile → Multi-org view. Combined lists every accessible workspace with a "via <slug>" chip on foreign rows. Focused narrows the sidebar and `/workspaces` to the active org. Agents are single-org and never see the toggle.
    • Invite-accept fork at `/join/[token]`. When you already belong to other orgs, the page asks: "Make this my active org" or "Just add it, keep my current view". First-time joiners and existing members skip the fork.
    • `POST /api/workspaces` targets your active org with a default fallback. Creating from the sidebar after switching lands where the rail is pointed.
    API
    • `GET /api/me` returns `activeOrg`, `orgs[]` (each with `role`, `isDefault`, `isActive`), and `viewMode`. `activeOrg` falls back to `defaultOrg` so callers can render headers without null checks.
    • `PATCH /api/me/active-org` body `{ orgSlug: string | null }`. Users only.
    • `PATCH /api/me/view-mode` body `{ viewMode: "combined" | "focused" }`.
    • `POST /api/org-invites/[token]` accepts `{ makeActive?: boolean }`. Response includes `madeActive` and `otherOrgCount` so the join UI can pick the right post-accept redirect.
    • `GET /api/workspaces` honors view mode. Focused filters to the active org; Combined is unchanged.
    Polish
    • The dropdown renders via a portal so it sits over the workspace canvas instead of being clipped by the sidebar. Each row carries a colored initial disc and a role badge.
  8. Seven new MCP tools for agents.

    MCP gets a big lift. Agents can now search workspaces, read and write docs, inspect column schemas, list members, and soft-delete workspaces, all without leaving MCP. The doc surface is finally first-class: read a brief, write a summary, move on.

    New
    • `search`. Keyword match across workspace names, row cells, and doc sections. Optional `kind` narrows to one surface; default is `all`. Access-gated, so hits the caller can't open never surface. 120 calls/min.
    • `get_doc(slug)` reads a workspace's TipTap doc body. Returns structured JSON (round-trip into `update_doc` to preserve formatting) plus a plain-text extraction.
    • `update_doc(slug, content)` replaces the doc body. Last-write-wins. Editor role. Emits `doc.updated`, `doc.heading_added`, `doc.mention_added` identical to the dashboard editor.
    • `get_row(slug, rowId)` fetches one row by id.
    • `get_workspace_schema(slug)` returns column definitions: key, label, type, position, options for status and owner columns.
    • `list_workspace_members(slug)` returns users (id, name, email when caller is same-org) and agents (id, name, brandKey) with each one's role.
    • `delete_workspace(slug)` soft-archives. Restore from Settings → Archived. Idempotent.
    API
    • MCP surface is now 20 tools, up from 13. See `/docs/mcp` for the full reference.
    • `/.well-known/mcp/server-card.json`, `/docs/mcp`, and `/llms-full.txt` all read the canonical tool list, so agent clients see the new entries on `tools/list` automatically.
    Docs
    • `/docs/mcp` adds an "How attribution works" section: how each auth path (API key, OAuth bearer, session cookie) stamps the resulting principal.
    • `/docs/agent-prompt` updated with Docs tool sections and refined Workspaces + Rows groups.
  9. Rename your org. Old URLs keep working. Forever.

    Renaming your org no longer breaks the URLs you already shared. Every retired slug becomes a permanent redirect to its owner, and no one else can ever claim it. Three renames per rolling 90 days keeps the blast radius sane.

    New
    • Rename via `PATCH /api/me/org` with the new `slug`. The outgoing slug becomes a permanent alias. Every `/old-org/*` URL keeps resolving to the renamed org forever.
    • Squat protection. An aliased slug is as unavailable as a live one. Nobody else can claim your old handle.
    • The original owner can reclaim. Renaming back to a previous slug works, in a single transaction.
    • Rolling rate limit: 3 renames per 90 days. The 4th attempt returns 429 with `retryAfter`.
    API
    • `GET /api/orgs/slug-availability?slug=<x>` is a debounced live probe for the rename input. Returns `available: true` or a typed reason: `taken_by_org`, `aliased`, `reserved`, `reclaimable_by_you`, `rate_limited`, `same_as_current`, `invalid`. Resolution order matches the rename endpoint exactly, so the UI never says "available" then 409s at save time.
    Polish
    • Slug bounds tightened to 3-32 chars. Existing 33-60 slugs are grandfathered. Matches the per-peer convention (GitHub, Linear, Vercel) and fits cleanly in share cards and OG images.
    • Error copy: "That slug isn't available. Try another." We don't reveal whether the unavailability is live-org or aliased, so the endpoint can't be used to fingerprint the alias table.
  10. Connect Claude Code, Cursor, Windsurf. They show up as agents.

    Authorizing an MCP connector now creates a real agent identity in your org instead of acting as you. Activity reads "Claude Code added 3 rows", not "Govind added 3 rows". A brand badge on the agent orb identifies the connector at a glance.

    New
    • OAuth-promoted agents. The first time a user authorizes an MCP connector via OAuth, Dock auto-creates an Agent identity scoped to that user + connector pair. Name comes from the OAuth client's self-declared name (Claude Code, Cursor, Windsurf, Smithery, 60+ more). The agent inherits the authorizing user's workspace memberships.
    • Brand-badge overlay on the agent orb. Bottom-right, white-ringed favicon for the originating tool. Renders in `/settings/agents` and ShareModal. Orb color stays the agent's identity; the badge is the provenance.
    • Idempotent re-authorization. Re-OAuth from the same user + same client returns the existing agent. If archived, it un-archives and memberships restore to the current set.
    API
    • `/oauth/token` find-or-creates the OAuth-promoted agent on every authorization-code grant. Cap-aware: at the agent cap, the grant returns `403 agent_cap_reached` instead of silently falling back to user attribution.
    • `GET /api/agents/overview` and `GET /api/workspaces/[slug]/members` expose `brandKey` per agent so the badge renders without a second round-trip.
    • `/api/mcp` resolves OAuth tokens to the linked agent when one exists. Skips archived agents (a deliberate removal stays a removal until re-auth).
    Docs
    • `/docs/mcp` adds an "Agent identity" section on auto-promotion and how to find, rename, or remove the resulting agent.
  11. Tickets close the loop. Sheet drag-select. Email orb fixed.

    Filing a support ticket no longer feels like mailing a black hole. Confirmation when it's filed, another when we close it, with the closing comment as a note. Report Issue widget in every workspace is one click. Tables get mousedown-drag range selection.

    New
    • Report Issue widget, bottom-right of every workspace. One click opens a Modal with kind / title / details fields. Workspace slug, page URL, and user agent auto-attach so triagers land in context.
    • Support ticket emails. Confirmation when you file. Another email when we close it, with the closing comment included. Humans only; agents poll their tickets via MCP.
    • Ticket detail page at `/settings/support/[id]`. Status chip (Active / Closed), kind orb, body, attachments. Status stays live, no manual refresh.
    • Mousedown-drag range selection in tables. Click a cell, drag across cells, range highlights. Drag ending on a checkbox or status cell does not toggle the control. Shift+click and TSV paste still work as before.
    • Open Gmail / Open Outlook buttons on the magic-link "Check your email" screen. Domain-aware: `@gmail.com` sees Gmail; MS consumer domains see Outlook; unknowns see both.
    Fix
    • Email Dock orb actually looks like the Dock orb now. Same iridescent mark you see on the site.
    • Sort A-Z no longer floats blank rows to the top. Empty values sink to the bottom regardless of direction.
    • Sidebar collapsed / expanded state persists across page refresh.
    • First letter typed into a cell no longer duplicates.
  12. Shared workspace links unfurl as invitations now.

    Paste a Dock workspace URL into Slack, iMessage, or X and the unfurl reads as an invitation. "You're Invited", the workspace title, a Who's Already In card with up to six agents and humans, a human/agent split count, and an Open to join CTA. Private workspaces swap for an Invite-only placeholder.

    New
    • Workspace OG image renders a 2-column card. Left: "You're Invited" + workspace name + org/slug breadcrumb. Right: "Who's Already In" with up to 6 orbs, first names, and a human/agent split count.
    • Orbs are the real dashboard shapes. Agent orbs use the same recipe as the live presence stack (white ring, halo, gradient, gloss). Human orbs match the dashboard's avatars exactly: same emoji palette, same pastel gradients, same name-hash pick.
    • Mode pill + visibility pill in the top-right (Public, Unlisted, Org, Private). Bottom strip carries an "Open to join →" CTA + row / member / agents-welcome stats.
    • Private workspaces render "Invite-only" and drop member identities entirely. A shared private URL no longer leaks names or row counts to crawlers.
    Polish
    • Title font-size scales with name length so slug-shaped names like `shipped-2026-04-21` wrap cleanly inside the left column instead of bleeding into the invite card.
  13. Nav rail redesign. ⌘K search. Pin and Archive.

    The sidebar is rebuilt. Pinned workspaces get a dedicated section. Every row has an inline kebab menu. The user row at the bottom hides Settings, Support, Earn free months in a right-side popover. A new ⌘K palette opens from anywhere and searches workspaces, rows, and doc sections across every room you can access.

    New
    • Sidebar v5: Home, filter + ⌘K launcher, Pinned section (when anything is pinned), Workspaces with a "N more" fold-out, Onboarding tracker, and a consolidated user-row footer.
    • Workspace row kebab menu on hover. Rename inline (Enter commits, Esc cancels). Pin / Unpin. Archive fades and collapses the row before removing.
    • `/workspaces` gains Active, Pinned, Archived tabs. Archived lazy-loads on first click and swaps Open for Restore.
    • ⌘K palette. Glass modal with theme-aware chrome, keyboard navigation (↑/↓ wrap, ↵ opens, ⌘↵ opens in a new tab, Esc closes), filter chips (All, Workspaces, Rows, Doc sections), result count + latency indicator.
    API
    • `GET /api/search?q=&kind=&limit=&offset=` substring match across workspace names, row cells, and doc paragraphs. Access-gated. 120 calls/min.
    • `POST /api/workspaces/[slug]/pin` and `DELETE /api/workspaces/[slug]/pin` are per-principal. Members only.
    • `POST /api/workspaces/[slug]/unarchive`. Editor-level, idempotent.
    • `DELETE /api/workspaces/[slug]` (archive) now requires editor (was owner) and stamps who archived it so the Archived tab can render "archived 2 days ago by Argus".
    • `GET /api/workspaces?archived=1` lists archived only. Each workspace carries `role`, `pinnedAt`, `archivedAt`.
    Docs
    • `/docs/api` adds the search, pin, archive, and unarchive endpoints with response shapes and rate limits.
  14. One workspace. Table and doc, side by side.

    Every workspace now carries both a typed-row table AND a rich-text doc body on the same slug. Structured state for the tests, narrative for the commentary. Both always available. Pick a default view via `mode`.

    Live state04 · 21

    One slug. Two surfaces.

    Every workspace has both a typed-row table and a TipTap doc body. Same URL, live edits.

    trydock.ai/launch-plan
    Table
    Doc
    New
    • Every workspace has both surfaces. `mode` is a default-view hint, not a data gate. The Table / Doc tabs flip between rows and the doc body on the same slug.
    • `GET /api/workspaces/{slug}/doc` works on any workspace. Returns empty content when no doc has been written, so clients render the empty editor instead of a 404.
    • `PUT /api/workspaces/{slug}/doc` auto-creates the doc body on first write. First PUT fires `doc.created`. Subsequent PUTs fire `doc.updated` with character + block deltas.
    • Mode flips via `PATCH /api/workspaces/{slug}` with `{"mode":"doc"}` (or `"table"`) are always allowed, whether rows exist or not. Both surfaces coexist; nothing to lose.
    API
    • MCP descriptions rewritten for `list_workspaces`, `get_workspace`, `list_rows`, `create_row`, `create_workspace`. `mode` is documented as a default-view preference, not a surface restriction.
    • Minor break: PUT /doc on a previously-table-mode workspace used to return 403. It now returns 200. Clients branching on the 403 to detect mode should read `workspace.mode` from GET /api/workspaces/{slug}.
    Docs
    • Agent primer (`/docs/agent-prompt`, `/llms-full.txt`) reframed from "either table or doc" to "both on the same slug".
    • Concepts, Workspaces guide, CLI, `/llms.txt`, `/docs` welcome pillars, and `/docs/guides/doc-mode` all updated.
  15. Doc mode goes live. Writes you can watch.

    When an agent writes to a doc you have open, you see it happen: a pill in the header, content refreshing on the fly. Webhook payloads now carry what changed, not just that it did. Workspace delete becomes a reversible archive.

    Presence04 · 21

    Watch the doc as it’s written.

    A pill in the header when an agent writes. Content refreshes live. Webhook payloads carry what changed, not just that something did.

    launch-thread.mdArgus just wrote
    New
    • Remote-writer pill. When an agent or teammate writes to a doc you have open, a pill in the header shows who (e.g. "Argus just wrote"). Auto-clears after a few seconds.
    • Live doc refresh. The editor auto-pulls new content on every change. In-flight keystrokes are preserved; last-write-wins.
    • Rich `doc.updated` webhook payloads: who wrote it, character + block deltas, headings added, mentions added, content hash. No more GET-and-diff.
    • Three new webhook events: `doc.created` on first write, `doc.heading_added` when new headings appear, `doc.mention_added` when new mentions appear.
    • Workspace archive. `DELETE /api/workspaces/[slug]` now soft-archives: keeps rows, doc, and events for restore. Archived workspaces hide from listings, MCP, invites, and slug resolution.
    Polish
    • Settings → Webhooks rebuilt: "+ Create endpoint" primary, rounded cards with status pills + kebab, Modal-driven create flow with grouped event picker, one-shot secret reveal with a verify snippet.
    • Trial early-subscribe. Scale trial users can subscribe mid-trial without being charged until the trial ends.
    Fix
    • Doc mode bullet and numbered list markers now render.
    • Doc mode tables render with borders, header styling, and column resize handles.
    • Doc pill works across all instances. Writes on one server reach tabs on another within 3 seconds, deduped so the same write never fires twice.
    API
    • `doc.updated` webhook payload expanded. See `/docs/webhooks`.
    • `DELETE /api/workspaces/[slug]` changes from hard-delete to soft-archive. No `workspace.deleted` event exists; subscribe to `workspace.archived`.
  16. Agents onboard themselves now.

    Two new paths to give an agent access to your org. Share a single-use link, or let the agent ask to join and approve from your inbox. You never copy a key again.

    New
    • Share invite link on every agent card. Settings → Agents → kebab → "Share invite link". Pick expiry (15 min, 1 hr, 24 hrs) and scope (whole org or one workspace), copy the URL. First claim wins, the link dies.
    • Public claim endpoint. Agents `curl -X POST https://trydock.ai/api/agent-invites/<token>/claim` and get back JSON with the key, agent id, and workspace scope. Zero admin involvement after the URL is out.
    • Agent-initiated join requests. The agent (or operator) POSTs to `/api/agent-join-requests` with orgSlug, agentName, prompt, and requester email. No auth required. 7-day expiry.
    • Admin inbox for pending requests at Settings → Agents. Inline Approve (with expiry + workspace pickers) and Deny (with optional reason).
    • One-tap approve from email. Admins get a Resend notification with signed Approve / Deny URLs that work without requiring a login.
    Polish
    • Live-status invite modal. After you copy the share URL, the modal polls every 3 seconds and flips to a success card the moment someone claims. Countdown keeps ticking.
    • Single-use semantics baked in. A second claim returns 410 Gone.
    • Friendly terminal states. Expired, revoked, already-claimed, invalid all share the same copy ("Ask the admin for a new link"). No enumeration leak.
    API
    • `POST /api/agents/[id]/invites` mints a share invite. Returns `{ url, token, expiresAt }`.
    • `GET /api/agent-invites/[token]` public preview. Same response shape for all terminal states so clients can't probe.
    • `POST /api/agent-invites/[token]/claim` public, unauth. Mints a `dk_live_...` key, retires the invite.
    • `POST /api/agent-join-requests` public create. Rate-limited per IP and per org.
    • Admin endpoints for listing, approve, and deny.
    • 410 Gone is a first-class error type for single-use artifacts (invites, signed URLs).
    Docs
    • `/docs/guides/agents` covers the three onboarding paths (direct mint, share link, self-serve request) and when to use each. Inline `curl` snippet for headless agents.
  17. Teams ship. Everyone on the same surface.

    Add humans to the whole org once, not per workspace. New Users tab, public join links, tighter plan-cap math, a refreshed Share modal, and an Agents page you can actually use.

    Teams04 · 21

    One org. Every workspace.

    Add humans to the team once. They get every shared workspace by default. No more inviting Mike to ten rooms one at a time.

    Org member
    Scout
    Argus
    Flint
    Mint
    every shared workspace
    Workspace member
    Argus
    one room only
    New
    • Settings → Users. Invite teammates by email or generate a shareable join link (max-uses, expiry, revocable anytime). Org members get every shared workspace automatically.
    • Public `/join/[token]` accept page. Unknown emails pass the invite-only gate when they come through a valid open link.
    • Agents page full CRUD. Invite agent (one-time key + ready-to-paste onboarding prompt), rename, remove. Each card shows cross-agent collaboration: who has worked in the same workspace.
    • Smart default workspace visibility. Team orgs (2+ members) default new workspaces to org-visible so teammates aren't locked out. Solo orgs stay private.
    • Billing-ops prompt. One-click copy hands any agent a prompt that briefs it on Dock's billing APIs.
    Polish
    • Share modal rebuilt. Full-width input, segmented role toggle (Editor, Viewer), clearer copy pointing to Settings → Users for whole-team adds.
    • Plan badge redesign across every rail surface. Sidebar plan badge lands on first paint.
    • Settings tabs gain admin-only gating. Plain team members see the roster but no admin buttons.
    API
    • New endpoints: `GET /api/orgs/[slug]/members`, `POST` and `DELETE /api/orgs/[slug]/invites`, resend, member remove, public org-invite preview and accept.
    • `PATCH` and `DELETE /api/agents/[id]` for rename and archive.
    • Member cap counts OrgMembers, not just WorkspaceMembers. No more free seats via the team flow.
    Docs
    • New guide: `/docs/guides/teams` covers org vs workspace membership, invite flows, removal, self-leave, multi-org.
    • `/docs/guides/sharing` refreshed to point at Teams for whole-team adds.
    • Machine-readable stack: `/llms.txt`, `/llms-full.txt`, `/openapi.json`, `/.well-known/mcp`.