Skip to content

Experimental: canvas thread/feed/inbox tweaks (all-hands demo)#3387

Draft
adamleithp wants to merge 18 commits into
mainfrom
ux/all-hands-demo-july-13-2026
Draft

Experimental: canvas thread/feed/inbox tweaks (all-hands demo)#3387
adamleithp wants to merge 18 commits into
mainfrom
ux/all-hands-demo-july-13-2026

Conversation

@adamleithp

@adamleithp adamleithp commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Experimental changes staged for the all-hands demo. Draft on purpose — each item is a rough cut to be picked up and done properly later.

What changed

  • Thread: removed the "Create PR"/"Draft PR" ship actions from the open thread's agent row (the status chip still reflects PR/ship state).
  • Feed card status: the feed task card now agrees with the thread — a settled live session downgrades a stale non-terminal cloud run status to "Ready" instead of a lingering "In progress".
  • Inbox tab: added a placeholder "Inbox" tab to the channel tab strip with a live pipeline-report count badge (no destination yet; clicking is a no-op).
  • Polish: minor spacing / mention-link tweaks in the feed and mention rendering.

Notes

  • None of these are final — treat as a spike. Follow-up work will pick each part up individually.

🤖 Generated with Claude Code

@trunk-io

trunk-io Bot commented Jul 13, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff (1)

  1. packages/ui/src/features/canvas/hooks/useChannelFeedMessages.ts, line 2739-2743 (link)

    P2 Feed Polling Stops Permanently

    The comment says the feed endpoint may be missing during rollout, but the first 404 puts this query into error and disables all future polling. If the endpoint becomes available later in the same session, system feed rows still never load until something manually invalidates or remounts the query, so context lifecycle announcements stay invisible while task polling continues.

Reviews (1): Last reviewed commit: "load thread only after everything is loa..." | Re-trigger Greptile

Comment on lines +121 to +137
const backendChannelId = await resolveBackendChannelId(
client,
channelName,
).catch(() => undefined);

const result = await taskService.createTask(
{
content: buildContextGenerationPrompt({ channelName, channelId }),
taskDescription: `Generate CONTEXT.md for #${channelName}`,
// Defaults to a cloud run — generation should never tie up (or
// depend on) the local machine, and it's never the sticky last-used
// workspace mode. The dev-only picker can override to "local" to
// test a local build of these features before merging.
content: buildContextGenerationPrompt({
channelName,
channelId,
description,
}),
taskDescription: `Build CONTEXT.md for ${channelName}`,
workspaceMode,
adapter: adapter ?? "claude",
model,
channelId: backendChannelId,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unowned Planning Tasks

When backend channel resolution fails, this path swallows the error and still creates the planning task with channelId: undefined. The task can be created and filed to Recents, but it will not be owned by the feed channel and the feed-message block is skipped, so the user lands on a new context with no task card or “building CONTEXT.md” row even though the session started.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deliberate best-effort: if backend channel resolution fails we'd rather create the planning task (it still files into the context via fileTask, so Recents/Artifacts pick it up) than fail the whole create flow. The feed card is a nice-to-have on top. No change.

Comment thread packages/ui/src/features/canvas/hooks/useGenerateContext.ts
Comment thread packages/ui/src/features/canvas/components/CreateChannelModal.tsx
Comment thread packages/ui/src/features/canvas/components/ThreadPanel.tsx Outdated
@adamleithp adamleithp marked this pull request as draft July 14, 2026 09:01
@adamleithp adamleithp changed the title Ux/all hands demo july 13 2026 Experimental: canvas thread/feed/inbox tweaks (all-hands demo) Jul 14, 2026
adamleithp and others added 16 commits July 14, 2026 10:10
Reworks the create-context dialog into a plan-mode launcher and gives the context
index a real feed of "PostHog agent" system messages.

Create dialog (quill Dialog): asks for a name + a description of what the context
is about, then launches a cloud plan-mode session that investigates the repo and
PostHog and co-builds CONTEXT.md with the user (buildContextGenerationPrompt seeds
it with the description). Resolves adapter/model like the composer so cloud runs
aren't rejected, and owns the task on the backend channel so it lands in the
context feed (not just Recents). On failure the context is kept and the typed
description is preserved for the next attempt.

Context feed: after launch you land on the context index, where durable, team-
visible announcements render alongside the plan task card — "created this context"
(server-emitted channel_created) then "is building CONTEXT.md" (context_md_building),
in order, then the card you click into for the session. Backed by the new
ChannelFeedMessage endpoint (posthog/posthog); ordered via explicit timestamps.

Removes the old fire-and-forget generation-task tracking (setGenerationTask /
useFolderGenerationTask / GeneratingState + polling); the empty-state "Build with
agent" now opens the same describe-and-plan dialog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The feed-message endpoint (posthog#70320) isn't deployed, so the feed
opened with the plan-task card instead of a creation announcement.
Synthesize the opener from TaskChannel.created_at/created_by — canonical,
always sorts first, deploy-independent — and filter server-emitted
channel_created/context_created rows so nothing duplicates once the
backend lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Resolve the cloud model via modelResolver.resolveDefaultModel (like the
  freeform-canvas flow) instead of trusting the composer picker's async
  state; hard-stop with a toast when no model resolves, before the task
  (and orphaned context) is created.
- Stop polling the channel feed once the query errors and disable retries
  — the endpoint 404s on prod until posthog#70320 deploys, and the old
  numeric interval + default retries streamed ~4 requests per 5s forever.
- Make the feed merge comparator consistent for equal timestamps.
- Only consume the stashed create-dialog description in create mode, so
  the describe-mode open the failed-launch flow lands on doesn't wipe it.
- Narrow ChannelFeedMessageEvent to the one event actually posted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reduce vertical padding on channel feed and demo message thread items,
and trim the inline mention/link chip padding for a denser feed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Remove the "Create PR"/"Draft PR" ship actions from the open thread's
  agent row (the status chip still reflects PR/ship state).
- Feed task card now agrees with the thread: a settled live session
  downgrades a stale non-terminal cloud run status to "Ready" instead of
  a lingering "In progress".
- Add a placeholder "Inbox" tab to the channel tab strip with a live
  pipeline-report count badge (no destination yet; clicking is a no-op).
- Minor spacing/mention-link tweaks in the feed and mention rendering.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebase merged main's pinned DEFAULT_GATEWAY_MODEL with the branch's
gateway-resolved model into one createTask literal; the resolved
model wins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@adamleithp adamleithp force-pushed the ux/all-hands-demo-july-13-2026 branch from 56f1157 to 5d1a626 Compare July 14, 2026 09:12
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

React Doctor found 6 issues in 3 files · 6 warnings.

6 warnings

src/features/canvas/components/InsertFakeMessageDialog.tsx

src/features/canvas/components/MentionText.tsx

src/features/canvas/components/ThreadPanel.tsx

Reviewed by React Doctor for commit e3c7e98.

adamleithp and others added 2 commits July 14, 2026 10:16
reconcileTaskConnection recovers a local task with no latest_run by
connecting fresh and replaying the description as an initial prompt
(task-detail's interrupted-creation path). Opening a thread to read
or reply is not a run action — suspend the connection until a run
or live session exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Any throw after context creation (model resolution, task create,
invalid created_at reaching toISOString) rejected generate(),
skipping callers' null-path recovery (CreateChannelModal stashes the
description and lands on the new context). Catch, toast, return
null; clamp the feed timestamp to now when created_at is unparsable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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