Skip to content

fix(app-shell): the Studio copilot draws no pending-drafts bar over its composer (objectui#12965, part of objectui#12725) - #12975

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-12965-studio-drafts-bar
Oct 18, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-12965-studio-drafts-bar

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #12965
Clause-②: no

Part of #12725. This is a draft by a dispatched developer; the seat repo:cloud#2 lands it. Session: https://claude.ai/code/session_01Cbdek8SKSHxddGqTPZXdqX.

What changes

In the package's own Studio, ChatPane (packages/app-shell/src/console/ai/AiChatPage.tsx) no longer mounts PendingDraftsBar. In the Studio copilot's right slot, the floating bar (「有 1 项改动尚未发布… 发布」, absolute at bottom-20, objectui#5694) sat over the composer's input line and hid the placeholder and the first typed line. There, the top bar's 变更 and 发布 and the applied card's 查看变更并发布 are the ways to review and publish, and #12725's ruled StudioRailCopilot artboard draws no bar.

Measured (live, zh-CN, the real build agent, one pending draft)

The driver is #12725 phase 6's, with the agent named build so isBuildSurface is true; only the reading is new. It records the composer textarea's box, the bar's box and their overlap. It also records what document.elementFromPoint finds at five points along the textarea's first text line, where the placeholder is drawn.

reading bar overlap with the textarea first-line points on the composer 变更 badge
Studio 1010, before (main at 43efd078) shown 267 by 51 px 0 of 5 (all the bar) 1
Studio 1280, before shown 327 by 51 px 0 of 5 (all the bar) 1
Studio 1010, after not drawn none 5 of 5 1
Studio 1280, after not drawn none 5 of 5 1
Full-page 1280, before and after (control) shown 670 by 51 px 0 of 5 n/a

After the fix, the placeholder 「问问数据,或让我改改这个应用…」 measures 208 px in the textarea's font, against 273 px (1010) and 333 px (1280) of content width, so it shows whole. The full-page control gives the same reading before and after.

Tests

packages/app-shell/src/console/ai/__tests__/AiChatPage.studioDraftsBar-12965.test.tsx, 3 tests. The harness is phase 6's: the real ChatPane and the real PendingDraftsBar, with ChatbotEnhanced stubbed. _drafts answers one draft for the bound package in every case.

  • On one of the package's Studio pillars, no pending-drafts-bar is drawn. A sibling probe reads the same ledger through usePendingDrafts, the hook the Studio top bar's 变更 badge uses. The probe must answer 1 before the bar's absence is read, so the absence is not read before the ledger has answered.
  • CONTROL, two hosts: the full-page chat (/ai/build/conv-1?package=app.hcpl) and the console dock's location (/apps/hcpl/hcpl_borrowing) still draw the bar.
  • No layout runs in the test. The unobstructed input line is the live reading above.

Run: pnpm exec vitest run packages/app-shell/src/console/ai/__tests__/AiChatPage.studioDraftsBar-12965.test.tsx --maxWorkers=2: Test Files 1 passed (1), Tests 3 passed (3).

Ablation (once, on the condition; the fix committed first as ac7edbc6). It went through ablation-replace.mjs in WRAP mode: anchor {isBuildSurface && !onBoundPackageStudio ? ( replaced by {isBuildSurface ? (. The anchor went from 1 hit to 0 and the blob from 02504bbffb97 to 1f902a32a34a. The same run went red as expected: Tests 1 failed | 2 passed (3), the Studio case failing on queryByTestId('pending-drafts-bar') (it expected null and got the bar's DIV), both controls green. Restore: the blob after restore equals HEAD (02504bbffb97), git diff HEAD is empty, and an on-disk grep -c of the anchor reads 1. The ablation was one-off; no permanent file was added for it.

@object-ui/app-shell full suite, at ac7edbc6 (the head of this PR), in 12 shards through the verify lock (pnpm exec vitest run --maxWorkers=2 --shard=K/12 packages/app-shell/). Every shard reported VERDICT command-exit 0. In total: Test Files 1570 passed | 1 skipped (1571), which equals the 1571 tracked app-shell test files (git ls-files at the same head); Tests 14761 passed | 9 skipped (14770); 0 failed.

Gates

Local, each exit code captured before any pipe:

  • pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build: VERDICT command-exit 0.
  • pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json): VERDICT command-exit 0, 0 error TS. tsc -p tsconfig.test.json --listFilesOnly lists the new test file.
  • eslint on the two changed source and test files: exit 0, 0 errors. Warnings on AiChatPage.tsx: 34 at base, 34 at head. The new test file has 0.
  • Exit 0: check:new-line-citations, check:control-bytes, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:changeset-claims, check:pending-changeset-literals, check:spec-symbols, check:phantom-deps, check:self-import, check:esm-specifiers, check:unreferenced-sources, check:handler-key-reads, check:metadata-write-doors, check:comment-mask-corpus, check:i18n-keys, check:doc-json (after the closure build; before it, exit 2, PREREQUISITE, the strict face unbuilt), check:doc-fences, check:doc-types, check:doc-example-ids, check:doc-example-readers, check:shell-escape-residue, changeset:check, node scripts/check-changeset-presence.mjs, node scripts/check-changeset-no-major.mjs.
  • NOT MEASURED locally: check:doc-snippets and check:doc-examples (exit 2, PREREQUISITE: a scoped build of the 34 packages the covered documents import). The docs change is one table-row sentence with no code fence. CI runs both.

objectui has no dispatch-gates.mjs. The list above is the root package.json check:* scripts whose scan roots read app-shell source, test files, .changeset/ or content/docs, the same derivation as PR #12964. CI's check-runs are the merge gate.

Evidence

Branch claude/issue-12965-evidence at df567c61, evidence/12965/ (never merged): six screenshots (Studio 1010 and 1280, before and after; full-page 1280, before and after), the six JSON readings, the driver and a README.

Deviations

  • File surface: the claim names AiChatPage.tsx, tests beside it and a changeset. The PR also adds one sentence to content/docs/guide/console.md (AGENTS.md Add automated testing infrastructure and CI/CD workflows #2). Nothing else.
  • The condition is keyed on the bound package's own Studio, not on "any Studio". The two agree for every host today, since the Studio copilot always passes its own package as editPackageId. Keying on the bound package reuses the one predicate the applied card's door already reads instead of writing a second path test.

Acceptance notes


Generated by Claude Code

…ts composer (objectui#12965, part of objectui#12725)

In the package's own Studio, ChatPane no longer mounts PendingDraftsBar.
In the copilot's right slot the floating bar sat over the composer's input
line (measured at 1010 and 1280 px with the real build agent and one
pending draft) and hid the placeholder. There the top bar's 变更 and 发布
and the applied card's 查看变更并发布 review and publish, and the ruled
StudioRailCopilot artboard draws no bar.

The condition is the reading the applied card's review door already
makes: studioChangesReviewTarget replaces the entry exactly when the
location is on the bound package's Studio pillar. The full-page chat and
the console dock keep the bar unchanged.

Claude-Session: https://claude.ai/code/session_01Cbdek8SKSHxddGqTPZXdqX
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation tests package: app-shell labels Oct 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 75 chunks) 3161.7 KB 3744.1 KB
Main entry chunk (gzip) 80.5 KB 350 KB
Entry file index-rc134vho.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 21.41KB 7.88KB
app-shell (runtime-config.js) 24.52KB 8.48KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 45.59KB 12.03KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 20.67KB 6.12KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.74KB 3.94KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.62KB 0.83KB
auth (authStyles.js) 5.27KB 1.86KB
auth (createAuthClient.js) 42.84KB 11.66KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.26KB 8.03KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (commentAuthorship.js) 1.39KB 0.78KB
collaboration (index.js) 1.93KB 0.85KB
collaboration (useCollaborationTranslation.js) 6.50KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 612.39KB 149.02KB
core (index.js) 10.18KB 4.04KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 248.83KB 69.44KB
fields (index.js) 291.72KB 74.47KB
i18n (LocalizationContext.js) 2.92KB 1.42KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.52KB 2.39KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 36.87KB 9.88KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.33KB 11.96KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 15.35KB 5.51KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.82KB 2.38KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.04KB 3.92KB
plugin-calendar (index.js) 55.04KB 16.10KB
plugin-charts (index.js) 85.06KB 23.39KB
plugin-chatbot (index.js) 230.81KB 54.29KB
plugin-dashboard (index.js) 147.53KB 39.95KB
plugin-designer (index.js) 233.95KB 50.08KB
plugin-detail (index.js) 266.04KB 70.50KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 181.16KB 46.84KB
plugin-gantt (index.js) 178.46KB 45.13KB
plugin-grid (index.js) 272.87KB 75.68KB
plugin-kanban (index.js) 63.37KB 19.51KB
plugin-list (index.js) 139.82KB 36.04KB
plugin-map (index.js) 27.17KB 9.00KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 46.66KB 13.13KB
plugin-timeline (index.js) 39.31KB 11.88KB
plugin-tree (index.js) 15.27KB 5.40KB
plugin-view (index.js) 94.68KB 24.36KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 12.07KB 3.68KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 125.37KB 41.04KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.71KB 2.11KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.07KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.81KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (product-blocks.js) 0.20KB 0.19KB
types (record-approval-decision.js) 0.20KB 0.20KB
types (record-components.js) 0.20KB 0.19KB
types (record-panels.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.26KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.48KB 3.50KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · repo:cloud#2 · session session_01Cbdek8SKSHxddGqTPZXdqX · 2026-10-18T16:08Z

Thread-read: objectui#12965's newest comment is the os-dev-report. PR #12975 is at head ac7edbc6.

  • 形态:
    • Draft, base main (43efd078). First lines Fixes #12965 and Clause-②: no. Assignee os-zhuang.
    • 4 files, +174 / −3: AiChatPage.tsx (one condition), a new test file, a changeset, one sentence in content/docs/guide/console.md.
    • No governed path. PendingDraftsBar.tsx is untouched, there is no packages/plugin-chatbot/** file, and the 变更 badge and the applied card are untouched, as the stop rules require.
  • 前提实测:
  • 门禁 check-runs on ac7edbc6: green or an expected skip at landing (the gate reads them). Local, per the report:
    • the new test 3 / 3 (the Studio case and two controls, the full-page chat and the console dock);
    • the full app-shell suite in 12 shards: 1570 passed + 1 skipped = the 1571 tracked files, 14761 tests;
    • type-check 0, eslint 0 errors (warnings 34 → 34), and 25 check:* scripts 0. check:doc-snippets and check:doc-examples were not measured locally; CI runs them.
    • Ablation on the condition turned the Studio case red with both controls green; restored by blob hash with an empty git diff HEAD.
    • Evidence is on claude/issue-12965-evidence df567c61.
  • 接受的偏差:
  • 范围外去向:
    • Filed objectui#12978 (Part of #12724): on the full-page AI build chat, the same bar covers the composer by 670 × 51 px. The bar stays there, because no top bar carries 变更 there, but it must not cover the input.
  • 落地条款:

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 18, 2026 16:09
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 18, 2026 16:09
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 18, 2026
Merged via the queue into main with commit 32a171e Oct 18, 2026
37 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-12965-studio-drafts-bar branch October 18, 2026 16:21
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 package: app-shell tests

Projects

None yet

2 participants