Repository navigation
fix(plugin-chatbot,app-shell): an incremental edit (kind: 'edit') is never read as a whole-app build (objectui#10109) - #10441
Conversation
…' envelope as a whole-app build apply_edit now lists every artifact it staged in drafted[], including the app artifact an add_object op re-stages for the nav merge. The whole-app test "drafted[] contains an app entry" was exact only while apply_blueprint was its sole producer. The producer declares the difference on the envelope (kind: 'edit' on apply_edit, absent on apply_blueprint), so detectBuiltAppPackage returns undefined for an edit envelope before the drafted[] scan. detectDraftResult is untouched: the edit keeps its draft card and its packageId. Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
…0109) Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
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
Size Limits
|
…-built-app Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
…d as a whole-app build (objectui#10109) Pins added ahead of the change: the draft review carries the producer's kind, a reloaded edit builds no done panel, the cache round trip keeps kind, and neither a reopened nor a live apply_edit moves the conversation to Studio. The apply_blueprint cases are the controls. Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
…eview so an apply_edit is never a whole-app build (objectui#10109) DraftReview gains an optional kind 'edit' that detectDraftResult lifts from the envelope. Three readers that answered whole-app from the staged set now respect it: buildProgressFromDraftReview builds no done panel for an edit, the builtPackageId draft-review fallback in AiChatPage does not move an edit to Studio, and the chat cache keeps kind when it re-mints the draft envelope, so the detectBuiltAppPackage guard survives a cache-fallback reload. An envelope without kind behaves as before; autoPublishable is not read as a second signal. Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
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
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsDiff read.
No accidental narrowing of the no- Readers honour Whole-app readers left that ignore Declared residual: ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
kind: 'edit') is never read as a whole-app build (objectui#10109)
…-built-app Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
…he published type declares kind (objectui#10109) The inline copy of DraftReview's fields on ChatToolInvocation.draftReview stopped matching when DraftReview gained the producer's optional kind, so ChatbotEnhancedToolInvocation under-declared what the runtime delivers. It now references DraftReview; the copy's field docs move onto DraftReview so the published type keeps them. AiChatPage's DraftReview upcast is redundant and is dropped (type-only, same emitted code). The DraftReview.kind doc names the readers that actually check it. Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
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
Size Limits
|
Contract reviewServed-tier: ① Derived judgmentsRefs and delta.
Emitted-JS identity (PR-body claim reproduced, not taken on trust). No- Reader sites, each honouring Tests. Pin set at head: Premise (cloud 403, unmeasured). ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASSGenerated by Claude Code |
Fixes #10109
Clause-②: yes —
DraftReviewis exported from@object-ui/plugin-chatbot's entry, and this PR adds an optionalkindfield to it. The widening is small, but it is on the published surface.What changed
An
apply_editresult sayskind: 'edit'on its envelope, and itsdrafted[]can list theappartifact the edit re-staged: anadd_objectop re-stages it for the nav merge. Anapply_blueprintbuild carries nokind. Every reader that asks "did this finish a whole-app build?" now uses the producer'skindto tell the two apart, instead of guessing a build from the staged artifact types. An envelope withoutkindbehaves exactly as before.autoPublishableis not read as a second whole-app signal.Round 1 (
packages/plugin-chatbot/src/mapMessages.ts):detectBuiltAppPackagereturnsundefinedfor an envelope that sayskind: 'edit', before it looks atdrafted[]. This covers both the drafted posture and the auto-publish (status: 'published') posture.Round 2 (the seat's answer A on the card):
DraftReviewgains an optionalkind?: 'edit'.detectDraftResultfills it from the envelope. It declares only the value its readers act on, so an envelope that says anything else leaves it unset. The edit still gets its draft card, its items and itspackageId, so one-click publish still works.buildProgressFromDraftReviewbuilds no finished "Built X" panel for a draft review whosekindis'edit'. A reloaded edit now shows what it showed live.packages/app-shell/src/console/ai/AiChatPage.tsx: the draft-review fallback in thebuiltPackageIdmemo no longer moves an edit to Studio. It readskindstraight offtool.draftReview, which round 3 types asDraftReview.packages/app-shell/src/hooks/useChatConversation.ts:CachedDraftReviewanddraftReviewToCachedResultkeepkind, so the envelope rebuilt for a cache-fallback reload still sayskind: 'edit', and the round-1 guard still applies.Round 3 (after the contract review of
fb2a20e):ChatToolInvocation.draftReviewinpackages/plugin-chatbot/src/ChatbotEnhanced.tsx, which is published asChatbotEnhancedToolInvocation['draftReview'], is now typed asDraftReviewinstead of an inline copy of its fields. The two copies were field-identical until round 2 addedkind, which left the published tool-invocation type under-declaring what the runtime delivers. The copy's field docs move ontoDraftReview, so the published type keeps them. TheDraftReviewupcast inAiChatPage.tsxbecame redundant and was dropped. TheDraftReview.kinddoc now names the readers that actually check it. All of this is type and comment only: the emitted JavaScript ofAiChatPage.tsx,ChatbotEnhanced.tsxandmapMessages.tsis byte-identical betweenfb2a20eandf7eaadc(TypeScripttranspileModulewith comments removed, compared by SHA-256).Tests:
packages/plugin-chatbot/src/__tests__/mapMessages.builtAppEditEnvelope-10109.test.ts(extended),packages/app-shell/src/hooks/__tests__/useChatConversation.editKindRoundTrip-10109.test.ts(new), andpackages/app-shell/src/console/ai/__tests__/AiChatPage.builtTransition.test.tsx(three new cases; its existingapply_blueprintreopen, auto-publish and live-build pins are the controls). Changesets:.changeset/10109-edit-envelope-not-built-app.md(@object-ui/plugin-chatbot: minor, for the added type field) and.changeset/10109-app-shell-edit-not-built-moment.md(@object-ui/app-shell: patch).Red, then green
The pins were committed on their own first (
aa52689) and run against the source as it was before round 2:Tests 5 failed | 13 passed (18). The five red cases:kind: 'edit';kind;Every
apply_blueprintcontrol was green. The published-posture reopen was also green, because the round-1 guard already covered it. With the fix (fb2a20e) the result isTests 18 passed (18).Then each fix site was removed on its own at
fb2a20e, usingablation-replace.mjs --delete. Every mutation was proven on disk (anchor x1 to x0, blob changed), and every restore was proven (blob equals HEAD,git diff HEADempty):detectDraftResultliftingkindbuildProgressFromDraftReviewguardkindcheckkinddetectBuiltAppPackage(re-run after round 2)In every run the only red cases were edit cases, and no
apply_blueprintcontrol went red.Reverse check on the rebuilt
.d.ts: app-shell's test project resolves@object-ui/plugin-chatbotthroughdist. In a typed probe there,DraftReviewwithkind: 'edit'compiled (exit 0), andkind: 'build'failed withTS2322: Type '"build"' is not assignable to type '"edit"'. Both were restored.Local verification (HEAD
fb2a20e, withorigin/main0d39dc6merged in; merged, not rebased)turbo run build --filter="@object-ui/app-shell^..." --concurrency=2: 28 successful, 28 total.pnpm --filter @object-ui/plugin-chatbot type-checkandpnpm --filter @object-ui/app-shell type-check(each istsc --noEmit && tsc -p tsconfig.test.json): exit 0 each. The test projects'--listFilesOnlyincludes the new and extended pins.pnpm exec vitest run packages/plugin-chatbot/plus the 34 test files outside plugin-chatbot that nameAiChatPageoruseChatConversation(app-shell, apps/console, components, i18n):Test Files 83 passed (83),Tests 856 passed (856). This is a narrowed run: test files that reach these modules only indirectly, without naming them, are not in it. The full app-shell suite is left to CI.check-changeset-presence: "6 source file(s) of 2 released package(s) changed, and this change declares 2 changeset(s)".check-changeset-no-major,check-changeset-overwrite,check-changeset-fixed,check-control-bytes,check-vi-mock-specifiers,check-vi-mock-inherit,check-vi-mock-override-shape,check-test-path-roots,check-shell-escape-residue,check:esm-specifiers: exit 0 each.check:new-line-citations: "VERDICT new-cross-file-line-citations: 0 new citation(s)".check-changeset-claims: exit 0 (report-only). It flags.changeset/6169-chatbot-authoring-face-type.md(namesAiChatPage.tsx, about theautoResponsefields) and.changeset/8214-chatbot-anypart-state-widen.md(namesmapMessages.ts, aboutAnyPart.state). I read both, and both still hold.check-readme-exports: NOT MEASURED. It needs every package built, and the run said "the population COLLAPSED -- this run proves nothing". Left to CI.AiChatPage.tsxanduseChatConversation.ts, and the same two files at0d39dc6give the same 35. None is on a changed line. Linting is not type-aware (emptyparserOptions), so this diff cannot change the verdict on any untouched file. The fullpnpm lintis left to CI.Round 3 verification (HEAD
f7eaadc, withorigin/mainff14e29merged in; merged, not rebased)@object-ui/plugin-chatbotthroughdist, a function that takes aChatbotEnhancedToolInvocationand returnstool.draftReview?.kindfailed atfb2a20ewithTS2339: Property 'kind' does not exist on type '{ items: ...and compiled atf7eaadc(exit 0). The same probe bytes were used both times, and it was removed after each run.turbo run buildof the app-shell closure (28 successful) at the old head, then of plugin-chatbot (9 successful) at the new head. The rebuiltdist/ChatbotEnhanced.d.tsdeclaresdraftReview?: DraftReview.pnpm --filter @object-ui/plugin-chatbot type-checkandpnpm --filter @object-ui/app-shell type-check: exit 0 each.Tests 18 passed (18). The AiChatPage fallback site was ablated again because the declaration it reads through changed:Tests 2 failed | 16 passed (18)(drafted reopen, live completion), then restored. The other sites' lines are unchanged, so their ablations were not re-run.check-changeset-presence("7 source file(s) of 2 released package(s) changed, and this change declares 2 changeset(s)"),check-changeset-no-major,check-changeset-overwrite,check-changeset-fixed,check-package-self-import,check-control-bytes,check-vi-mock-specifiers,check-vi-mock-inherit,check-vi-mock-override-shape,check-test-path-roots,check-shell-escape-residue,check:esm-specifiers,check:new-line-citations(0 new).check-changeset-claims(report-only) now also flags.changeset/6687-chatbot-surface-authorable.md, which namesChatbotEnhanced.tsxaboutChatbotSurface; that paragraph still holds.fb2a20e(ChatbotEnhanced.tsx10,AiChatPage.tsx31,mapMessages.ts0).Acceptance notes
kindread here (apply_editansweringkind: 'edit',apply_blueprintcarrying none) rests on the producer seat's filing on the card. Whether the producer change is live in the cloud repository, and which.objectui-shait pins, is also NOT MEASURED. Nothing in objectui or in the installed@objectstack/*17.4.0 declareskindon the chat tool-result envelope.Generated by Claude Code