Repository navigation
Conversation
|
Warning Review limit reachedThe included review limit has been reached and this organization has disabled usage-based review continuation. Wait for reviews to reset or ask a billing admin to change After included review limits.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Next included review available in 28 minutes. View limit details
|
… when it cannot The Inbox's layout rules used unnamed container queries. The thread pane is a container too, so the rule that shows Back read the thread's width and Back appeared beside the list in the two-pane layout. The Inbox's container is now named and its rules query it. The list and the thread sit side by side from 560px of Inbox width (was 700px); the list's minimum is 240px, leaving the thread 320px. Back has a visible border where it shows. (cherry picked from commit 9b965da)
Replace @polymorfa/browser, @polymorfa/react, @polymorfa/elements, @polymorfa/ui, @polymorfa/store and @polymorfa/devtools with one package, @polymorfa/ui-kit, using subpath exports: the root, /internal, /react, /web-components (+ /chat, /templates, /calls), /appearance, /store (+ /store/react) and /devtools (+ /devtools/production). Sources and tests move without behavior changes. definePolymorfa becomes defineUiKit (DefineUiKitOptions) with no alias; the pmfa- prefix stays. react and react-dom are optional peers used only by the React subpaths. Examples, native host bridges, READMEs, the architecture doc and the changelog use the new imports. Browser call reports name @polymorfa/ui-kit.
… toggle state Session client tokens accept the two group actions in all six server SDKs, the drop-in handler and the UI Kit grant vocabulary. Customer tokens cannot carry them. The handler forwards them on session grants. Call toggles named their next action while also reporting aria-pressed, so a camera that was off read as 'Turn camera on, pressed'. They now carry only the action label. CallNumberPicker renders through the shared shell with the callNumberPicker slot, theme classes and bundled styles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add framework-neutral controllers for a searchable contacts directory, the new-chat flow and one WhatsApp group, with API sources that use the client token (read_contact, groups_read, groups_manage). React gets NewChat, ContactListView and GroupDetails; Web Components get <pmfa-new-chat> and <pmfa-group-details>. The Inbox opens new chats as drafts until their first message, and group threads show who wrote each run of messages. Relayed group messages no longer rename the conversation after their sender. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… React and elements Also fixes two Inbox defects the tests exposed: without a provider client the Inbox offered a call button that then threw, and API group defaults were offered with no client to call them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…an invite Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CallLogController groups consecutive calls as WhatsApp does and filters missed calls. React CallLog, <pmfa-call-log> and an Inbox Chats/Calls switch render it. Sources: the handler's history/calls route (read_calls), the store's reduced call.* events. The handler no longer relays call events without a peer to grants limited to conversations, and the store keeps a caller's number when later call events carry only the ID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ContactListView no longer takes the internal slot resolver: it takes className and classNames like every component and adds the stylesheet, theme and contactList slot. The directory-backed ContactList and <pmfa-contact-list> render the account's Contacts list on their own. React contact rows had lost the pmfa-contact-list class and rendered unstyled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All six SDKs read the new peer field on call records and accept the
read_calls client-token action. The UI Kit call log reads
GET /messaging/{session}/calls through client.messaging().calls by default.
The handler history/calls route and the event-derived call log sources are
removed; read_calls is forwarded to the API on session grants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Kit All six SDKs, the drop-in handler and the UI Kit accept the new session actions (conversations, labels, contact blocking, the account profile and privacy, channels, catalog reads and presence) and let Customer-scoped tokens carry every action except mcp. The UI Kit browser client gains chats, labels, profile, channels and catalog resources, presence.set, contact block/unblock/info and base64 group pictures. Calls clients take clientTokenSession so a Customer token names the number it calls from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The message field was 41.2px beside 40px buttons, and below 600px the buttons grew to 44px while the field stayed at 41px. In ChatWindow the emoji and attachment buttons were 40px next to a 44px field and Send. The composer now has one control size (40px, 44px below 600px and in ChatWindow). The field's vertical padding is derived from that size and its own line height, so one line matches the buttons at any text size; more lines still grow upward from the shared bottom edge.
GET /messaging/{session}/calls returns each call with the other party
in peer. Records are kept and served in the number's data region, so
caller identity is only on this route: Platform call records go back
to peerRef, which is what the API returns.
- TypeScript and Python: calls.list
- Go: SessionCalls().List
- .NET: Calls.ListAsync
- PHP: calls->list
- Rust: calls().list
Each has a native wire test.
The session calls list added Go and Rust SDK source files after the snippets were bound to the UI Kit consolidation. Re-bind sourceCommit to a3f6b51 and regenerate.
503df7f to
85eb685
Compare
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85eb685af2
ℹ️ 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".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| get(target, property, receiver) { | ||
| if (property !== "request") return Reflect.get(target, property, receiver); |
There was a problem hiding this comment.
Bind forwarded transport members to the original instance
When createBrowserCalls receives clientTokenSession, this proxy forwards getters and methods with the proxy as their receiver. BrowserTransport.baseUrl and BrowserTransport.token() access private fields, so both throw a TypeError; CallsSignalingClient uses these members to establish the lifecycle socket. This prevents Customer-scoped browser calls from connecting. Read getters against the original transport and bind forwarded methods to it, rather than forwarding the proxy receiver.
Useful? React with 👍 / 👎.
| const newChat = useOwnedController<NewChatController>( | ||
| controller, | ||
| () => | ||
| new NewChatController({ | ||
| contacts: contacts ?? createApiContactSource(client!), |
There was a problem hiding this comment.
Wait for the initial grant before initializing NewChat
When <NewChat/> mounts directly inside <PolymorfaProvider tokenEndpoint="…">, the initial grant has not arrived yet. Its startup effect immediately loads the API contacts source, whose client.can("read_contact") check rejects before token acquisition, leaving the directory in a permission-error state even after the grant arrives. Additionally, canCreate is initially false and useOwnedController retains that first controller, so an eventual groups_manage grant never enables group creation. Defer API-backed initialization until the grant is available, or update and reload the owned controller when it arrives.
Useful? React with 👍 / 👎.
| ) : snapshot.groups.length === 0 ? ( | ||
| <p className="pmfa-newchat-state"> | ||
| {text(configuration, snapshot.filter === "missed" ? "callLog.noMissed" : "callLog.empty")} | ||
| </p> | ||
| ) : ( |
There was a problem hiding this comment.
Keep pagination available when the missed filter has no matches
If the first page contains no missed calls but has a next cursor, choosing Missed renders this empty state and removes the Load more button, which exists only in the nonempty-list branch. CallLogController.setFilter() filters only loaded entries, so older missed calls cannot be reached from this view and the UI incorrectly reports no missed calls. The web-component renderer has the same branching issue. Keep pagination available when hasMore is true, or fetch additional matching pages before declaring the filtered log empty.
Useful? React with 👍 / 👎.
| shell.dataset.contactOpen = ""; | ||
| children.push(info); | ||
| } else delete shell.dataset.contactOpen; | ||
| shell.replaceChildren(...children); |
There was a problem hiding this comment.
Preserve connected panels during inbox rerenders
When an inbox activity update arrives while the new-chat panel is open, this unconditional replaceChildren removes and reinserts the same pmfa-new-chat element. Its disconnectedCallback() disposes the owned NewChatController, and reconnection creates a fresh one, discarding the search, selected group members and group name, or aborting an in-flight group creation. The call-log and group-details panels likewise dispose their owned controllers on these parent rerenders. Avoid disconnecting unchanged child elements when updating the inbox shell.
Useful? React with 👍 / 👎.
| ): Promise<boolean> { | ||
| this.assertActive(); | ||
| const current = this.getSnapshot(); | ||
| if (current.pending !== undefined || !this.canManage) return false; |
There was a problem hiding this comment.
Allow invite-code reads without group-management permission
For a grant with groups_read but no groups_manage, GroupDetails creates a controller with canManage: false yet still displays the Show invite button. Clicking it calls showInviteCode(), which goes through this guard and silently returns false without reading anything. The API source explicitly authorizes invite-code retrieval with groups_read, so this blocks an otherwise permitted read in both React and web-component group details. Separate read operations from the management guard, or exempt inviteCode while retaining the pending-operation check.
Useful? React with 👍 / 👎.
Related source stack
Backend native view: Stack 957.
Backend order: #877 → #878. This SDK PR targets
main; those are API contract dependencies, not Git parents. Consolidation predecessor: SDK #365, owned separately.Summary
Add a real contacts directory, Start New Chat, group creation/member/settings controls and an API-backed call log to framework-neutral controllers, React and native Web Components. All six server SDKs gain Number call-history reads and the new client-token actions.
Verification
At current remote head
85eb685af2238a41f20beb0bca14aa0dca65f448, native Go/Python/PHP/.NET/Rust CI passed. Both JavaScript CI jobs failed formatting on 37 files. Accepted-main integration, the genuine formatting repair and refreshed source/package/snippet qualification remain unfinished; the local successor has not been pushed. No fresh pass is claimed for it.Release status
Open source candidate; the Ready flag does not establish merge qualification. The carried #365 consolidation remains a separate predecessor owned by its existing source owner. The client-action API depends on polymorfa/polymorfa#877 (migration identity held); the regional call route is in #878 and still needs regional activation. Accepted API/coverage pins are unchanged. Missing or mismatched snippet recipes retain cURL fallback. No registry publication, API acceptance or customer availability is claimed.