Repository navigation
feat(studio): the right slot counts the copilot's items awaiting confirmation - #27789
Conversation
…irmation The copilot tab badge and the folded strip read 「AI 副驾 · N 项待确认」: plugin-chatbot's onPlanApprovalPendingChange now also reports the count (a change plan's rows, 1 for a build plan) and treats a pending change plan as a proposal; the assistant bus keeps the count per conversation. Claude-Session: https://claude.ai/code/session_01Utp6CZkqrAJBqDcZ2PKjos Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Utp6CZkqrAJBqDcZ2PKjos Co-authored-by: Claude <noreply@anthropic.com>
…-pf560g Claude-Session: https://claude.ai/code/session_01Utp6CZkqrAJBqDcZ2PKjos Co-authored-by: Claude <noreply@anthropic.com>
|
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe Contract-review-claim: session_01Utp6CaJoinvGQSbHeDaWBe · head 413cff8 · 2026-10-29T23:20Z |
|
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe Contract reviewServed-tier: Face: declaration only ( ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe 席位核对ACCEPT · head
Generated by Claude Code |
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe
Requested by Bill · project thread
维护者速读
ui/packages/plugin-chatbot/src/ChatbotEnhanced.tsx(newestProposal一段)、ui/packages/app-shell/src/assistant/assistantBus.ts(按会话存条数)、ui/packages/app-shell/src/views/studio-design/StudioRightSlot.tsx。pnpm --dir ui exec vitest run packages/plugin-chatbot/src/__tests__/ChatbotEnhanced.planApprovalCount-25943.test.tsx packages/app-shell/src/views/studio-design/__tests__/studioRightSlot-12725.test.tsx,预期全部通过,其中 zh 用例断言折叠条读「AI 副驾 · 3 项待确认」。Part of #25943
Clause-②: yes (widening)
Metadata-protocol: none
What changes
The card's Target 1–6 were measured on
main@481ade61first: items 1–6 already hold (the right slot, select-to-properties, the copilot strip and canvas hint, no 源码 tab, the status line and the item ⋯ menu, change card v2, the 变更 badge and 「草稿 · N 项未发布」, pillar labels fromlg), with one gap: the copilot segment and the folded strip carried a boolean 「方案待确认」 dot, not a count, and only for a build plan. This PR closes that gap.@object-ui/plugin-chatbot,ChatbotEnhanced. The newest-proposal reading behindonPlanApprovalPendingChangenow also counts a change plan (proposedChanges, the 「修改方案 · N 项」 card). A change plan is pending while its card still offers its confirm / 存为草稿 button: no replay verdict, no later same-tool commit, no click in flight (confirmPendingIds), no quota refusal (quotaBlockedChanges). The callback gains a second argument,count: the rows of a pending change plan, 1 for a pending build plan, 0 when nothing is pending. It fires when either value changes, and still keys on the reading alone, not the callback's identity.@object-ui/app-shell, assistant bus.publishPlanApprovalPendingtakes an optionalcount(defaults to 1 while pending) and keeps it per conversation beside the owner.usePlanApprovalPending()is unchanged in meaning (any pending reading of the signed-in user). NewusePlanApprovalPendingCount()sums the user's conversations.ChatPanepublishes the chat's count with its boolean.StudioCopilotStatuscarriesplanPendingCountin place ofplanPending. The copilot tab's dot becomes a count badge, and the strip readsAI 副驾 · {count} 项待确认(enAI copilot · {count} awaiting your approval) through the new studio keyengine.studio.slot.pendingCount; the tab's accessible description is the same sentence.ui/packages/plugin-chatbot/README.mddescribes the two-argument callback and the change-plan reading.content/docs/frontend/has no page that documents this prop, so none changed.Tests
ChatbotEnhanced.planApprovalCount-25943.test.tsx(5 cases, real wire envelopes through the real mapper, each asserting the reading and the card it mirrors): a change plan awaiting 存为草稿 reads[true, 2]; the click reads[false, 0]at once (applying); a drafted replay reads[false, 0]; a build plan reads[true, 1]and a newer change plan supersedes it with its rows (an unchanged reading is not re-announced); nothing proposed reads[false, 0].planApprovalPendingCount-25943.test.tsx(4 cases) for the bus: the per-conversation sum, a count change, a reading without a count counts 1, another user's readings are not counted.AiChatPage.planApprovalReachesLaunchers-11666.test.tsxgains one case: the chat's count reaches the bus and its end clears it.StudioDesignSurface.rightSlot-12725.test.tsx: the marker case now counts (badge2, description and strip text), plus a case with nothing pending.studioRightSlot-12725.test.tsxgains the zh strip case 「AI 副驾 · 3 项待确认」.planPendingtoplanPendingCount.Readings, all on the final head
413cff81(the work merged withorigin/main) under the verification lock unless a line says otherwise:Package suites: plugin-chatbot 92 files / 854 tests, i18n 90 files / 1380 passed + 13 skipped
app-shell and console: the 287 test files that name a touched module, 2130 / 2130 passed
Every
packages/app-shell/src/**andapps/console/src/**test file that namesStudioDesignSurface,StudioRightSlot,StudioAiCopilot,assistantBus,AiChatPage,ChatDock,ConsoleChatbotFaborplanApproval(git grep -l),--reporter=verbose:Test Files 287 passed (287) · Tests 2130 passed (2130), lock VERDICT command-exit 0. The whole@object-ui/app-shellsuite (1,911 files) was started and stopped after 16 minutes with no output (non-TTY reporter); it is left to CITest UI, which shards it.Type-check and lint
Ablations (four, each through scripts/ablation-replace.mjs, restored with blob == HEAD and git diff HEAD empty)
ChatbotEnhanced.tsx, the newest-proposal scan withouttool.proposedChanges→planApprovalCount-25943: 2 failed / 5 (the change plan reads, and the newer change plan's rows).ChatbotEnhanced.tsx, the count fixed to1→planApprovalCount-25943: 2 failed / 5.StudioRightSlot.tsx, the strip text back toengine.studio.slot.planPending→studioRightSlot-12725zh case andStudioDesignSurface.rightSlot-12725count case: 2 failed / 23.assistantBus.ts, the sum counting each reading as 1 →planApprovalPendingCount-25943and the ChatPane count case: 2 failed / 9.src, so no dist build sits between the mutation and the run.Derived gates (dispatch-gates --commands on this diff): 35 run, 35 exit 0, reconciled
pnpm --dir ui exec vitest run scripts/first exited 1 with four 15 s timeouts (check-hand-rolled-comment-mask,check-vi-mock-inherit) while it ran beside the locked test run; re-run alone under the lock:Test Files 169 passed | 2 skipped (171) · Tests 4902 passed | 2 skipped.dispatch-gates --ran: 35 derived, 35 run, 0 NOT-MEASURED, 0 UNRUN.Acceptance notes
main(StudioDesignSurface.rightSlot-12725,pillarsClaimSlot-12725,leafColumnSelection-12725,kanbanCardSelection-12725,copilotDraftBadge-12725,itemDraftLine-12725); this PR adds the count. 2: screenshots are NOT MEASURED — a local backend serves no AI agent catalog, so the copilot half never mounts and no proposal can be produced; the DOM is pinned by the jsdom cases above. 3: see the readings above; the whole@object-ui/app-shellsuite (1,911 files) is left to CITest UI.by: "api": the producer (cloudservice-ai-studio,stageDraft/applyDraft) does not passsurface: 'copilot', and this repo's HTTP doors refusecopilotfrom a client by design. The ui code for the marks is onmain. Carrier: cloud.hcpl_book.default(404 onGET /meta/view/...) while the copilot draftedhcpl_book.list. Reading ofmain:listViewTargetOffalls back toOBJECT.defaultwhen no merged list view is flaggedisDefault, and the runtime'sObjectViewpromotes the object's embeddedlistunder that same identity (defaultListViewId) as its default tab, so for an object that declareslistthe inspector and the runtime agree, and the view the copilot edited is a secondary one. They would disagree only for an object with neitherlistnor a flagged view, where the runtime shows the first list view; whetherhcpl_bookis that case was not measurable from here. Not changed.engine.studio.slot.planPendingis no longer read but stays in the studio table, so the i18n change only widens; retiring it is a narrowing for a later sweep.ChatbotEnhancedwould report(true, 0)for a pendingproposedChangeswith no rows; the assistant bus clamps a pending reading to at least 1. No such card reaches the chat today: the mapper liftsproposedChangesonly when the envelope carries at least one parseable change row (objectui#8343), so there is no visible defect in this repository. (Added by the seat from contract review 6510852862.)Verification
See the readings under Tests.
Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code