Repository navigation
NEXUS-4029: Add task source references and primary controls - #1889
Conversation
372d5f3 to
b51dd9f
Compare
64ba117 to
6c76138
Compare
4ab1160 to
7696f76
Compare
|
🤖 @codex review |
|
To use Codex here, create a Codex account and connect to github. |
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source review via Wes’s account.
Reviewed head 6c7613893ec4b96d0823524a535cf494f7b62103 against base 7696f760e4c6aaa17a02a629bf5b1820feff3b7c. Integrated independent systems/lifecycle, correctness/security/concurrency, and product/accessibility source reviews.
One P2 product finding is inline: existing task chats lose their durable-primary selection control.
[P2] Remove internal coordination links from the public PR description. The description links to an internal hosted report, a repository verified private, and organization-internal issue tracking. Replace those links with a self-contained public explanation of the dependency and intended behavior; keep internal coordination in its private workspace. The URLs are intentionally not repeated here. No credentials were identified.
Source-only: no tests, builds, PR code or apps were executed. A one-time check-runs snapshot at this head lists successful DCO, Semgrep and zizmor checks; it provides no application-test evidence. No browser cases were added or removed in this patch; colocated and native tests were inspected, not run. Runtime focus, native folder selection, cross-platform behavior and human acceptance remain unverified. Public description and feature commit text inspected; no attached images. COMMENT only, not approval.
| : taskChannel | ||
| ? (value.recipients[0]?.pubkey ?? taskPrimary) | ||
| : undefined, | ||
| selectPrimary: taskDraft?.selectPrimary |
There was a problem hiding this comment.
🤖 [P2] Keep durable-primary selection available in existing task chats
selectPrimary is supplied only for a new taskDraft, while this patch removes TaskRecipientControl, the existing UI caller of participants.makePrimary. In an already-created task, the toolbar therefore falls back to inserting a one-message mention. After sending to agent B, the next untagged message still goes to primary A; there is no longer a UI action to make B the durable primary. A task whose primary is no longer eligible also loses that repair action.
Restore an explicit bound-task action using the existing participants.makePrimary contract, preserving current membership/incarnation guards and explicit mentions. Keep a mounted test that changes primary through the real control: the updated cases at lines 12250 and 12337 call the fixture’s makePrimary directly and consequently cannot detect this missing UI.
6c76138 to
b8e1133
Compare
7696f76 to
0aac713
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord’s automated source follow-up via Wes’s account.
Reviewed head b8e1133acda40dda568bad28f96cef748f57968d against base 0aac7134db8ae6428504f69a07b17731650c674f.
No new actionable finding in this limited follow-up. Direct comparison with the previously reviewed head shows only an inherited retry-test assertion change in CommunityAddress.test.tsx (one insertion, five deletions). The base contains exactly that same change, and the complete feature diff is byte-for-byte unchanged. This meets our small-follow-up solo exception; Star Lord performed this pass without new delegate reviews.
The two P2 findings in the previous review remain unresolved: durable-primary selection in existing task chats, and internal coordination links in the public description. Their existing comments remain the actionable feedback; no duplicate inline comments are added.
Source-only: no tests, builds, PR code or apps executed. The single check-runs snapshot includes running jobs, cancelled jobs and a failed CI required check; no green-CI claim or failure attribution is made. Runtime retry/focus, native folder selection and human acceptance remain unverified. Public description and current feature commit messages inspected; no attached images. COMMENT only, not approval.
…a channel (#2512) ## TL;DR Adds `conversation.ui.Conversation`, a public host-owned scope that lets a plugin's own `ui.Message` rows and `ui.Composer` for one channel get native Edit, confirmed Delete with recovery and retry, and host media review. Mounting it never marks anything read, follows a thread or enters the channel visit. Cross-channel overview cards need this; today a bare `ui.Message` row has neither Edit nor Delete, and `ui.Thread` always visits. Fixes NEXUS-4193 ## How it works `ui.Conversation({ session, scope, channelId, channelName?, threadId?, children(interactions) })` renders the existing `ConversationChannel` in its host-dialog, non-visiting mode (`host` plus `active={false}`). Inbox Drafts already uses this mode internally. Inside it: - `MessageManagement` supplies the row menu's Edit/Delete under the existing permission checks, the delete confirmation and the failed/unconfirmed recovery notice. - `MessageEditScope` makes Edit target the `ui.Composer` in the same scope. A scope without a composer offers no Edit, as in other previews. - `ConversationHost` owns media review and panel overlays, focus return, and the existing stale-session guard (nothing opens once the relay snapshot is no longer this ready session). `children` receives the host's `onOpenLink`, `canOpenLink` and `onOpenMediaReview` to pass to the rows. `EmbeddedThread` and the new scope now share one `HostedChannel` wrapper, so `ui.Thread` behavior is unchanged. No changes to `MessageManagement`, `ConversationHost`, `MessageComposer` or `contracts.ts`. ## Evidence `src/features/conversation/EmbeddedConversation.test.tsx` mounts two fictional channel cards (real relay session, real `ui.Message` rows and `ui.Composer` from `ConversationService`; only `MediaReviewViewer` is reduced, since it has its own suites). It covers: - the same rows without the scope have no Edit/Delete; inside it, each card offers both - mount, background presentation, re-present and unmount never call `enterChannel`, `leaveChannel`, `follow`, `markMessageRead`, `markChannelRead` or the roster's `profiles.reserve`, and publish nothing - Edit fills only that card's composer and publishes a kind-40003 edit tagged with that card's channel. The other card's message is untouched. - Delete: cancel publishes nothing; confirm publishes kind 5; a relay rejection shows the recovery notice in that card only; Retry resends the same event id and the row goes away - media review opens with the card's channel and message, and stops opening after the session stops being ready Fail-then-pass: with `active={false}` removed from the scope, all 4 tests fail (`enterChannel` and `profiles.reserve` are called). The scope restored, all pass. The packed `@buzz/author` consumer fixture (`tests/fixtures/conversation-consumer`) now renders its rows and composer inside `ui.Conversation` and passes `interactions.onOpenLink` to its rows. So the generated declarations must export the new component and its `children(interactions)` type, and the existing `conversation.spec.mjs` journey mounts it in the real app. The fixture type-checks against freshly built declarations. As a negative control, a misspelled interactions field fails `tsc`. Run on a Linux Blox box on base `a34ba4f` (the local host-build guard refused under load): - `vitest run src/features/conversation src/features/messages/MessageManagement.test.tsx src/bundled/inbox/DraftsView.test.tsx`: 19 files, 221 tests passed - `tsc --noEmit` and `biome check --error-on-warnings` on the touched files: clean - `pnpm author:build`, packed and installed into a copy of the consumer fixture, then `pnpm build` (`tsc`): clean No browser journeys were added or removed. The existing consumer journey now mounts the scope; it runs only in hosted CI, not locally. Focus, overlay and native-edit geometry are unchanged existing `ConversationHost`/composer behavior that existing suites already cover. ## Limits and coordination - Not exercised in the native desktop app or a browser journey. Hosted CI runs the full suites. - Two `ui.Conversation`s for the same channel each show that channel's recovery notice, because recovery is per channel. The docs say to render one per channel or card. - No overlap in hunks or behavior with #2483 (Solo list arrangement/row action in `service.tsx`), #1889, #2306 or #2303 (`contracts.ts`), #2083 (`MessageManagement.tsx`) or #2167 (`ConversationHost.tsx`). This PR does not edit `contracts.ts`, `MessageManagement.tsx` or `ConversationHost.tsx`. - This PR doesn't adopt the scope in any plugin. That is separate work. ## Initiative context [Buzz Threads status](https://g2.sqprod.co/apps/kylez-buzz-threads-status) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Kyle Zemek <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
Choose a task's primary agent from the existing mention toolbar, using the shared agent choices and the task's eligibility. Label the draft New task and show its workspace in the header with a remove action. Workspace filing stays personal document metadata, so recovery compares only signed message content. The product catalogue uses real agent choices so its mention control renders. Co-authored-by: Codex <[email protected]> Co-authored-by: Claude <[email protected]> Signed-off-by: Gil Birman <[email protected]>
b8e1133 to
34e10b6
Compare
0aac713 to
325ffdd
Compare
ELIE: What the buzz-app Nexus host stack adds to Buzz
Task authors need source choices that survive editing and retry, and a clear way to change the primary agent. Keep project selection in draft metadata, preserve inline repository, folder and skill references, and show the effective recipient in the composer toolbar. Primary changes preserve explicit mentions; project labels stay out of the prompt and new signed message tags.
Reuse the token and durable-draft owners from #2303 and #2306. Desktop folder listing reads only immediate real directories under the configured repositories folder, with existing size bounds and no symlink traversal. The Nexus plugin supplies the pickers. Refs NEXUS-4022, NEXUS-4029 and NEXUS-4051.
Generated with Codex