Skip to content

Replace per-workspace host state with one global publishUsers call - #157

Merged
molefrog merged 3 commits into
mainfrom
claude/collab-publish-users
Oct 9, 2026
Merged

molefrog merged 3 commits into
mainfrom
claude/collab-publish-users

Conversation

@molefrog

@molefrog molefrog commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

A host app that embeds moi now tells it who is signed in, and who all the users are, with one call. Before, the host had to keep a separate user list for each workspace, each with its own loading state, and go through a setup handshake to deliver it. Now there is one list for the whole app, and moi keeps it.

<script type="module">
  // Runs after moi's bundle. Call it again whenever something changes.
  window.moi.collab.publishUsers({
    me: 'user-alex',
    users: [{ id: 'user-alex', name: 'Alex' }, { id: 'user-anton', name: 'Anton', color: 'blue' }]
  })
</script>

Each call replaces everything. me has to be one of users. Leave it out when nobody is signed in.

Worth a look:

  • This breaks existing hosts. The old setHostState API and the moi:collab-ready event are gone.
  • The host script has to be a module script. A plain inline script runs before moi loads and finds nothing there.
  • Every workspace now shows the same users, so a member picker lists everyone, not just that workspace's members.

Also in here: the applet guide no longer says where users come from, and the PR description rule got a small update.

The commit message in 9375f9f has the rest of the details.

🤖 Generated with Claude Code

An outer host now hands moi its identity and users through a single call,
window.moi.collab.publishUsers({ me, users }). The same call covers startup
and every later change, and each call replaces the whole snapshot.

- The user directory is global to the moi instance instead of one list per
  workspace, and it no longer has a loading state. A published list is
  authoritative, including when it is empty.
- `me` is an id that must be listed in `users`. Leaving it out, or passing
  null, means nobody is signed in. The directory is then emptied even if the
  host still lists users.
- moi owns the state and the host only pushes into it. setHostState,
  getHostState, subscribeHostState, the getter read before load, and the
  moi:collab-ready event are removed.
- installHostApi() runs while the entry module evaluates rather than inside
  the async init, so a host module script placed after the bundle finds the
  API at once and publishes before React mounts. A classic inline script in
  that position runs before the bundle and finds nothing.
- Current-user observers are notified only when the viewer or its source
  actually changed. Each notice makes every open workspace resend the viewer
  profile to its room, so a directory update for other users now sends
  nothing over the socket.
- The engine contract exposes getDirectory and subscribeDirectory, and the
  default engine reads the same global directory, so users also resolve
  outside a workspace.

The applet API is unchanged. The applet guide drops the loading directory
and notes that the directory is the same in every workspace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T13:55:38.527128Z 9375f9f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

molefrog and others added 2 commits October 9, 2026 16:03
The guide is for agents building applets, who only read users through
hooks. Where the user list comes from is nothing an applet can see or act
on, so the paragraph about a host-supplied directory goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@molefrog
molefrog merged commit 87bbbfb into main Oct 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant