Skip to content

fix(plugin-chatbot): draft card Publish (N) refreshes after a publish it did not run - #26539

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-fgqxfq
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-fgqxfq

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Steve · project thread
Fixes #26471
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:AI 对话里草稿卡的「发布 (N)」现在会订阅控制台已有的元数据刷新脉冲,横幅或 Studio 发布之后卡片重新读待发布数,归零就显示「已发布」。
  • 为什么改:从对话横幅发布后,卡片还显示「发布 (5)」,客户分不清发布到底成功没有。
  • 风险与回滚:只加一个可选 prop 和两行接线,没有新的计数来源;不传该 prop 的宿主行为不变。回滚即撤销本 PR。
  • 先看:ui/packages/plugin-chatbot/src/ChatbotEnhanced.tsx 新增的订阅 effect;ui/packages/app-shell/src/console/ai/AiChatPage.tsx 的两行接线;新测试文件。
  • 两分钟验证:cd ui && pnpm exec vitest run packages/plugin-chatbot/src/__tests__/ChatbotEnhanced.pendingCountPulse-26471.test.tsx,预期 2 条全绿。
  • 需要你做的:无,席位落地。

What changes

  • ChatbotEnhanced (plugin-chatbot) takes a new optional prop subscribeMetadataRefresh?: (listener) => unsubscribe, the same signature as app-shell's assistant-bus subscribeMetadataRefresh. The draft card's pending-count block records every package a draft card is bound to; one effect subscribes to the pulse and, on each pulse, re-reads those packages through the existing refreshPendingCount / fetchPendingDraftCount. No second count source. The effect is keyed on the subscriber and the fetcher, so it subscribes once and unsubscribes on unmount; a re-render fetches nothing.
  • The 发布 (N) render is unchanged: a count of 0 already draws the Published badge, exactly as a first render with 0 pending does.
  • AiChatPage.tsx (app-shell), the only host that wires fetchPendingDraftCount, passes the bus's subscribeMetadataRefresh (2 lines: the existing assistantBus import and the prop at the ChatbotEnhanced mount).
  • Why a prop and not an import: the pulse lives in app-shell (src/assistant/assistantBus.ts), and app-shell depends on plugin-chatbot, so importing it from plugin-chatbot would be a dependency cycle. The seat widened the file surface to those 2 app-shell lines (option A).
  • Root changeset 26471-draft-card-pending-count-pulse.md: patch for @object-ui/plugin-chatbot and @object-ui/app-shell.

Tests

  • New ui/packages/plugin-chatbot/src/__tests__/ChatbotEnhanced.pendingCountPulse-26471.test.tsx: (1) a card shows 发布 (2); a re-render fetches nothing; the pulse fires, the fetch now answers 0, and the card no longer offers 发布 (Published shown); (2) unmount unsubscribes, and a later pulse fetches nothing.
  • No existing test was edited.
  • Ablation (one-off, not kept): the subscription effect's guard was replaced with an unconditional return through scripts/ablation-replace.mjs (anchor 1 → 0, blob f6afd3b0aaa4 → 778b78f95853). Both new tests went red ("expected vi.fn() to be called 2 times, but got 1 times"; "expected +0 to be 1"). Restored: blob == HEAD and git diff HEAD empty.

Acceptance notes

Verification

All on head ecc34812.

Local runs
  • cd ui && pnpm exec vitest run new test + ChatbotEnhanced.changeCardV2-12894 + ChatbotEnhanced.draftPreviewAny-12968: Test Files 3 passed, Tests 27 passed (lock VERDICT command-exit 0).
  • pnpm --filter @object-ui/plugin-chatbot test --maxWorkers=2: Test Files 85 passed, Tests 807 passed (VERDICT command-exit 0).
  • app-shell, narrowed to the 21 console/ai/__tests__/AiChatPage.* files: Test Files 21 passed, Tests 98 passed (VERDICT command-exit 0). The full app-shell suite is left to CI Test UI.
  • pnpm --filter @object-ui/plugin-chatbot type-check: exit 0. pnpm --filter @object-ui/app-shell type-check: exit 0 (after building @object-ui/app-shell^...).
  • node scripts/pm/dispatch-gates.mjs --commands: 35 families, every one run with exit 0; --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero, all exit codes recorded).

Generated by Claude Code

…adata pulse

The draft tool card's Publish (N) count was fetched once per toolCallId and
only refreshed by the card's own publish/discard, so a publish from the chat
banner left a stale Publish (N). ChatbotEnhanced takes an optional
subscribeMetadataRefresh prop and re-reads every on-screen draft package's
count through fetchPendingDraftCount on each pulse; AiChatPage passes the
assistant bus's subscriber.

Claude-Session: https://claude.ai/code/session_01ADHkmRirVxTgwfMT99xmtc
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling labels Oct 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · seat domain:ui#1 · 2026-10-27T07:25Z · #26471

Head ecc34812 (read from the PR object). Fixes #26471.

Landing: ready + auto-merge through the relay.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 07:26
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 07:26
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 7600209 Oct 27, 2026
55 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-fgqxfq branch October 27, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Draft card keeps 「发布 (N)」 after the chat banner publishes: the pending count never refreshes (no subscriber to the metadata-refresh pulse)

2 participants