@object-ui/app-shell 6.2.3 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +1229 -0
  2. package/README.md +292 -0
  3. package/dist/assistant/assistantBus.d.ts +72 -0
  4. package/dist/assistant/assistantBus.js +133 -0
  5. package/dist/chrome/CommandPalette.d.ts +1 -1
  6. package/dist/chrome/CommandPalette.js +26 -22
  7. package/dist/chrome/ConditionalAuthWrapper.d.ts +1 -1
  8. package/dist/chrome/ConsoleToaster.d.ts +1 -1
  9. package/dist/chrome/ConsoleToaster.js +3 -1
  10. package/dist/chrome/ErrorBoundary.d.ts +1 -1
  11. package/dist/chrome/KeyboardShortcutsDialog.d.ts +1 -1
  12. package/dist/chrome/KeyboardShortcutsDialog.js +16 -5
  13. package/dist/chrome/LoadingScreen.d.ts +1 -1
  14. package/dist/chrome/LoadingScreen.js +22 -26
  15. package/dist/chrome/RouteFader.d.ts +1 -1
  16. package/dist/chrome/ThemeProvider.d.ts +1 -1
  17. package/dist/components/ManagedByBadge.d.ts +1 -1
  18. package/dist/console/AppContent.d.ts +1 -1
  19. package/dist/console/AppContent.js +184 -39
  20. package/dist/console/ConsoleShell.d.ts +7 -7
  21. package/dist/console/ConsoleShell.js +32 -3
  22. package/dist/console/ai/AiChatPage.d.ts +88 -1
  23. package/dist/console/ai/AiChatPage.js +747 -66
  24. package/dist/console/ai/ConversationsSidebar.d.ts +26 -1
  25. package/dist/console/ai/ConversationsSidebar.js +149 -34
  26. package/dist/console/ai/LiveCanvas.d.ts +28 -0
  27. package/dist/console/ai/LiveCanvas.js +80 -0
  28. package/dist/console/ai/reconcileTurn.d.ts +8 -0
  29. package/dist/console/ai/reconcileTurn.js +20 -0
  30. package/dist/console/auth/AuthPageLayout.d.ts +1 -1
  31. package/dist/console/auth/ForgotPasswordPage.d.ts +1 -1
  32. package/dist/console/auth/LoginPage.d.ts +1 -1
  33. package/dist/console/auth/RegisterPage.d.ts +1 -1
  34. package/dist/console/auth/RegisterPage.js +23 -3
  35. package/dist/console/cloud-connection/CloudConnectionPanel.d.ts +1 -0
  36. package/dist/console/cloud-connection/CloudConnectionPanel.js +169 -0
  37. package/dist/console/home/AppCard.d.ts +1 -1
  38. package/dist/console/home/AppCard.js +6 -12
  39. package/dist/console/home/HomeAppsStrip.d.ts +8 -0
  40. package/dist/console/home/HomeAppsStrip.js +61 -0
  41. package/dist/console/home/HomeLayout.d.ts +1 -1
  42. package/dist/console/home/HomeLayout.js +3 -1
  43. package/dist/console/home/HomePage.d.ts +1 -2
  44. package/dist/console/home/HomePage.js +149 -21
  45. package/dist/console/home/HomeRail.d.ts +22 -0
  46. package/dist/console/home/HomeRail.js +62 -0
  47. package/dist/console/home/QuickActions.d.ts +1 -1
  48. package/dist/console/home/QuickActions.js +3 -11
  49. package/dist/console/home/RecentApps.d.ts +1 -1
  50. package/dist/console/home/RecentApps.js +2 -2
  51. package/dist/console/home/StarredApps.d.ts +1 -1
  52. package/dist/console/home/StarredApps.js +2 -2
  53. package/dist/console/marketplace/InstalledListWidget.d.ts +1 -0
  54. package/dist/console/marketplace/InstalledListWidget.js +93 -0
  55. package/dist/console/marketplace/MarkdownText.d.ts +1 -1
  56. package/dist/console/marketplace/MarketplaceAccessDenied.d.ts +1 -1
  57. package/dist/console/marketplace/MarketplaceInstalledPage.d.ts +8 -14
  58. package/dist/console/marketplace/MarketplaceInstalledPage.js +14 -66
  59. package/dist/console/marketplace/MarketplacePackagePage.d.ts +1 -1
  60. package/dist/console/marketplace/MarketplacePackagePage.js +249 -8
  61. package/dist/console/marketplace/MarketplacePage.d.ts +1 -1
  62. package/dist/console/marketplace/MarketplacePage.js +60 -3
  63. package/dist/console/marketplace/PackageIcon.d.ts +1 -1
  64. package/dist/console/marketplace/PluginDisclosure.d.ts +14 -0
  65. package/dist/console/marketplace/PluginDisclosure.js +38 -0
  66. package/dist/console/marketplace/marketplaceApi.d.ts +123 -0
  67. package/dist/console/marketplace/marketplaceApi.js +254 -1
  68. package/dist/console/organizations/CreateWorkspaceDialog.d.ts +1 -1
  69. package/dist/console/organizations/OrganizationsLayout.d.ts +1 -1
  70. package/dist/console/organizations/OrganizationsPage.d.ts +1 -1
  71. package/dist/console/organizations/manage/AcceptInvitationPage.d.ts +1 -1
  72. package/dist/console/organizations/manage/InvitationsPage.d.ts +1 -1
  73. package/dist/console/organizations/manage/InviteMemberDialog.d.ts +1 -1
  74. package/dist/console/organizations/manage/MembersPage.d.ts +1 -1
  75. package/dist/console/organizations/manage/OrganizationLayout.d.ts +1 -1
  76. package/dist/console/organizations/manage/SettingsPage.d.ts +1 -1
  77. package/dist/context/CommandPaletteProvider.d.ts +44 -0
  78. package/dist/context/CommandPaletteProvider.js +71 -0
  79. package/dist/context/FavoritesProvider.d.ts +1 -1
  80. package/dist/context/NavigationContext.d.ts +1 -1
  81. package/dist/context/RecentItemsProvider.d.ts +2 -2
  82. package/dist/context/UserStateAdapters.d.ts +1 -1
  83. package/dist/context/index.d.ts +2 -0
  84. package/dist/context/index.js +1 -0
  85. package/dist/hooks/index.d.ts +5 -2
  86. package/dist/hooks/index.js +4 -1
  87. package/dist/hooks/useActionModal.d.ts +53 -0
  88. package/dist/hooks/useActionModal.js +111 -0
  89. package/dist/hooks/useChatConversation.d.ts +137 -4
  90. package/dist/hooks/useChatConversation.js +316 -25
  91. package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
  92. package/dist/hooks/useConsoleActionRuntime.js +564 -0
  93. package/dist/hooks/useConversationList.js +61 -3
  94. package/dist/hooks/useHomeInbox.d.ts +13 -0
  95. package/dist/hooks/useHomeInbox.js +142 -0
  96. package/dist/hooks/useNavPins.js +17 -23
  97. package/dist/hooks/useNavigationSync.d.ts +33 -0
  98. package/dist/hooks/useNavigationSync.js +98 -12
  99. package/dist/hooks/useReconcileOnError.d.ts +40 -0
  100. package/dist/hooks/useReconcileOnError.js +37 -0
  101. package/dist/hooks/useRecordApprovals.d.ts +18 -19
  102. package/dist/hooks/useRecordApprovals.js +24 -40
  103. package/dist/hooks/useResponsiveSidebar.js +14 -5
  104. package/dist/hooks/useSettleSignal.d.ts +19 -0
  105. package/dist/hooks/useSettleSignal.js +20 -0
  106. package/dist/hooks/useTrackRouteAsRecent.js +35 -0
  107. package/dist/hooks/useUrlOverlay.d.ts +62 -0
  108. package/dist/hooks/useUrlOverlay.js +88 -0
  109. package/dist/index.d.ts +18 -8
  110. package/dist/index.js +17 -5
  111. package/dist/layout/ActivityFeed.d.ts +1 -1
  112. package/dist/layout/AppHeader.d.ts +3 -2
  113. package/dist/layout/AppHeader.js +237 -72
  114. package/dist/layout/AppSidebar.d.ts +2 -1
  115. package/dist/layout/AppSidebar.js +26 -46
  116. package/dist/layout/AppSwitcher.d.ts +2 -1
  117. package/dist/layout/AppSwitcher.js +9 -5
  118. package/dist/layout/AuthPageLayout.d.ts +1 -1
  119. package/dist/layout/ConnectionStatus.d.ts +1 -1
  120. package/dist/layout/ConnectionStatus.js +9 -6
  121. package/dist/layout/ConsoleChatbotFab.d.ts +19 -1
  122. package/dist/layout/ConsoleChatbotFab.js +16 -2
  123. package/dist/layout/ConsoleFloatingChatbot.d.ts +34 -2
  124. package/dist/layout/ConsoleFloatingChatbot.js +391 -41
  125. package/dist/layout/ConsoleLayout.d.ts +1 -1
  126. package/dist/layout/ConsoleLayout.js +27 -11
  127. package/dist/layout/ContextSelectors.d.ts +44 -0
  128. package/dist/layout/ContextSelectors.js +242 -0
  129. package/dist/layout/InboxPopover.d.ts +6 -1
  130. package/dist/layout/InboxPopover.js +25 -6
  131. package/dist/layout/LocaleSwitcher.d.ts +1 -1
  132. package/dist/layout/LocalizedSidebarTrigger.d.ts +2 -0
  133. package/dist/layout/LocalizedSidebarTrigger.js +15 -0
  134. package/dist/layout/MobileViewSwitcherContext.d.ts +1 -1
  135. package/dist/layout/ModeToggle.d.ts +1 -1
  136. package/dist/layout/PageHeader.d.ts +1 -1
  137. package/dist/layout/UnifiedSidebar.d.ts +2 -1
  138. package/dist/layout/UnifiedSidebar.js +116 -15
  139. package/dist/layout/agentPicker.d.ts +56 -0
  140. package/dist/layout/agentPicker.js +40 -0
  141. package/dist/observability/index.d.ts +1 -0
  142. package/dist/observability/index.js +1 -0
  143. package/dist/observability/settleSignal.d.ts +64 -0
  144. package/dist/observability/settleSignal.js +131 -0
  145. package/dist/preview/CommitTimeline.d.ts +15 -0
  146. package/dist/preview/CommitTimeline.js +82 -0
  147. package/dist/preview/DraftChangesPanel.d.ts +19 -0
  148. package/dist/preview/DraftChangesPanel.js +114 -0
  149. package/dist/preview/DraftPreviewBar.d.ts +8 -0
  150. package/dist/preview/DraftPreviewBar.js +86 -0
  151. package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
  152. package/dist/preview/PreviewDraftEmptyState.js +47 -0
  153. package/dist/preview/PreviewModeContext.d.ts +57 -0
  154. package/dist/preview/PreviewModeContext.js +99 -0
  155. package/dist/preview/UnpublishedAppBar.d.ts +8 -0
  156. package/dist/preview/UnpublishedAppBar.js +83 -0
  157. package/dist/preview/commitHistory.d.ts +28 -0
  158. package/dist/preview/commitHistory.js +48 -0
  159. package/dist/preview/draftStatus.d.ts +20 -0
  160. package/dist/preview/draftStatus.js +27 -0
  161. package/dist/preview/usePublishAllDrafts.d.ts +18 -0
  162. package/dist/preview/usePublishAllDrafts.js +106 -0
  163. package/dist/providers/AdapterProvider.d.ts +1 -1
  164. package/dist/providers/AdapterProvider.js +6 -1
  165. package/dist/providers/ExpressionProvider.d.ts +1 -1
  166. package/dist/providers/MetadataProvider.d.ts +17 -2
  167. package/dist/providers/MetadataProvider.js +192 -12
  168. package/dist/runtime-config.d.ts +46 -2
  169. package/dist/runtime-config.js +39 -2
  170. package/dist/services/builtinComponents.js +68 -59
  171. package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
  172. package/dist/skeletons/SkeletonDetail.d.ts +1 -1
  173. package/dist/skeletons/SkeletonGrid.d.ts +1 -1
  174. package/dist/utils/appRoute.d.ts +21 -0
  175. package/dist/utils/appRoute.js +25 -0
  176. package/dist/utils/deriveRelatedLists.d.ts +54 -0
  177. package/dist/utils/deriveRelatedLists.js +91 -0
  178. package/dist/utils/index.d.ts +4 -0
  179. package/dist/utils/index.js +3 -0
  180. package/dist/utils/managedByEmptyState.d.ts +8 -1
  181. package/dist/utils/managedByEmptyState.js +13 -7
  182. package/dist/utils/preferLocal.d.ts +18 -0
  183. package/dist/utils/preferLocal.js +24 -0
  184. package/dist/views/ActionConfirmDialog.d.ts +1 -1
  185. package/dist/views/ActionConfirmDialog.js +3 -1
  186. package/dist/views/ActionParamDialog.d.ts +6 -1
  187. package/dist/views/ActionParamDialog.js +9 -3
  188. package/dist/views/ActionResultDialog.d.ts +13 -0
  189. package/dist/views/ActionResultDialog.js +134 -0
  190. package/dist/views/ComponentNavView.d.ts +14 -1
  191. package/dist/views/CreateViewDialog.d.ts +1 -1
  192. package/dist/views/DashboardConfigPanel.d.ts +28 -0
  193. package/dist/views/DashboardConfigPanel.js +81 -0
  194. package/dist/views/DashboardView.d.ts +4 -3
  195. package/dist/views/DashboardView.js +38 -239
  196. package/dist/views/FlowRunner.d.ts +31 -0
  197. package/dist/views/FlowRunner.js +121 -0
  198. package/dist/views/InterfaceListPage.d.ts +49 -0
  199. package/dist/views/InterfaceListPage.js +347 -0
  200. package/dist/views/MetadataInspector.d.ts +2 -2
  201. package/dist/views/ObjectView.d.ts +1 -1
  202. package/dist/views/ObjectView.js +209 -532
  203. package/dist/views/PageView.d.ts +8 -3
  204. package/dist/views/PageView.js +45 -32
  205. package/dist/views/RecordDetailView.d.ts +1 -1
  206. package/dist/views/RecordDetailView.js +363 -148
  207. package/dist/views/RecordFormPage.d.ts +1 -1
  208. package/dist/views/RecordFormPage.js +26 -1
  209. package/dist/views/ReportConfigPanel.d.ts +37 -0
  210. package/dist/views/ReportConfigPanel.js +85 -0
  211. package/dist/views/ReportView.d.ts +1 -1
  212. package/dist/views/ReportView.js +116 -7
  213. package/dist/views/RuntimeDraftBar.d.ts +30 -0
  214. package/dist/views/RuntimeDraftBar.js +112 -0
  215. package/dist/views/ScreenView.d.ts +70 -0
  216. package/dist/views/ScreenView.js +73 -0
  217. package/dist/views/SearchResultsPage.d.ts +1 -1
  218. package/dist/views/SearchResultsPage.js +8 -18
  219. package/dist/views/ViewConfigPanel.d.ts +24 -17
  220. package/dist/views/ViewConfigPanel.js +121 -77
  221. package/dist/views/index.d.ts +1 -1
  222. package/dist/views/index.js +1 -1
  223. package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
  224. package/dist/views/metadata-admin/AuditPanel.js +79 -0
  225. package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
  226. package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
  227. package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
  228. package/dist/views/metadata-admin/DirectoryPage.js +101 -24
  229. package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
  230. package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
  231. package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
  232. package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
  233. package/dist/views/metadata-admin/JsonSourceEditor.d.ts +39 -0
  234. package/dist/views/metadata-admin/JsonSourceEditor.js +196 -0
  235. package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
  236. package/dist/views/metadata-admin/LayeredDiff.js +171 -5
  237. package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
  238. package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
  239. package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
  240. package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
  241. package/dist/views/metadata-admin/PackagesPage.js +403 -0
  242. package/dist/views/metadata-admin/PageShell.d.ts +1 -1
  243. package/dist/views/metadata-admin/PageShell.js +9 -4
  244. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
  245. package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
  246. package/dist/views/metadata-admin/QuickFind.js +6 -3
  247. package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
  248. package/dist/views/metadata-admin/RelatedPanel.js +20 -18
  249. package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
  250. package/dist/views/metadata-admin/ResourceEditPage.js +1250 -60
  251. package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
  252. package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
  253. package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
  254. package/dist/views/metadata-admin/ResourceListPage.js +258 -30
  255. package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
  256. package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
  257. package/dist/views/metadata-admin/SchemaForm.js +559 -49
  258. package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
  259. package/dist/views/metadata-admin/StudioHomePage.js +205 -0
  260. package/dist/views/metadata-admin/anchors.js +255 -24
  261. package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
  262. package/dist/views/metadata-admin/clientValidation.js +169 -0
  263. package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
  264. package/dist/views/metadata-admin/color-variant-field.js +38 -0
  265. package/dist/views/metadata-admin/createDerive.d.ts +75 -0
  266. package/dist/views/metadata-admin/createDerive.js +179 -0
  267. package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
  268. package/dist/views/metadata-admin/dashboard-schema.js +80 -0
  269. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
  270. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
  271. package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
  272. package/dist/views/metadata-admin/datasource/register.js +24 -0
  273. package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
  274. package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
  275. package/dist/views/metadata-admin/default-schemas.js +115 -10
  276. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
  277. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
  278. package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
  279. package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
  280. package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
  281. package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
  282. package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
  283. package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
  284. package/dist/views/metadata-admin/external/api.d.ts +100 -0
  285. package/dist/views/metadata-admin/external/api.js +124 -0
  286. package/dist/views/metadata-admin/i18n.d.ts +1 -0
  287. package/dist/views/metadata-admin/i18n.js +1252 -2
  288. package/dist/views/metadata-admin/index.d.ts +8 -5
  289. package/dist/views/metadata-admin/index.js +12 -2
  290. package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
  291. package/dist/views/metadata-admin/inspector-registry.js +11 -0
  292. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
  293. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
  294. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
  295. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
  296. package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
  297. package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
  298. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
  299. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
  300. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
  301. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
  302. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
  303. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +221 -0
  304. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
  305. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +126 -0
  306. package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
  307. package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
  308. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
  309. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
  310. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
  311. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
  312. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
  313. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +205 -0
  314. package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
  315. package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
  316. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
  317. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
  318. package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
  319. package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
  320. package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
  321. package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
  322. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
  323. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +55 -0
  324. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
  325. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +365 -0
  326. package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
  327. package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
  328. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
  329. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +218 -0
  330. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
  331. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
  332. package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
  333. package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
  334. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
  335. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
  336. package/dist/views/metadata-admin/inspectors/_shared.d.ts +128 -0
  337. package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
  338. package/dist/views/metadata-admin/inspectors/datasetFilterCondition.d.ts +24 -0
  339. package/dist/views/metadata-admin/inspectors/datasetFilterCondition.js +97 -0
  340. package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
  341. package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
  342. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
  343. package/dist/views/metadata-admin/inspectors/flow-node-config.js +506 -0
  344. package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
  345. package/dist/views/metadata-admin/inspectors/index.js +45 -0
  346. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
  347. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
  348. package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
  349. package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
  350. package/dist/views/metadata-admin/issuePath.d.ts +22 -0
  351. package/dist/views/metadata-admin/issuePath.js +65 -0
  352. package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
  353. package/dist/views/metadata-admin/mergeServerFields.js +56 -0
  354. package/dist/views/metadata-admin/package-scope.d.ts +26 -0
  355. package/dist/views/metadata-admin/package-scope.js +43 -0
  356. package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
  357. package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
  358. package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
  359. package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
  360. package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
  361. package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
  362. package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
  363. package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
  364. package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
  365. package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
  366. package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
  367. package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
  368. package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
  369. package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
  370. package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
  371. package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
  372. package/dist/views/metadata-admin/previews/DatasetPreview.js +105 -0
  373. package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
  374. package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
  375. package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
  376. package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
  377. package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
  378. package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
  379. package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
  380. package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +49 -0
  381. package/dist/views/metadata-admin/previews/FlowCanvas.js +416 -0
  382. package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
  383. package/dist/views/metadata-admin/previews/FlowPreview.js +120 -0
  384. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
  385. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
  386. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
  387. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +204 -0
  388. package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
  389. package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
  390. package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
  391. package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
  392. package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
  393. package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
  394. package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
  395. package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
  396. package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
  397. package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
  398. package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
  399. package/dist/views/metadata-admin/previews/PagePreview.js +200 -5
  400. package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
  401. package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
  402. package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
  403. package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
  404. package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
  405. package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
  406. package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
  407. package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
  408. package/dist/views/metadata-admin/previews/ScreenPreview.d.ts +38 -0
  409. package/dist/views/metadata-admin/previews/ScreenPreview.js +61 -0
  410. package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
  411. package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
  412. package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
  413. package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
  414. package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
  415. package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
  416. package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
  417. package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
  418. package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
  419. package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
  420. package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
  421. package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
  422. package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
  423. package/dist/views/metadata-admin/previews/block-config.js +324 -0
  424. package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
  425. package/dist/views/metadata-admin/previews/block-types.js +110 -0
  426. package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
  427. package/dist/views/metadata-admin/previews/field-types.js +97 -0
  428. package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +102 -0
  429. package/dist/views/metadata-admin/previews/flow-canvas-layout.js +227 -0
  430. package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +96 -0
  431. package/dist/views/metadata-admin/previews/flow-canvas-parts.js +373 -0
  432. package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
  433. package/dist/views/metadata-admin/previews/form-preview.js +29 -0
  434. package/dist/views/metadata-admin/previews/index.js +43 -0
  435. package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
  436. package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
  437. package/dist/views/metadata-admin/previews/object-fields-io.d.ts +130 -0
  438. package/dist/views/metadata-admin/previews/object-fields-io.js +243 -0
  439. package/dist/views/metadata-admin/previews/screen-spec.d.ts +43 -0
  440. package/dist/views/metadata-admin/previews/screen-spec.js +108 -0
  441. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +102 -0
  442. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
  443. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +15 -0
  444. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +185 -0
  445. package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +73 -0
  446. package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +426 -0
  447. package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
  448. package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
  449. package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
  450. package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
  451. package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
  452. package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
  453. package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
  454. package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
  455. package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
  456. package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
  457. package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
  458. package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
  459. package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
  460. package/dist/views/metadata-admin/previews/widget-types.js +40 -0
  461. package/dist/views/metadata-admin/registry.d.ts +140 -19
  462. package/dist/views/metadata-admin/report-schema.d.ts +26 -0
  463. package/dist/views/metadata-admin/report-schema.js +121 -0
  464. package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
  465. package/dist/views/metadata-admin/useMetadata.js +155 -4
  466. package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
  467. package/dist/views/metadata-admin/view-item-normalize.js +68 -0
  468. package/dist/views/metadata-admin/view-schema.d.ts +16 -0
  469. package/dist/views/metadata-admin/view-schema.js +107 -0
  470. package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
  471. package/dist/views/metadata-admin/view-variant-model.js +64 -0
  472. package/dist/views/metadata-admin/widgets.d.ts +89 -1
  473. package/dist/views/metadata-admin/widgets.js +491 -17
  474. package/dist/views/runtime-metadata-persistence.d.ts +78 -0
  475. package/dist/views/runtime-metadata-persistence.js +89 -0
  476. package/dist/views/useOpenRecordList.d.ts +18 -0
  477. package/dist/views/useOpenRecordList.js +36 -0
  478. package/dist/views/userFilterUrlState.d.ts +15 -0
  479. package/dist/views/userFilterUrlState.js +53 -0
  480. package/dist/views/view-config-adapter.d.ts +38 -0
  481. package/dist/views/view-config-adapter.js +80 -0
  482. package/package.json +52 -34
  483. package/dist/views/DesignDrawer.d.ts +0 -28
  484. package/dist/views/DesignDrawer.js +0 -51
  485. package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
  486. package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
package/CHANGELOG.md CHANGED
@@ -1,5 +1,1234 @@
1
1
  # @object-ui/app-shell — Changelog
2
2
 
3
+ ## 7.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7b5d0f0: Build-history timeline + revert UI for AI builds (ADR-0067)
8
+
9
+ The unpublished-app banner gains a **History** button that opens a commit timeline (`GET /packages/:id/commits`): every change an AI build/edit landed, newest-first, with **Revert** per apply commit (`POST /packages/:id/commits/:cid/revert`). The history-not-confirm model — review the timeline and revert, instead of approving each publish.
10
+
11
+ - `commitHistory.ts` — `fetchCommits` / `revertCommit` helpers.
12
+ - `CommitTimeline.tsx` — slide-over panel (sibling of `DraftChangesPanel`).
13
+ - `UnpublishedAppBar` — History button + timeline mount (package-scoped).
14
+
15
+ - 7cd950e: feat(metadata-admin): dataset create opens the rich designer + dual-axis preview
16
+
17
+ - **Create → rich designer.** `dataset` joins `object` / `report` in
18
+ `CREATE_MODE_CANVAS_TYPES`, so "New dataset" opens the structured designer
19
+ (base-object picker, joins, dimension/measure editors, live preview) instead
20
+ of the degraded generic SchemaForm. `DatasetDefaultInspector` gains a
21
+ create-mode **Name** field that auto-derives a snake_case identifier from the
22
+ label until edited (mirrors `ReportDefaultInspector` / `ObjectDefaultInspector`),
23
+ so a dataset created through the canvas saves with a valid identity instead of
24
+ dead-ending.
25
+ - **Mixed-scale preview.** When a dataset preview mixes a ratio/percent measure
26
+ (e.g. `utilization`, `0.0%`) with magnitude measures (currency in the
27
+ hundred-thousands), the ratio measures now plot as a line on a secondary
28
+ (right) Y axis via the existing `combo` chart — they're no longer crushed to an
29
+ invisible sliver beside the large bars. Same-scale selections stay a plain bar
30
+ chart.
31
+
32
+ - fccebfe: feat(metadata-admin): visual filter authoring in the dataset designer
33
+
34
+ The dataset designer gains a visual filter editor (reusing the shared
35
+ `FilterBuilder`) for both the dataset-level **Scope filter** (`dataset.filter`)
36
+ and per-measure **Filter** (`measure.filter`) — previously only settable via the
37
+ raw Source/JSON tab. Both are backed by real runtime: the analytics executor ANDs
38
+ the scope filter into every query and runs measure-scoped filters as supplementary
39
+ grouped queries, so e.g. `won_amount = sum(amount) where stage = won` and an
40
+ "exclude archived" dataset scope are now authorable without hand-writing JSON.
41
+
42
+ A small, unit-tested converter bridges the builder's flat `{field, op, value}`
43
+ group ⇄ the spec `FilterCondition` (Mongo-style `$and` / `$op`). Conditions it
44
+ can't faithfully round-trip (nested groups, `$or`, multi-operator objects) are
45
+ detected and shown as "edit in Source" rather than being silently rewritten.
46
+
47
+ - 0acf0c8: feat(metadata-admin): friendlier + safer dataset measure authoring
48
+
49
+ The `dataset` designer's measure editor gets three improvements so a business
50
+ user can author measures without spec knowledge and without saving a broken
51
+ dataset:
52
+
53
+ - **Display-format picker** — replaces the raw `format` / `currency` numeral
54
+ text inputs with a structured Kind (Raw / Number / Currency / Percent) +
55
+ Decimals + Currency selection and a live sample (e.g. `US$1,234.50`). Parses
56
+ an existing format string back into the picker, so editing an existing measure
57
+ round-trips.
58
+ - **Auto-name from field** — picking a dimension/measure field when the row is
59
+ still unnamed defaults the name to the field's leaf (`account.region` →
60
+ `region`).
61
+ - **Author-time validation** — a `relationship.field` dimension/measure whose
62
+ relationship isn't in `include` now shows an inline warning with a one-click
63
+ "Add it", catching at design time the "relationship not declared in include"
64
+ error that previously only surfaced when the live preview query ran. A derived
65
+ measure with too few operands is flagged too.
66
+
67
+ - 3e1fcf5: feat(chatbot): reveal the Build/Ask switcher in the app floating assistant when AI dev is unlocked
68
+
69
+ The bottom-right FAB assistant bound each app to a single agent and hid the
70
+ agent picker unless `VITE_AI_SHOW_AGENT_PICKER` was set, so a user on an
71
+ AI-unlocked environment could not switch from `ask` (read-only data/query) to
72
+ `build` (authoring) without leaving for the full `/ai` page.
73
+
74
+ The picker now auto-reveals when AI development is unlocked for the viewer — the
75
+ live agent catalog serves BOTH an `ask` and a `build` agent (alias-aware, so
76
+ legacy `data_chat`/`metadata_assistant` count) AND authoring isn't
77
+ deployment-disabled (`aiStudio`). Pure end-user apps (only `ask`) stay clean and
78
+ never see a picker. An explicit `showAgentPicker` prop or
79
+ `VITE_AI_SHOW_AGENT_PICKER` still forces it on.
80
+
81
+ - e2b0072: Flow builder: live preview for Screen nodes (#1944)
82
+
83
+ Screen-flow nodes were authored blind — there was no way to see the form an end user would get, and the Debug simulator showed only `paused` when it reached a screen. Add a live preview that renders the screen exactly as it runs.
84
+
85
+ The runtime `FlowRunner`'s screen body (flat input fields + object-form mode) is extracted into a shared `ScreenView`, so the preview reuses the **same** renderer as runtime and can't drift (the design↔runtime divergence #1927 fixed). A new `ScreenPreview` builds a `ScreenSpec` from the node's authored `config` and feeds it to `ScreenView`.
86
+
87
+ - Reflects `title`, `description` (with `{var}` interpolation), input `fields`, and object-form mode (`objectName` / `mode` / `defaults`, rendered via `plugin-form`'s `ObjectForm`).
88
+ - Updates live as the node config changes.
89
+ - Two homes: the **flow node inspector** (interpolates against the flow's declared variable defaults) and the **Debug simulator** when paused at a screen (interpolates against the live simulated run state, replacing the bare `paused`).
90
+
91
+ - 780cabc: feat(studio): add a "Local / Custom (this env)" scope to the package selector
92
+
93
+ In a self-hosted, metadata-customizable environment (single-tenant — no org
94
+ dimension), the package selector only listed code packages, so metadata authored
95
+ at runtime (`package_id = null` / `sys_metadata` provenance) was filtered out of
96
+ every code-package view and became un-navigable — opening such an item redirected
97
+ to "new". This complements framework #2252 + objectui #1937, which stop runtime
98
+ metadata from being stamped into a loaded code package and keep it editable.
99
+
100
+ - Surface a stable, always-present "Local / Custom (this env)" entry in the
101
+ Studio package context-selector (`ContextSelectors`), mapped to the
102
+ `sys_metadata` scope the metadata list/get API already understands.
103
+ - Accept that scope in the metadata-admin pages (`StudioHomePage`,
104
+ `DirectoryPage`, `ResourceListPage`) via a shared `buildPackageScopeOptions`
105
+ helper, so it no longer redirects, and the list shows this environment's
106
+ runtime-authored items (`package_id = null`).
107
+ - On the Studio home grid, the Local scope shows every runtime-creatable type so
108
+ the user can start authoring locally even with zero items yet.
109
+
110
+ - 93cf2b1: feat(studio): preview record pages against a real sample record
111
+
112
+ The Studio page editor's Preview tab rendered a `type: 'record'` page's
113
+ `record:*` blocks (details / highlights / path / alert / quick_actions) as the
114
+ "bind a record to preview" placeholder — the metadata editor has no record
115
+ route, so the author designed blind.
116
+
117
+ The preview now fetches a handful of real records of the bound object (with
118
+ lookup / master_detail fields `$expand`ed so they show display names, not raw
119
+ foreign-key IDs), auto-binds the first one, and wraps the canvas in a
120
+ `<RecordContextProvider>` — mirroring the runtime `RecordDetailView`. A
121
+ "Preview record" dropdown lets the author switch records, so `visible` CEL
122
+ expressions (e.g. `record.status == 'in_review'`) and per-record field values
123
+ re-render live.
124
+
125
+ ### Patch Changes
126
+
127
+ - 68d82ae: New script action seeds a valid body; add create-roundtrip conformance guard
128
+
129
+ A new action defaults to `type: 'script'`, which the spec requires to carry an executable `body` or `target` — the create form seeded neither, so "New action → Save" failed validation (422). Seed a no-op L2 body in `createDefaults` so the default create round-trips. Adds a conformance guard that asserts every authorable type's default create-form output passes spec validation (catches the "designer minimal shape ≠ spec required" family before it ships).
130
+
131
+ - aae8791: Flow Screen preview: render inline master-detail subforms (follow-up to #1944)
132
+
133
+ The object-form mode of the Screen-node preview now renders inline master-detail
134
+ child grids, matching runtime. `ScreenPreview` feeds the SAME enriched object
135
+ list the runtime `FlowRunner` uses (`useMetadata().objects`, which derives
136
+ `form.subforms` from `inlineEdit` relationships via `attachInlineSubforms`), so
137
+ e.g. a `showcase_invoice` object-form step previews its **Line Items** grid
138
+ (with live Subtotal/Tax/Total) — only fetched in object-form mode.
139
+
140
+ To keep the preview non-persisting — consistent with the flat-field preview
141
+ (disabled Submit) and the simple object-form preview (no Save) — `MasterDetailForm`
142
+ now honours a `showSubmit` flag (default shown; backward-compatible) that
143
+ `ObjectForm` forwards, so the preview hides the master-detail Save bar. Also drops
144
+ a dead `e = formData` assignment in `ObjectForm` (lint `no-useless-assignment`).
145
+
146
+ - 4014bc9: Flow Screen preview: gate fields by `visibleWhen` (follow-up to #1944)
147
+
148
+ The Screen-node preview now evaluates each input field's `visibleWhen` against
149
+ the active variables — reusing the simulator's own condition evaluator
150
+ (`evalCondition`), normalising `{var}` placeholders to bare identifiers — so it
151
+ hides/shows conditional fields exactly as the runtime `screen` executor does
152
+ (which filters server-side before emitting the `ScreenSpec`).
153
+
154
+ - Debug simulator (live run state): gates faithfully, e.g. a screen whose
155
+ `opportunityName`/`opportunityAmount` are `visibleWhen: "{createOpportunity} == true"`
156
+ hides them while `createOpportunity` is false.
157
+ - Inspector (no run state): fails open — an unparseable or not-yet-decidable
158
+ condition keeps the field visible, so configured fields are never hidden on
159
+ missing data — and a footnote reports how many fields are gated out.
160
+
161
+ - d27f045: fix(metadata-admin): remove the unwired "Certified" measure toggle from the dataset designer
162
+
163
+ `measure.certified` is dead in the spec liveness ledger (declared but read by
164
+ nothing — no certifier authority, no provenance, not surfaced at point-of-use).
165
+ A self-asserted checkbox the dataset author flips on their own work isn't
166
+ certification — it's a fake trust signal. Drop the toggle (and the create
167
+ default) until real metric governance exists (separate `dataset.certify`
168
+ authority + `certifiedBy`/`certifiedAt` + a badge where reports pick measures).
169
+ The spec field stays (dormant, liveness=dead) so existing data is untouched.
170
+
171
+ - d23ed60: feat(studio): author the approval revise loop in the flow designer (ADR-0044)
172
+
173
+ The ADR-0044 send-back-for-revision loop — an approval node's `revise` out-edge to a wait point, closed by a declared `type: 'back'` edge re-entering the approval (round N+1) — was previously reachable only by hand-editing flow JSON. The flow designer now authors it visually:
174
+
175
+ - **Revise branch** — an approval out-edge offers `approve` / `reject` / `revise` via a new Approval-branch picker in the edge inspector; `maxRevisions` surfaces on the approval node's property form (from the engine's published configSchema when online, with a hardcoded fallback offline).
176
+ - **Back-edge authoring** — a new Connection-type select marks an edge as `back` (also `fault` / `conditional`). A back-edge renders distinctly on the canvas as a dashed amber return arc and is excluded from the layered auto-layout (exactly as the engine excludes it from DAG validation), so the loop reads top-to-bottom instead of dragging its target node below the wait point.
177
+ - **Client-side DAG validation** — the simulator's preflight now flags an UNmarked cycle as an error (the graph minus declared back-edges must be a DAG, mirroring `registerFlow`), while a declared revise loop passes and a self-loop is caught.
178
+ - **One-click "add revision loop"** — an amber affordance on an approval node drops the signal `wait` node + the `revise` edge + the declared `back` edge in a single gesture, reproducing the canonical `showcase_budget_approval` shape.
179
+
180
+ Refs framework#1770. Follows the flow-builder work in #1927 and #1930.
181
+
182
+ - 47c6e25: fix(studio/flow): wire decision branches to edges, expand screen config, align simulator with engine
183
+
184
+ Four fixes for the Studio Flow Builder, found dogfooding it as a business user:
185
+
186
+ - **Decision branches now route.** The "Branches" editor wrote `node.config.conditions`
187
+ but never the outgoing edges, so a decision built entirely in Studio left every
188
+ out-edge unconditional — the engine and simulator (which branch on `edge.condition`)
189
+ ran _all_ branches. Branches now mirror onto the node's out-edges (by order):
190
+ `FlowCanvas.addNode` carries the matching branch onto a newly-connected edge, and
191
+ `FlowNodeInspector` re-syncs existing edges when branches are edited (a `true`
192
+ expression marks the default/else edge).
193
+ - **Screen node config expanded.** The form exposed only `fields`; it now also edits
194
+ `title`, `description` (interpolates `{var}`), `waitForInput`, and the object-form
195
+ keys (`objectName`, `idVariable`, `mode`, `defaults`) — so a message screen or an
196
+ object-form wizard step no longer requires dropping to Advanced JSON.
197
+ - **Simulator applies assignment nodes.** Assignment was a no-op pass-through, so a
198
+ Debug run never reflected `Set variables`. It now normalizes the same shapes the
199
+ engine accepts (`assignments` map/array + flat) and interpolates `{var}`.
200
+ - **Simulator screen-pause parity.** The simulator paused on every screen; it now
201
+ pauses only when the screen collects input (`fields`) or sets `waitForInput`,
202
+ matching the engine's `shouldPause` — a field-less screen passes through.
203
+ - **Palette HTTP de-duplicated.** The base palette hardcoded the deprecated
204
+ `http_request` alias while the engine publishes the canonical `http`, showing
205
+ two HTTP entries. The base now uses `http` (merging into one), aliased to the
206
+ `http_request` config form so the inspector is unchanged.
207
+
208
+ - 4c2f910: feat(studio): surface flow validation errors inline on the canvas
209
+
210
+ The flow designer's structural validation (an un-declared cycle, missing entry node, duplicate ids, dangling edges, …) was only visible in the Debug panel. It now surfaces **inline on the canvas**: an un-declared cycle paints its offending edges + nodes red — using the same `validateFlowDraft` the simulator preflight runs — and an error banner lists the messages, so the author sees a broken graph without opening Debug. Each edge that closes the cycle carries a tooltip pointing at the fix ("mark the edge that closes the loop as a back-edge"). A declared revise loop (ADR-0044 back-edge) is excluded from cycle detection and stays un-flagged.
211
+
212
+ Follows #1954 (revise-loop authoring) and #1955 (simulating approval decisions).
213
+
214
+ - 1b3ccd1: feat(studio): simulate approval decisions in the flow debugger
215
+
216
+ The designer-time flow simulator treated an `approval` node as a pass-through that fanned out to every out-edge at once — so an ADR-0044 revise loop couldn't be debugged: it walked approve / reject / revise simultaneously and hit the step ceiling on the back-edge.
217
+
218
+ The simulator now models an approval as a durable pause (like `wait` / `screen`): it suspends at the node, and the Debug panel offers the node's out-edge labels (`approve` / `reject` / `revise`) as decision buttons. Resuming routes down ONLY the chosen branch — mirroring how the engine resumes a suspended approval by branch label — so a full revise loop is now walkable in the debugger: revise → wait → resubmit (back-edge) → round 2 → approve. An unmatched decision falls back to fanning out (mirroring the engine's label-fallback), logged so the author notices.
219
+
220
+ Follows #1954 (ADR-0044 revise-loop authoring).
221
+
222
+ - 05584aa: feat(studio/flow): context-aware Start trigger fields + explicit decision-branch binding
223
+
224
+ Two flow-builder UX improvements (follow-ups to the decision/screen/simulator fixes in #1927):
225
+
226
+ - **Start node trigger fields are now context-aware.** The Start node showed `Object`
227
+ and `Entry condition` (record-trigger config) even on screen / manual flows where
228
+ they don't apply. They're now gated by the chosen `triggerType` — shown for record /
229
+ schedule / webhook / event triggers, hidden for manual / unset (screen wizards). A
230
+ field that already holds a value is never hidden, so existing flows are unaffected.
231
+ - **Decision branches can be bound to edges explicitly.** Selecting a decision out-edge
232
+ now shows a **Branch** picker listing the source decision's branches (label · condition,
233
+ or "· default"). Picking one writes that branch's expression / label (or marks the
234
+ default) onto the edge — so routing stays correct even when edges are connected out of
235
+ branch order, instead of relying solely on the implicit by-order auto-wire. A
236
+ "— Custom —" option preserves manual editing.
237
+
238
+ Adds `flow-node-config.test.ts` covering the trigger-field gating.
239
+
240
+ - 44d4582: fix(studio): localize lookup picker config + keep published org objects editable
241
+
242
+ - The lookup field's "Picker config" sub-panel (display/description field,
243
+ selectable-records filters, depends-on, page size, quick-create) was
244
+ hard-coded English in an otherwise-Chinese designer. Routed every literal
245
+ through `t()`/`tFormat()` with new `designer.field.lookup.*` keys (en + zh).
246
+ - A freshly-published org object read back as read-only: after publish its
247
+ active version surfaces in the layered `code` slot tagged with the
248
+ `sys_metadata` provenance sentinel, and `ResourceEditPage` treated any
249
+ non-null `code` as a packaged artifact (needs `allowOrgOverride`, which the
250
+ `object` type lacks). Mirror the server's `isArtifactBacked` — which excludes
251
+ `_packageId === 'sys_metadata'` — so org-authored items stay editable.
252
+
253
+ - b419a7c: fix(studio): enable report authoring (create flow, chart render, dataset-aware inspector)
254
+
255
+ Found dogfooding report design in Studio as a business user — you could not create a report at all, plus several follow-on gaps.
256
+
257
+ - **Report create now uses the canvas + `ReportDefaultInspector`.** Only `object` was in `CREATE_MODE_CANVAS_TYPES`, so report-create fell back to a stale name-first form whose create-config (`objectName`, `columns: []`) predates the ADR-0021 dataset-bound model — saving failed server validation (_"a report needs `dataset` + `values`"_) with no field to fix it. Add `'report'` to the canvas set; the inspector exposes an auto-derived snake_case Name in create mode; fix the create-config (drop `objectName`/`columns`, seed `type: 'summary'` + `drilldown: true`).
258
+ - **Preserve `?package=` on post-create navigation** — it was dropped, so the editor reloaded a blank draft in the user's default package.
259
+ - **Render a report's embedded `chart`** in `DatasetReportRenderer` (authorable in Studio but never rendered) via the lazily-registered generic chart component; requests a non-animated render for export/background-tab safety.
260
+ - **Dedicated Chart panel in the inspector** — chart type + dataset-aware X-Axis (dimension) / Y-Axis (measure) dropdowns + title, replacing free-text axis fields and the vague "Chart: Required text value" validation.
261
+
262
+ - 15f140d: Validation messages name the offending widget + field
263
+
264
+ A nested Zod issue (e.g. `widgets.2.layout`) was shown as just its head field label — "Widgets: Invalid input" — so an author couldn't tell which widget or sub-field was at fault. `labelForIssuePath` now appends a readable trail, resolving each array index to the item's stable identity (id/name/title, incl. I18nLabel objects) from the draft: "Widgets → priority_split → layout". Single-segment paths are unchanged.
265
+
266
+ - Updated dependencies [677f7ed]
267
+ - Updated dependencies [08c47da]
268
+ - Updated dependencies [a71be60]
269
+ - Updated dependencies [cb03bc3]
270
+ - @object-ui/types@7.1.0
271
+ - @object-ui/core@7.1.0
272
+ - @object-ui/react@7.1.0
273
+ - @object-ui/auth@7.1.0
274
+ - @object-ui/collaboration@7.1.0
275
+ - @object-ui/components@7.1.0
276
+ - @object-ui/data-objectstack@7.1.0
277
+ - @object-ui/fields@7.1.0
278
+ - @object-ui/layout@7.1.0
279
+ - @object-ui/permissions@7.1.0
280
+ - @object-ui/plugin-editor@7.1.0
281
+ - @object-ui/providers@7.1.0
282
+ - @object-ui/i18n@7.1.0
283
+
284
+ ## 7.0.0
285
+
286
+ ### Minor Changes
287
+
288
+ - a00e16d: feat: evaluate CEL `disabled` on action buttons + record-page Undo wiring
289
+
290
+ - **components (page header)**: the `record_header` action toolbar now evaluates
291
+ a CEL `disabled` predicate against the record (boolean was the only honoured
292
+ form before), mirroring its existing `visible` evaluation. An action can now
293
+ grey out conditionally (e.g. "Reassign" on a converted lead) instead of only
294
+ hiding via `visible`.
295
+ - **plugin-grid (row menu)**: `RowActionMenu` items likewise evaluate `disabled`
296
+ (boolean or CEL against the row), and skip the click when disabled.
297
+ - **components (action-button)**: forward `undoable` / `recordIdField` when
298
+ executing, so undoable update actions keep their Undo affordance through the
299
+ `action:button` path.
300
+ - **app-shell (RecordDetailView)**: mount `useGlobalUndo` and wire the record
301
+ action runtime's success toast to offer "Undo" for `undoable` actions
302
+ (capturing the changed fields' prior values from the loaded record).
303
+ - **plugin-detail (record:quick_actions)**: the widget's buttons now evaluate a
304
+ CEL `disabled` and show a spinner + disable while running.
305
+
306
+ - 11ef5e3: Action modal transport with placement (SDUI opt #2).
307
+
308
+ `useActionModal` provides a reusable `onModal` handler that renders an action's modal envelope in the right container by `placement`: `center` (Dialog), `side` (Sheet), `bottom` (Drawer), `fullscreen`. `content` is an arbitrary SchemaNode rendered via `SchemaRenderer`, so a modal action can open any page/form/list; string targets / `{objectName, mode}` keep opening a `ModalForm`. Wired into `RecordDetailView` so `type:'modal'` actions open client-side (previously routed to a server POST).
309
+
310
+ - f7f325d: feat: action progress state + Undo affordance
311
+
312
+ - **core**: `ActionResult.undo` (an `UndoableOperation`) and `ActionDef.undoable`.
313
+ On success the `ActionRunner` pushes the operation onto the global UndoManager
314
+ and the success toast carries an "Undo" affordance (`ToastHandler` gains an
315
+ `undo` option).
316
+ - **app-shell**: the console action runtime mounts `useGlobalUndo` (Ctrl+Z /
317
+ Ctrl+Shift+Z) and renders the toast's "Undo" button; its `apiHandler` resolves
318
+ the row id from the list row record and, for `undoable` actions, captures the
319
+ changed fields' prior values so the update can be reverted.
320
+ - **plugin-detail**: record-header quick-action buttons show a spinner + disable
321
+ while the action runs (a visible progress state for slow/flow actions).
322
+
323
+ - c12986e: Add resultDialog + target interpolation for one-shot action reveals
324
+
325
+ Some platform actions return values the user MUST copy now because the
326
+ server will not surface them again — 2FA TOTP URI + backup codes, freshly
327
+ minted OAuth client_secret, regenerated recovery codes. Previously these
328
+ had to ship as bespoke pages in `apps/account` because actions only
329
+ emitted a fire-and-forget toast.
330
+
331
+ **`@object-ui/core` — ActionRunner**
332
+
333
+ - New `ActionDef.resultDialog: ResultDialogSpec` field. When set on a
334
+ successful action, the runner suppresses the `successMessage` toast and
335
+ awaits the registered `ResultDialogHandler` instead. Missing handler is
336
+ non-fatal (logs a warning); rejected handler is treated as acknowledged.
337
+ - New `setResultDialogHandler(handler)` setter.
338
+ - New types: `ResultDialogSpec`, `ResultDialogFieldSpec`,
339
+ `ResultDialogHandler`.
340
+ - `executeUrl` and `executeAPI` now run `${param.X}` and `${ctx.X}`
341
+ interpolation against `target` before fetching / navigating. Values are
342
+ `encodeURIComponent`'d, missing keys resolve to empty string. `ctx`
343
+ exposes `origin`, `user`, `org`, `recordId` by default; consumers can
344
+ inject more via `context.ctx`.
345
+
346
+ **`@object-ui/react`**
347
+
348
+ - `ActionProvider` and `useActionRunner` both gained an `onResultDialog`
349
+ option that wires straight through to the runner.
350
+
351
+ **`@object-ui/app-shell`**
352
+
353
+ - New `ActionResultDialog` component — promise-based, blocks click-outside
354
+ and Escape (the user MUST click acknowledge), renders five field
355
+ formats: `qrcode` (client-side via the `qrcode` package — never sent
356
+ off-device, so 2FA URIs stay secret), `code-list`, `secret`, `text`,
357
+ `json`. Falls back to `json` when a value's shape doesn't match its
358
+ declared format.
359
+ - `ObjectView` and `RecordDetailView` install the handler and mount the
360
+ dialog automatically, so any action with `resultDialog` declared in
361
+ metadata now works without code changes.
362
+ - New dependency: `qrcode@^1.5.x` for client-side QR rendering.
363
+
364
+ Pairs with the framework-side `Action.resultDialog` schema added in
365
+ `@objectstack/spec` and the `sys_two_factor` / `sys_oauth_application` /
366
+ `sys_account` updates in `@objectstack/platform-objects`.
367
+
368
+ - 0c95963: ADR-0021 single-form: dataset-native report editing + legacy report surface retired.
369
+
370
+ - The Studio/runtime report inspector now edits the 9.0 dataset binding (dataset picker + values/rows selectors sourced from the dataset's semantic layer) instead of the removed objectName/columns query form.
371
+ - plugin-report: the pre-9.0 query-form renderers (SpecReportGrid, MatrixRenderer, JoinedReportRenderer), the drill helpers, and the legacy authoring components (ReportBuilder, ReportConfigPanel, ColumnsEditor, GroupingsBuilder, JoinedBlocksEditor, FieldPickerDialog, ChartConfig, ScheduleConfig) are removed. ReportRenderer dispatches dataset-bound reports to DatasetReportRenderer; stored pre-9.0 spec JSON renders through the lossy specReportToPresentation → ReportViewer bridge until migrated.
372
+
373
+ - 1c25b56: ADR-0032: author-time condition validation in the flow inspectors.
374
+
375
+ Flow node and edge condition editors now flag a malformed predicate **as you
376
+ type** — most importantly the `{record.x}` template-brace-in-CEL mistake (#1491),
377
+ which `{…}` parses as a CEL map literal and silently fails — with the same
378
+ corrective message the build and the `validate_expression` agent tool emit.
379
+ Client-side check for now (no CEL parser in the browser); swaps to
380
+ `@objectstack/formula`'s shared `validateExpression` once it is published.
381
+
382
+ - 30ee761: feat(studio): surface pending drafts on the package detail (ADR-0033)
383
+
384
+ After an AI builds an app, its objects/views land as drafts bound to the app package — but Studio's active-only browsers hid them, so the package looked empty and there was no obvious way to find what to review/publish.
385
+
386
+ - `MetadataClient.listDrafts({ packageId?, type? })` calls the new `GET /api/v1/meta/_drafts` endpoint, returning pending draft headers (with `packageId`).
387
+ - The package detail sheet (PackagesPage) now shows a **Pending changes** section listing each drafted item, each linking to the existing per-item review/diff (`?review=1`) so the user can publish it. A just-built app package is no longer shown as empty.
388
+
389
+ - 81c0777: feat(studio): ADR-0033 Phase B — draft review surface (chat → designer → generic diff)
390
+
391
+ Closes the AI metadata-authoring loop in Studio. The framework (ADR-0033 Phases A + C) makes the assistant stage every change as a DRAFT; this lets a human see and review those drafts.
392
+
393
+ **`@object-ui/plugin-chatbot`**
394
+
395
+ - `mapMessages` now detects the framework's draft envelopes — `{ status:'drafted', type, name, … }` (single) and `{ status:'drafted', drafted:[{type,name}] }` (apply_blueprint batch) — and lifts the reviewable targets onto `ChatToolInvocation.draftReview` (mirrors the existing HITL `pendingActionId` path; the Vercel `{type:'text',value}` wrapper is peeled). `blueprint_proposed` is intentionally not surfaced (no draft yet).
396
+ - `ChatbotEnhanced` renders a **"Review N change(s)"** button on drafted tool results, driven by a new `onReviewDraft` callback prop.
397
+
398
+ **`@object-ui/app-shell`**
399
+
400
+ - `assistantBus` gains a review channel (`requestReview` / `requestAssistantReview`); `ConsoleFloatingChatbot` wires the chat button to it; a small navigator inside `AppContent` (which knows the app base) routes to `/apps/:appName/metadata/:type/:name?review=1`.
401
+ - `ResourceEditPage` honours `?review=1`: it force-reloads the pending draft (covers the case where the AI drafted the item after the page mounted) and opens the review/diff.
402
+ - New **`DraftReviewPanel`** — a generic, type-agnostic draft↔published structural diff (added / changed / removed by key), reusing `LayeredDiff`'s `computeDiffRows`. It gives **every** metadata type (view, dashboard, flow, …) a real "what will publishing change" review, surfaced as a toolbar affordance + sheet whenever a draft exists. The object designer keeps its richer per-field review.
403
+
404
+ Nothing is published by any of this — the human still clicks Publish.
405
+
406
+ - 672f854: feat(studio): add "Publish app" button to publish all package drafts (ADR-0033)
407
+
408
+ The package detail's Pending changes section gains a primary **Publish app (N)** button that calls `POST /api/v1/packages/:id/publish-drafts` to promote every drafted item of the app in one shot, then refreshes the pending list. Complements the per-item review/publish links — so after an AI builds an app you can review item-by-item or publish the whole thing at once.
409
+
410
+ - 893e530: Package documentation portal + nav entry (ADR-0046).
411
+
412
+ The `/docs/:name` viewer already existed but had no way in: no index and no
413
+ navigation entry, so a doc was reachable only by typing its exact URL. Adds a
414
+ platform-level docs portal at `/docs` (`DocsIndex`) that lists every installed
415
+ `doc` metadata item grouped by package namespace, each linking to the existing
416
+ viewer. A "Documentation" entry now appears in the home/system navigation
417
+ (`UnifiedSidebar`), visible to all users (not gated behind workspace-admin), so
418
+ docs are discoverable. The viewer route stays app-independent and
419
+ single-coordinate (`/docs/<name>`); per-app deep-links remain opt-in `url` nav
420
+ items pointing at that same global URL. Doc grouping is a pure, unit-tested
421
+ helper (`groupDocsByPackage`).
422
+
423
+ - 053c948: feat: ADR-0047 — interface pages, visualization switcher, and Airtable-parity filters
424
+
425
+ End-user interface/list pages reach full rendering and authoring parity:
426
+
427
+ - **Spec tabs + visualization switcher** — `ObjectView` now forwards
428
+ `viewDef.tabs` (stored/served but never rendered) and `viewDef.appearance`
429
+ (`allowedVisualizations` whitelist), turning on the dormant `ViewSwitcher` when
430
+ more than one type is whitelisted; effective options = author whitelist ∩
431
+ capability-resolvable types (kanban needs `groupBy`, calendar a date field, …).
432
+ `ListView` accepts the canonical `ViewFilterRule[]` tab-filter shape.
433
+ - **User filters** — render only when `userFilters` is explicitly configured;
434
+ selections (dropdown values + active tab) mirror into `uf_*` URL params and
435
+ restore on load, so filtered lists survive reload and are shareable.
436
+ - **Toolbar polish** — the visualization switcher becomes a compact right-side
437
+ "Grid ▾" dropdown inside the tool cluster (no extra row); filter tabs and
438
+ dropdown filters are mutually exclusive.
439
+ - **Studio authoring** — a usable, schema-driven interface-page inspector
440
+ (collapsible sections honoured, array-of-enum → multi-select, a None/Tabs/
441
+ Dropdown `filter-mode` selector where None maps to ABSENCE of `userFilters`),
442
+ and the Design/Preview tabs render the live list via `InterfaceListPage`
443
+ (including a non-empty grid when the source view is hollow).
444
+
445
+ - 053c948: feat(app-shell): ADR-0048 (option A) — package-id app routing + prefer-local resolution
446
+
447
+ Apps are now routed by their canonical package id rather than name:
448
+
449
+ - **Resolution layer** — new `appRoute` helpers: `appRouteSegment(app)`
450
+ (canonical link segment = package id, name fallback) and
451
+ `matchAppBySegment(apps, seg)` (prefers `_packageId`, falls back to `name`).
452
+ `AppContent` selects the active app via `matchAppBySegment`, so
453
+ `/apps/<packageId>` resolves while `/apps/<appName>` keeps working (a per-tenant
454
+ alias / legacy URL).
455
+ - **Emission layer** — nav generates `/apps/<packageId>` links across app
456
+ switching (AppSwitcher/AppSidebar/CommandPalette), sidebar base paths,
457
+ create/edit-app, and the hidden-app switch, all via `appRouteSegment(app)`.
458
+ - **Prefer-local resolution** — `preferLocal(list, name, ownerPackageId)` resolves
459
+ a bare metadata name to the item whose `_packageId` matches the active app's
460
+ package (falling back to first match), wired at PageView/DashboardView/
461
+ ReportView and AppHeader so two installed packages can ship the same bare name.
462
+
463
+ - 053c948: feat(console/ai): AI workspace UX — date-grouped conversations, draggable split, keyboard shortcuts
464
+
465
+ ChatGPT/Claude-parity polish for the console AI workspace:
466
+
467
+ - **Date-grouped conversations** — the flat conversations list groups into
468
+ recency sections (Today / Yesterday / Previous 7 days / Previous 30 days /
469
+ Older) with calendar-day boundaries, via a pure exported
470
+ `groupConversationsByDate()`.
471
+ - **Draggable chat ↔ preview split** — a draggable, double-click-to-reset divider
472
+ between chat and the Live Canvas preview; width persists to `localStorage`,
473
+ clamped so neither pane collapses (chat ≥ 360px, preview ≥ 420px), keyboard-
474
+ accessible (`role="separator"`, ←/→ resize).
475
+ - **Collapsible conversations list** — auto-tucks when the preview opens, with a
476
+ manual toggle.
477
+ - **Keyboard shortcuts** — ⌘⇧O new chat, ⌘⇧S toggle the conversations list.
478
+
479
+ - 5c23088: **Wire `App.hidden` shell hint — App Switcher + avatar dropdown**
480
+
481
+ Honour the new `App.hidden` field from `@objectstack/spec/ui`:
482
+
483
+ - **`AppSwitcher.tsx`** — filter `app.hidden === true` out of the top-bar app dropdown so personal-settings-style apps don't appear next to business apps.
484
+ - **`AppHeader.tsx`** — render hidden apps as entries in the avatar / user dropdown (immediately after the hardcoded Profile / Settings items). Uses the app's `icon` + `label` via the existing `getIcon` + `appLabel` utilities, and navigates to `/apps/${app.name}`.
485
+
486
+ This is the front-end side of the Account-app split: the `account` app shipped by `@objectstack/platform-objects` declares `hidden: true` and now surfaces through the avatar menu — same pattern as GitHub Settings, Google account chip, and Salesforce Personal Settings.
487
+
488
+ No new dependencies; pure metadata-driven wiring.
489
+
490
+ - 053c948: feat(app-shell): zero-roundtrip `newTabUrl` fast path for `opensInNewTab` actions
491
+
492
+ Actions that declare `newTabUrl` (a path template with a `{recordId}` placeholder
493
+ whose target endpoint performs all auth/authz itself) now drive the pre-opened
494
+ popup straight to that URL on click, skipping the action POST entirely — applied
495
+ to both server-action paths (list rows via `useConsoleActionRuntime`, record
496
+ header via `RecordDetailView`). The popup paints the existing spinner page until
497
+ the (possibly slow) endpoint commits its redirect; the URL is resolved absolute
498
+ because `about:blank` gives a bare-relative href no reliable base. The
499
+ popup-blocked toast fallback is unchanged. Removes one full round trip of
500
+ white-screen latency from every such Open click.
501
+
502
+ - 05ff1fb: Studio: the "New page" form can now create a record page bound to an object.
503
+
504
+ The page create form was identity-only (label/name/icon/description), so it couldn't make a `pageType: 'record'` page or bind it to an object — even though the page edit form and protocol schema fully support those fields. Mirror the `view` resource's create config: the page create form now exposes **Object**, **Page type** (default `record`), and **Kind** (`full`/`slotted`), so a record page can be created and bound in Studio (#1541). The block layout is then composed in the editor's PagePreview canvas.
505
+
506
+ - 7c956d0: Runtime persistence seam: add `'page'` artifact type (record-page draft/publish).
507
+
508
+ `RuntimeArtifactType` now includes `'page'`, so a record `PageSchema` stages and publishes through the same ADR-0034 `/meta` draft model as views/reports/dashboards (#1541). New pure helpers `recordPageName(objectName, existing?)` (prefers an assigned page name, else mints `<object>_record`) and `recordPageEnvelope(objectName, schema, name?)` (sets the `name`/`object`/`pageType:'record'`/`kind:'full'` identity fields the resolver matches on) — foundation for the record-page edit loop.
509
+
510
+ - b0d64c4: Studio: new record pages seed their layout from the object's default detail page.
511
+
512
+ Creating a `pageType: 'record'` page bound to an object previously started from a blank canvas. The `page` resource now has a `createSeed` hook that, on create, fetches the bound object and seeds the page's `regions` from `buildDefaultPageSchema(objectDef)` — the same auto-generated detail layout the runtime renders by default. Authors start by tweaking the default page, not rebuilding it. A generic async `createSeed` hook was added to `MetadataResourceConfig` (merged into the create body after `createBuildBody`/`createDefaults`; best-effort). Completes #1541's Studio authoring path.
513
+
514
+ - 80f9796: Repoint the Console bell to `sys_inbox_message` + `sys_notification_receipt` (ADR-0030)
515
+
516
+ The notification bell read the legacy `sys_notification` object's
517
+ `recipient_id`/`is_read`/`title`/`body` columns. ADR-0030 re-modeled
518
+ `sys_notification` into the L2 _event_ (no recipient/read-state), so the bell
519
+ returned nothing — every notification the new pipeline produced was invisible.
520
+
521
+ The bell now reads the L5 in-app materialization instead:
522
+
523
+ - **List**: `sys_inbox_message` filtered by `user_id` (the `mine` scope), 20
524
+ most-recent, ordered by `created_at`.
525
+ - **Read-state**: joins `sys_notification_receipt` (filtered by `user_id` +
526
+ `channel:'inbox'`). A message is unread until its event has a
527
+ `read`/`clicked`/`dismissed` receipt; the unread count drives the badge.
528
+ - **Mark-read**: `UPDATE`s the existing `delivered` receipt to `read`
529
+ (keyed `(notification_id, user_id, channel)`), inserting only as a fallback
530
+ when no receipt exists. Replaces the old `sys_notification.is_read` write.
531
+ - **Navigation**: follows the materialization's `action_url` (absolute,
532
+ `/apps/...`, or app-relative `/{object}/{id}`), falling back to the legacy
533
+ `source_object`/`source_id` pointer.
534
+ - **"View all"**: routes to `/apps/setup/sys_inbox_message?view=mine`.
535
+
536
+ Pairs with the framework ADR-0030 pipeline (`@objectstack/service-messaging`).
537
+ Verified in-browser (showcase Console): a materialized inbox message + its
538
+ `delivered` receipt lit the bell badge; the popover rendered the row;
539
+ "mark all read" flipped the receipt to `read` in place (no duplicate) and
540
+ cleared the badge.
541
+
542
+ - 5e8965c: Complete the page-editor block configuration and prune shell-only blocks. Adds configurable property panels for the remaining content blocks with authorable properties — `page:accordion`, `record:path`, `record:quick_actions`, `ai:chat_window`, `ai:input` — so every page-content block in the palette is configurable in the UI (pure containers like `page:section` / `element:divider` correctly have no panel). Removes shell-singleton blocks (`app:launcher`, `global:notifications`, `user:profile`) from the page block palette — those are provided by the app shell, not authored as page content.
543
+ - 94c58ad: Align the page-editor element palette with reality. Adds the real lightweight-list primitives — `element:definition-list` (compact key/value `<dl>`) and `element:repeater` (data-bound, chrome-free list) — to the block palette with full config panels (object/field pickers for the repeater), and removes three palette entries that have no renderer (`element:form`, `element:filter`, `element:record_picker`) so the palette only offers blocks that actually render.
544
+ - c681874: Expand page-editor block configuration. Adds configurable property panels for more blocks (`element:number`, `element:button`, `record:alert`) and introduces array-valued property editors — a `string-list` editor (e.g. `record:highlights` fields) and an add/remove `array` editor (e.g. `page:tabs` items, `record:details` sections) — so these blocks are configurable in the UI instead of only via raw JSON.
545
+ - d988090: Schema-driven object/field pickers in the page-editor block inspector. Data-reference block properties are now dropdowns populated from the live metadata instead of free-text: an object picker (e.g. `record:related_list` object, `element:number` object) and cascading field pickers that list the chosen object's actual fields (e.g. `record:related_list` relationship field, `element:number` field, `record:path` status field, `record:highlights`/`record:details` field lists). Resolves the object from the record page's bound object or a sibling block property; degrades gracefully to a text input when the metadata can't be fetched.
546
+ - 9049bbe: Add end-user friendly agent process summaries for chatbot tool calls, with a debug mode for raw reasoning and tool details. Console chat surfaces now keep a sanitized browser-side display cache so refreshes can restore user/assistant text plus grouped tool states when the backend returns no message rows.
547
+ - 77cc6bb: Cloud Connection bind v2 UX (cloud ADR runtime-identity-binding §2.3): the binding flow becomes one click. `CloudConnectionPanel` drops the environment-id input entirely (registration happens cloud-side at approval), auto-opens the approval page in a popup on Connect (user-code display stays as the popup-blocked fallback), and shows the registered runtime name + runtime id once bound. `DeviceAuthPage` displays the requesting device's context (`runtime_name` / `runtime_version` from the verification URL) plus an "only approve if you started this" warning — the informed-consent surface for the RFC 8628 flow. Two new `auth.device.*` keys across all locales.
548
+ - 0ca2040: `cloud-connection:panel` SDUI widget — the RFC 8628 device-code binding state machine for the metadata-driven Cloud Connection Setup page (shipped by `@objectstack/cloud-connection`). status → connect → user-code display + approval link → poll → bound/disconnect; the runtime credential never reaches the browser.
549
+ - 04e6168: SDUI: give PageView a console action runtime (#1605). Extract ObjectView's schema-action wiring into a reusable `useConsoleActionRuntime` hook (+ a `ConsoleActionRuntimeProvider` wrapper): confirm / param / result dialogs, the authenticated api / flow / server-action handlers, SPA navigation, the paused screen-flow runner, and a refresh callback. ObjectView now consumes the hook (behaviour unchanged), and PageView wraps its page schema in the runtime — so a page-level `action:button` can collect params, call authenticated API endpoints, show confirm/result dialogs, run screen flows, navigate the SPA, and invalidate embedded data after success. Pages run global (object-less) actions; the hook binds `objectName` only when one is present. This unblocks metadata-driven app home pages (e.g. a "Create environment" primary action) instead of bespoke React components.
550
+ - 39c89e7: ADR-0021 D2: true matrix cross-tab + dataset-path drill-down.
551
+
552
+ - DatasetReportRenderer pivots `type: 'matrix'` reports into a real rows × columns cross-tab (one dataset query over all dimensions, pivoted client-side; matrix without `columns` degrades to the flat grouped table). Joined blocks pivot too.
553
+ - Drill-down: aggregated rows / matrix cells are clickable when the host passes `onDrill` (and the report doesn't set `drilldown: false`), emitting `{dataset, groupKey, runtimeFilter}`. ReportView resolves the dataset's object + dimension→field mapping (reverse-mapping select option labels back to stored values) and navigates to the object list scoped by `?filter[field]=value`.
554
+ - Studio: the report inspector gains a Columns (across dimensions) list for matrix reports; ReportPreview renders through the same DatasetReportRenderer as the runtime, so the matrix preview is WYSIWYG.
555
+
556
+ - 1c8f775: Add the External Datasource Federation Studio surface (ADR-0015 P5)
557
+
558
+ Federated datasources (`schemaMode !== 'managed'`) now get a dedicated
559
+ panel inside their Studio Preview tab, so connecting a mature external
560
+ database and registering its tables as ObjectStack objects is a
561
+ point-and-click flow instead of a CLI-only one. The panel pairs with the
562
+ framework backend shipped in objectstack-ai/framework#1390
563
+ (`registerExternalDatasourceRoutes` → `/api/v1/datasources/:name/external/*`).
564
+
565
+ ObjectStack is metadata-driven: `datasource` is a metadata type, so it is
566
+ browsed and edited through the standard metadata-admin engine
567
+ (`metadata:resource`) reached from the Studio app's left-side menu —
568
+ **not** a hand-written page. The Studio app (framework
569
+ `packages/platform-objects/src/apps/studio.app.ts`, Integration group)
570
+ gains a `Datasources` nav item pointing at
571
+ `metadata:resource?type=datasource`; the federation panel is contributed
572
+ to that standard surface via `registerMetadataPreview('datasource', …)`.
573
+
574
+ **`@object-ui/app-shell` — `views/metadata-admin/external/`**
575
+
576
+ - `api.ts` — a thin, typed REST client over the four federation routes
577
+ (`tables`, `tables/:remote/draft`, `refresh-catalog`, `validate`) plus an
578
+ `importObjectDraft` helper that PUTs a generated draft to `/meta/object`.
579
+ All calls go through `createAuthenticatedFetch()` (Bearer + `X-Tenant-ID`
580
+ - `Accept-Language`). A `503 external_service_unavailable` reply is mapped
581
+ to a typed `ExternalServiceUnavailableError` so the UI shows a friendly
582
+ "federation not enabled on this server" hint. Contract types are inlined
583
+ (they were added in framework 7.3; objectui pins `@objectstack/spec`
584
+ `^7.2.1`).
585
+ - `SchemaBrowser` — lists remote tables (allowedSchemas-filtered server-side)
586
+ with a text filter, on-demand Refresh (never a timer — warehouse
587
+ introspection is expensive), and a per-table Import action.
588
+ - `ImportObjectDialog` — generates an Object draft, surfaces the
589
+ type-compat matrix's `// REVIEW:` columns and the generated `*.object.ts`
590
+ source, then imports it as a real object. Never mutates the remote schema.
591
+ - `ValidationPanel` — runs validation on demand and renders per-object
592
+ structured schema diffs (missing column, type mismatch, …). Doubles as an
593
+ on-demand drift view.
594
+ - `ExternalDatasourcePanel` — Tables / Validation tabs plus a header strip
595
+ with "Refresh catalog" and the snapshot timestamp.
596
+ - `DatasourcePreview` — registered via `registerMetadataPreview('datasource', …)`,
597
+ it renders the panel automatically inside the standard resource edit
598
+ page's Preview tab when the saved datasource is federated
599
+ (`schemaMode !== 'managed'`), keyed off the item name. This is the only
600
+ wiring needed: no bespoke page, no extra route, no `@object-ui/app-shell`
601
+ surface to re-export — the metadata-admin engine + left-side nav own the
602
+ navigation. Federated datasources are read-only code artifacts (the
603
+ `datasource` type forbids runtime create), which the standard list view
604
+ already reflects (no "Create" button).
605
+
606
+ Out of scope (blocked on backend follow-ups): the connection wizard
607
+ (driver/credentials/secrets — belongs in System Settings) and a push-based
608
+ drift inbox (needs an event feed). The framework exposes no
609
+ test-connection, secrets, or drift-feed routes yet.
610
+
611
+ - d54346c: feat: action/flow completion messaging
612
+
613
+ - **core**: `ActionResult.silent` — a handler sets it when the action only
614
+ HANDED OFF to a follow-up UI (rather than completing), so `ActionRunner`
615
+ skips the automatic success toast. Fixes the misleading "Action completed
616
+ successfully" toast that fired the moment a `flow` action opened its wizard.
617
+ - **app-shell**: both flow handlers now return `silent: true` when the flow
618
+ pauses at a screen (the wizard only opened — it hasn't completed). `FlowRunner`
619
+ renders the flow's declared `successMessage` / `errorMessage` (from the
620
+ terminal `AutomationResult`) instead of a generic "Done" / the raw error.
621
+
622
+ - 12566ea: Flow designer ↔ automation engine alignment + run history panel.
623
+
624
+ - **Palette/type-picker:** replace the BPMN `parallel_gateway` / `join_gateway`
625
+ (and `boundary_event` in the picker) with the structured `parallel` and
626
+ `try_catch` constructs the engine actually executes (ADR-0031 keeps the BPMN
627
+ gateway types as import/export interop only — they have no executor, so
628
+ flows authored with them failed at runtime with `NO_EXECUTOR`). Legacy
629
+ gateway nodes still render for imported flows.
630
+ - **Runs panel:** new `FlowRunsPanel` fetches `GET /api/v1/automation/{name}/runs`
631
+ and surfaces run status / duration / per-node step logs in the FlowPreview
632
+ side panel (Variables / Debug / Runs), degrading quietly when the engine is
633
+ offline.
634
+ - **Simulator:** structured containers (`parallel`, `try_catch`) pass through
635
+ honestly as unsupported instead of faking their semantics.
636
+
637
+ - 4e060b7: Polish the Studio flow-designer canvas visuals
638
+
639
+ A refinement pass over the metadata-admin flow designer (`FlowCanvas` +
640
+ `flow-canvas-parts`) — purely presentational, no behavioral or API changes,
641
+ theme-aware (light/dark), and still dependency-free.
642
+
643
+ - **Node cards**: the flat 3px left-accent stripe is replaced by a tinted,
644
+ color-coded **icon chip** (the card's primary category cue), with a bolder
645
+ label, refined uppercase type caption, layered hover elevation
646
+ (`-translate-y-0.5` + soft shadow), and clearer selected / run-state rings.
647
+ Per-category `chip` tone tokens (soft bg + inset ring) added alongside the
648
+ existing icon/accent/label tones. Added distinct tones for `loop` (sky),
649
+ `screen`/`user_task` (pink) and `assignment` (purple) — previously they fell
650
+ back to the generic slate "task" tone, so every node type now reads as a
651
+ distinct color in the canvas.
652
+ - **Readable labels**: node width 188→240 and the per-node summary moved from a
653
+ right-hand column onto a second line, so the label now gets the **full card
654
+ width** (it was badly truncated — "Manager Re…", "Budget Ab…"). A native title
655
+ tooltip surfaces the full text on the rare remaining truncation.
656
+ - **No overlap on add**: adding a connected node no longer pins it directly below
657
+ its parent (which stacked every sibling on the same spot) — it's left to the
658
+ layered auto-layout, which slots it beside its siblings.
659
+ - **Canvas surface**: the dot grid now tracks pan **and** zoom (it moves with
660
+ the diagram instead of floating behind a static texture), plus a subtle inset
661
+ vignette for depth.
662
+ - **Edges**: rounded line caps, slightly stronger default stroke, and
663
+ pill-shaped (rounded-full, frosted) branch/condition labels.
664
+ - **Toolbar + add-node palette**: frosted, rounded controls with a primary
665
+ hover affordance; the palette gains an "Add node" header and matching tinted
666
+ icon chips per row.
667
+
668
+ Verified in-browser (Studio → flow → designer) in both light and dark themes.
669
+
670
+ - 5332639: feat(app-shell): render full object forms (incl. master-detail) in screen-flow wizard steps
671
+
672
+ `FlowRunner` now renders an `object-form` screen step: when the paused screen
673
+ carries `kind: 'object-form'`, it mounts the real `<ObjectForm>` for the named
674
+ object (auto-routing to `MasterDetailForm` for inline child collections),
675
+ prefilled from the step's `defaults`. The form persists itself (atomic
676
+ master-detail batch), then resumes the run with the saved record id bound to the
677
+ step's `idVariable`. `dataSource`/`objects` are threaded through all three
678
+ `FlowRunner` mount points.
679
+
680
+ Also fixes three pre-existing bugs this surfaced (each affects normal forms too):
681
+
682
+ - **plugin-form**: `ObjectForm` now forwards `initialValues`/`initialData` when
683
+ routing to `MasterDetailForm`, so prefilled header values are no longer
684
+ dropped on master-detail create forms.
685
+ - **fields**: `PercentField` treated values as `0–1` fractions (`value × 100`),
686
+ so a `0–100` field (e.g. `probability` default `50`) rendered as `5000%` —
687
+ exceeding `max=100`, which makes HTML5 constraint validation mark the field
688
+ `:invalid` and silently block the whole form's submit. It now treats a field
689
+ declaring `max > 1` as the `0–100` whole-number convention, matching the
690
+ read-side formatter.
691
+ - **data-objectstack**: `ObjectStackAdapter.batchTransaction` now sends
692
+ `credentials: 'include'`, so master-detail batch saves authenticate under the
693
+ console's cookie session (previously every batch save 401'd).
694
+
695
+ - e02aedd: Group the flow add-node palette by category, and offer every node type
696
+
697
+ The quick-add palette listed 12 node types as a flat list; `assignment`,
698
+ `screen`, `delete_record` and the parallel gateways could only be reached by
699
+ adding a node and switching its type in the inspector. Building flows, that's a
700
+ real friction point.
701
+
702
+ - **Complete**: the palette now offers Delete record, Set variables
703
+ (assignment), Screen, Parallel split and Parallel join too — so every common
704
+ node type is one click away.
705
+ - **Grouped**: items are organised into **Data / Logic / Human / Integration /
706
+ Flow** sections with headers and dividers, so the (now longer) list stays
707
+ scannable. A new `nodeCategory(type)` helper drives the grouping and gives
708
+ engine-only / plugin-contributed node types a sensible section; `mergePalette`
709
+ preserves a base item's category and infers one for engine-only types.
710
+
711
+ Verified in-browser: the grouped palette renders all sections with tinted icon
712
+ chips, and the newly-offered types add to the canvas with the correct icon/tone
713
+ and no overlap.
714
+
715
+ - 7130d4e: Add FlowRunner — render & resume interactive screen-flows
716
+
717
+ A `type: 'flow'` action whose run pauses at a `screen` node now opens a
718
+ `FlowRunner` modal that renders the screen's fields, submits the values to the
719
+ framework resume endpoint (`POST /api/v1/automation/{flow}/runs/{runId}/resume`),
720
+ and advances to the next screen or closes + refreshes on completion. Previously
721
+ such flows launched server-side but the screen was never rendered, so the input
722
+ was never collected.
723
+
724
+ - New `FlowRunner` component (fields → form → resume loop).
725
+ - `ObjectView` + `RecordDetailView` flow handlers detect a paused-screen launch
726
+ response (`{ status:'paused', runId, screen }`) and open the runner; for
727
+ list_item actions the row's id (`_rowRecord.id`) flows in as the flow's
728
+ `recordId`.
729
+
730
+ Pairs with the framework screen-flow runtime (`@objectstack/service-automation`
731
+ - `@objectstack/runtime`). Verified in-browser: showcase task row → "Reassign…"
732
+ → form → submit → the task is reassigned.
733
+
734
+ - 3fa23a7: feat(header): context-aware Help & Documentation menu + app-scoped docs index
735
+
736
+ The top-right "?" was a bare external link to `docs.objectstack.ai`, duplicating
737
+ the left sidebar's in-product `/docs` entry and ignoring the ADR-0046 docs hub.
738
+ It is now an aggregated, context-aware menu:
739
+
740
+ - **This app's docs** — shown only when the current app's package owns docs
741
+ (matched by `_packageId`). A single-doc app deep-links straight to the
742
+ viewer; a multi-doc app lands on the new app-scoped index.
743
+ - **All documentation** — the in-product `/docs` portal.
744
+ - **Online documentation** — `docs.objectstack.ai` (opens in a new tab).
745
+
746
+ Docs are lazily fetched once on first menu open (names/labels only), so the menu
747
+ adds no cost until used; a failed fetch soft-degrades to the static entries.
748
+
749
+ Also adds the app-scoped docs index route **`/apps/:packageId/docs`**
750
+ (`AppDocsIndex`) — the package-scoped sibling of `/docs`, listing just that
751
+ app's docs — which the "This app's docs" entry targets when an app ships more
752
+ than one. New `help.*` strings added to the `en` and `zh` bundles (other
753
+ locales fall back to `en`).
754
+
755
+ - 9f9d1db: Add an `icon` form widget — a searchable Lucide icon picker for metadata-admin.
756
+
757
+ Metadata `icon` fields (page/app/object) were a raw text input where authors had to know and type an exact Lucide name. The new `widget: 'icon'` renders a combobox: the trigger shows a live preview of the current icon, and opening it reveals a search box plus a grid of matching icons (preview + name). Selecting writes the kebab-case name string. Out-of-catalog values (e.g. icons from another library, or typos to fix later) survive — they render on the trigger and stay reachable as a "keep" option so re-opening never silently drops them. Registered as `'icon'` in the metadata-admin `WIDGETS` map; pair with `widget: 'icon'` in the spec `*.form.ts`.
758
+
759
+ - 0d707b6: `marketplace:installed-list` SDUI widget — the Installed Apps body (control-plane/local dual-source list, refresh, uninstall) extracted from the React route page, which now renders the same component. The page shell ships as metadata with `@objectstack/cloud-connection`'s install-local plugin (cloud ADR-0009 P2a).
760
+ - 67dbaa1: interface page: Add-Record config now takes effect; view picker mirrors runtime resolution
761
+
762
+ - **Fix: `interfaceConfig.addRecord` did nothing.** `InterfaceListPage` never forwarded `addRecord` into the schema it hands to `ListView`, so the panel's Add-Record toggle/position/mode were silently dropped — the button could never appear on an interface page. Now `addRecord` is passed through (ListView already gates the button on `addRecord.enabled` across all visualizations).
763
+ - **`view-ref` picker no longer mislabels resolvable values.** A stored `sourceView` like the bare `default` was tagged "(not in object)" even though the runtime resolves it. The widget now mirrors `InterfaceListPage.resolveSourceView` (exact name / `<object>.<name>` suffix / `default`-`list` special-case) via an extracted, unit-tested `resolveStoredViewRef`, showing the matched view's label (e.g. "All Tasks → showcase_task.default") instead of a false warning.
764
+
765
+ - 586770c: metadata editor: `view-ref` widget for picking a source view
766
+
767
+ Adds a `view-ref` form widget so `interfaceConfig.sourceView` (and any field with `widget: 'view-ref'`) renders as a dropdown of the source object's views instead of a free-text name the author could mistype. Views come from a new `WidgetContext.objectViews`, which `ResourceEditPage` loads for the page's source object (`interfaceConfig.source` / `object`). A value not in the catalog is still shown so stale/custom names survive; clearing to "None" omits the field (the protocol treats absence as the object's default view). The widget mirrors the existing `field-ref` picker and degrades gracefully when no source object is bound.
768
+
769
+ Pairs with the `@objectstack/spec` change that sets `widget: 'view-ref'` + `dependsOn: 'source'` on the page form's `sourceView` field.
770
+
771
+ - 652f9b2: feat(packages): "Discard changes" and "Delete app" buttons in the package detail sheet
772
+
773
+ Adds two one-click package-lifecycle actions next to the existing "Publish app", mirroring the new backend endpoints:
774
+
775
+ - **Discard changes (N)** — next to "Publish app" in the Pending changes block. Drops every pending draft via `POST /packages/:id/discard-drafts`, reverting the app to its last published baseline. Non-destructive (published metadata + data untouched), then refreshes the pending list.
776
+ - **Delete app** — in the Actions row. Removes the whole package via `DELETE /packages/:id` (active + draft metadata + drops each object's table). Confirms first ("this cannot be undone"); closes the sheet on success, keeps it open and shows the error on failure.
777
+
778
+ Together with "Publish app", this gives the full AI-build review loop a UI: publish to preview → keep, **discard all changes**, or **delete the app**.
779
+
780
+ - 82195b5: Configurable property panels for page-editor blocks (SDUI). The Studio page editor's block inspector now renders typed, protocol-aligned property fields (editing the block's `properties`) for the minimal SDUI-essential content blocks — `element:text`, `element:image`, `page:header`, `page:card`, `record:related_list` — instead of only the generic `type`/`id`/`className`/`hidden` fields. Previously these properties were editable only via raw JSON.
781
+ - f12225b: The Studio page editor can now edit nested sub-blocks inside container blocks. A `page:tabs`/`page:accordion` tab's children, and a `page:card`/`page:section`'s body, are surfaced as indented, selectable sub-blocks — each one can be selected, configured (via the inspector and its object/field pickers), edited, removed, and new ones added — in both full and slotted pages. Addressing is handled by extending the block-path scheme to support object-key hops (e.g. `…components[0].properties.items[0].children[0]`) and a nested sub-path under slot ids. Closes the last gap so a container's contents are fully point-and-click instead of raw JSON.
782
+ - 14e3db5: The Studio page editor can now edit slotted record pages. A `kind:'slotted'` page surfaces its 7 canonical slots (header / actions / alerts / highlights / details / tabs / discussion) as editable regions — overridden slots show their blocks (selectable + configurable via the inspector and its object/field pickers), and unoverridden slots show an "inherited — add a block to override" placeholder. Edits write back to `slots`; empty slots are omitted so they keep inheriting the synthesized default. This closes the loop for the most common low-code task — customizing a business object's detail page (highlights/tabs/details) point-and-click instead of by hand-editing JSON.
783
+ - 4eb9cb6: feat(plugin-tree): add a `tree` / tree-grid object view type
784
+
785
+ Renders a self-referencing object as an indented, expand/collapse tree-grid —
786
+ the right view for arbitrary-depth hierarchies (business unit / org chart,
787
+ category trees, BOMs, nested comments) that fixed-depth grouping can't express.
788
+ New `@object-ui/plugin-tree` package (`object-tree`/`tree`), `tree` added to the
789
+ `ViewType` union, and dispatch wired through plugin-list `ListView` +
790
+ app-shell `ObjectView` (the console path).
791
+
792
+ - de3224e: feat(metadata): relationship-level `inlineEdit` auto-renders master-detail
793
+
794
+ A child object's `master_detail`/`lookup` field can declare `inlineEdit: true`
795
+ (in the data model) to mean "edit me inline within my parent's form". The
796
+ metadata layer now scans for these and merges the resulting child collections
797
+ into each parent object's form view as `subforms` — so the parent's **standard**
798
+ New/Edit form auto-renders an atomic master-detail form with **no view config
799
+ and no bespoke page**. The intent lives once in the data model (where e.g. an AI
800
+ modelling the schema naturally sets it); forms derive the UI.
801
+
802
+ `master_detail` children WITHOUT `inlineEdit` are not inlined (so associations
803
+ like comments/attachments stay out of the entry form). An explicit
804
+ `form.subforms` entry overrides the derived one. Optional
805
+ `inlineTitle`/`inlineColumns`/`inlineAmountField` tune the grid.
806
+
807
+ - 010883d: Migrate the runtime DashboardView "dashboard editor" onto the studio's spec-driven inspectors. A single app-shell `DashboardConfigPanel` now replaces both legacy `plugin-dashboard` panels (the dashboard-level config panel and the per-widget config panel): with no widget selected it hosts a new spec-driven `DashboardDefaultInspector` (registered as the studio default inspector for the `dashboard` type), and with a widget selected it hosts the existing `DashboardWidgetInspector`. Both inspectors edit the full nested Dashboard document directly, so the runtime's widget flatten/unflatten adapters are removed. The panel lives in app-shell to avoid a circular dependency on plugin-dashboard; the `sys_dashboard` persistence path is unchanged.
808
+ - 7da8a57: Migrate the runtime ReportView "report editor" onto the studio's spec-driven inspector. The right-rail editor now hosts the same report inspector the metadata studio uses (config fields sourced from `@objectstack/spec` `ReportSchema` / `reportForm`) instead of plugin-report's legacy `buildReportSchema` / `ConfigPanelRenderer` engine, so runtime and studio share one report-editing surface. A new spec-driven `ReportDefaultInspector` is registered as the studio default inspector for the `report` type, and a thin app-shell `ReportConfigPanel` hosts it for the runtime (kept in app-shell to avoid a circular dependency on plugin-report). Field pickers read from the in-memory object definition (no extra network fetch); the `sys_report` persistence path is unchanged.
809
+ - 7b71cd8: Unify the runtime ObjectView "view editor" onto the studio's spec-driven inspector. The right-rail view editor now hosts the same `ViewVariantInspector` the metadata studio uses (config fields sourced straight from `@objectstack/spec`) instead of the legacy `buildViewConfigSchema` engine, so runtime and studio share one view-editing surface. A new `view-config-adapter` bridges the runtime's flat view shape and the studio's ViewItem draft, keeping the `sys_view` persistence path untouched; field pickers read from the in-memory object definition (no extra network fetch). The legacy `buildViewConfigSchema` engine and its exports are retired; `ConfigPanelRenderer` is retained for the dashboard/report config panels.
810
+ - 8426db7: feat(form): standard New/Edit modal renders form-view subforms (Tier 0)
811
+
812
+ The console's standard create/edit record modal now renders inline child
813
+ collections when the object's form view declares `subforms` — master-detail
814
+ entry with **no bespoke page**, persisted as one atomic transaction.
815
+
816
+ - `ModalForm` (and the create/edit modal in app-shell `AppContent`) detects
817
+ `subforms` and renders `MasterDetailForm` inside the dialog (it owns its Save
818
+ bar; the modal footer is suppressed); on success the modal closes + refreshes.
819
+ - `AppContent` sources `subforms` from the object's default form view
820
+ (`form.subforms` / `formViews.default.subforms`).
821
+ - `ModalFormSchema` gains `subforms`.
822
+
823
+ With this, declaring `formViews.default.subforms: [{ childObject }]` is enough
824
+ to make an object's standard New/Edit screen a master-detail form — completing
825
+ the config-driven master-detail story (Tier 0 → derive everything from the
826
+ relationship + child metadata).
827
+
828
+ ### Patch Changes
829
+
830
+ - 3b5e293: ADR-0034 step 2: route ObjectView's view-config save through the runtime persistence seam, completing the seam's coverage of all three runtime editors (view/report/dashboard). Corrects the seam's `view` branch to mirror ObjectView's real update path (`dataSource.updateViewConfig(...)`, the ADR-0005 overlay API) rather than a raw `sys_view` write. Behaviour is unchanged while the `VITE_RUNTIME_EDIT_VIA_META` flag is off; flag on routes the view update to the studio `/meta` draft. The view CREATE path (`createView` + default-column/kanban/gallery massaging) and the draft/publish UI remain deferred.
831
+ - 02c3c65: ADR-0034 step 1: introduce a flag-gated runtime metadata persistence seam. `persistRuntimeMetadata` / `publishRuntimeMetadata` centralise where the runtime view/report/dashboard editors save. Behind the `VITE_RUNTIME_EDIT_VIA_META` flag (default **off**) they reproduce today's `sys_*` writes exactly (zero behaviour change); flag **on** routes to the studio `/meta` per-item draft/publish model (`MetadataClient.save(..., { mode: 'draft' })` + `publish`). ReportView and DashboardView now save through the seam; ObjectView (view) and the draft/publish UI are deliberately deferred. No `sys_*` table is removed and no data is migrated. Also adds the finalized ADR-0034.
832
+ - b8a5d41: ADR-0048: finish sweeping app-entry links onto the canonical package-id route
833
+ segment (follow-up to the home-page fix).
834
+
835
+ - `AppManagementPage` (System → Apps) "Open app" button now opens
836
+ `/apps/<packageId>` (`app._packageId ?? app.name`) instead of `/apps/<name>`.
837
+ - `AppContent` current-app sub-routes/redirects (the `metadata/package` →
838
+ `component/developer/packages` redirect, and the record-form `baseUrl`) now
839
+ build against the URL's own `appName` segment instead of `activeApp.name`, so a
840
+ `/apps/<packageId>/…` URL keeps its package-id segment instead of flipping to
841
+ the name form. `requestedAppMissing` (preview-drafts) now resolves the segment
842
+ via `matchAppBySegment` so a package-id URL isn't treated as a missing app.
843
+
844
+ - 4cd0a0d: ADR-0048 (#1824): the Studio metadata editor's post-save refresh now scopes its
845
+ layered + draft re-read to the same package as the initial load (`?package=`), so
846
+ when two installed packages ship the same `type`/`name` the editor re-reads
847
+ this package's own row after saving — not another package's. The save itself
848
+ already binds the package; this aligns the refresh with it.
849
+ - a571911: ADR-0048: the console **home** page now links into apps by their canonical
850
+ package-id route segment, matching the nav. The app grid (`HomePage`) and the
851
+ "add to favorites" href (`AppCard`) were still building `/apps/<app.name>` while
852
+ the sidebar/switcher/command-palette emit `/apps/<packageId>` (via
853
+ `appRouteSegment`). So opening an app from the home page produced a name-form URL
854
+ (e.g. `/apps/studio`) instead of `/apps/com.objectstack.studio`. Both now use
855
+ `appRouteSegment(app)`.
856
+ - b99d9bd: ADR-0048: package-scope the Studio metadata editor read. Two installed packages
857
+ may ship metadata with the same `type`/`name`; the editor now resolves the right
858
+ one instead of first-match.
859
+
860
+ - `MetadataClient`: `layered()` and `getDraft()` accept `{ packageId }`, and
861
+ `get()` emits the `package` query param (→ server prefer-local, `?package=`).
862
+ - `ResourceListPage`: each item's edit link carries its owning package
863
+ (`?package=<row._packageId>`), so even the unscoped "all" list disambiguates;
864
+ falls back to the workspace suffix for runtime/overlay-only rows.
865
+ - `ResourceEditPage`: reads `?package=` and scopes the layered + draft read to
866
+ that package. (The route's `:appName` is the Studio app, not the edited item's
867
+ owner, so the scope must come from the URL, not the active app.)
868
+
869
+ - 5a95032: Polish the full-page AI workspace with a responsive conversation drawer, clearer page context, constrained chat width, and accessible conversation row actions.
870
+ - 053c948: fix(app-shell): send the current-page object to the AI assistant context
871
+
872
+ The floating console assistant forwarded only `appName` + the full objects list,
873
+ never the object the user is actually viewing — so asking it to "analyse this
874
+ object" (especially in a non-English prompt) gave the agent nothing to anchor on
875
+ and it replied that it couldn't find the object. The current object/record are
876
+ now derived from the route (mirroring `useTrackRouteAsRecent`'s URL layout,
877
+ tolerant of a `_console` shell prefix) and passed as `context.objectName` /
878
+ `context.recordId`, so the backend injects that object's schema into the system
879
+ prompt and scopes data queries to it. Pairs with the framework current-object
880
+ resolution fix.
881
+
882
+ - 40c79df: Improve the floating chatbot flow with responsive panel bounds, safer FAB placement, inline responding and stop states, and clearer retryable error feedback.
883
+ - 6c0c92c: fix(app-shell): command palette idempotent open + stable locators (ADR-0054 Phase 1)
884
+
885
+ The top-bar "Search… ⌘K" button now opens the command palette directly via a
886
+ shared, idempotent `openCommandPalette()` instead of re-dispatching a synthetic
887
+ `⌘K` `KeyboardEvent` — so it works under automation and in ⌘K-reserving
888
+ browsers. Open state is URL-addressable (`?palette=1`, `?cmdk=1` alias), making
889
+ the palette deep-linkable and restore-on-reload. The dialog and header trigger
890
+ emit stable `data-testid` locators (`overlay:command-palette`,
891
+ `action:command-palette:open`) plus an ARIA name. New `useCommandPalette()` hook
892
+ and `CommandPaletteProvider`; `CommandDialog` gains a `contentProps` passthrough
893
+ for the dialog locator/ARIA. Implements invariants C1/C3/C4 of the UI
894
+ testability contract.
895
+
896
+ - 97c6831: Localize AI workspace, shell navigation, startup, connection, toast, and chatbot affordance text across core console screens.
897
+ - f6044fa: feat(form): subforms in DrawerForm + full-page record form (Tier 0 everywhere)
898
+
899
+ Completes config-driven master-detail across all standard create/edit entry
900
+ points (after the modal in the previous change):
901
+
902
+ - `DrawerForm` now hosts `MasterDetailForm` inside the drawer when the schema
903
+ declares `subforms` (its own Save bar; closes + refreshes on success).
904
+ - `RecordFormPage` (full-page New/Edit) sources `subforms` from the object's
905
+ form view, so the full-page form renders inline child collections too.
906
+ - `ObjectForm`'s subforms shortcut now defers to the drawer/modal variants for
907
+ those formTypes (so they keep their envelope), and only renders the
908
+ master-detail form directly for inline/simple forms.
909
+
910
+ Declaring `formViews.default.subforms: [{ childObject }]` now yields a
911
+ master-detail experience in the modal, drawer, AND full-page form — no bespoke
912
+ page anywhere.
913
+
914
+ - 6cfa330: feat(dashboard): drill "Open in list" escape hatch + unify report drill
915
+
916
+ Adopts the mainstream BI peek-then-escalate drill model. Drill-through opens an
917
+ in-place drawer (keep context) and offers an "Open in list →" affordance to
918
+ escalate to the object's full list page (sort / bulk-select / export / shareable
919
+ URL) — the Looker / Power BI "see records → open in page" pattern.
920
+
921
+ - New `DrillNavigationContext` (`@object-ui/react`): the app shell provides
922
+ `openRecordList`; the renderer stays decoupled from console routing.
923
+ - The drill drawers (pivot / dataset / chart / KPI) render the escape hatch when
924
+ a host navigation handler is present, and hide it otherwise (self-contained
925
+ peek). `DashboardView` provides the handler via `useOpenRecordList`.
926
+ - `DrillDownConfig.target` gains `'navigate'` — skip the drawer and open the
927
+ list directly; degrades to `'drawer'` when no host handler is available.
928
+ - `ReportView` drill-through now opens the same in-place drawer (peek records →
929
+ click a row to open a record) instead of navigating away; the escape hatch
930
+ preserves the previous navigate-to-list behavior. Dashboard and report drill
931
+ are now unified.
932
+ - i18n: `dashboard.openInList` (en / zh).
933
+
934
+ - 23bf869: fix(app-shell): edit-in-studio pencil no longer overlaps interface-page toolbar buttons
935
+
936
+ The PageView "Edit in studio" pencil is an absolute overlay at the page's
937
+ top-right. On an interface (list) page whose header surfaces toolbar buttons
938
+ (e.g. an Approvals page's "Mark Done"), the pencil sat on top of the rightmost
939
+ button, clipping its label. PageView now tells InterfaceListPage to reserve
940
+ right padding on its header (`reserveEditAffordance`, only when the pencil is
941
+ shown) so the toolbar clears the affordance. Non-admin / non-editable pages are
942
+ unchanged.
943
+
944
+ - 70b7780: Metadata editor: a failed LOAD no longer masquerades as field validation errors.
945
+
946
+ When the layered/draft fetch fails (network/500/timeout), `ResourceEditPage` previously still rendered the form on empty defaults, so the client Zod validator fired spurious "name/label/regions required" diagnostics — making a transport failure look like a structurally broken item.
947
+
948
+ - New `loadFailed` state, set in the load catch block and reset at the start of each load.
949
+ - The validation-diagnostics banner is now gated by `shouldRenderDiagnostics()`, which suppresses the diagnostics block entirely on load failure, so the empty-default form's required-field issues never surface.
950
+ - The top error banner is now explicit: "Failed to load &lt;type&gt;/&lt;name&gt;: &lt;message&gt;" (new `engine.edit.loadFailed` i18n key, en + zh-CN).
951
+
952
+ The happy path is unaffected: a genuinely-invalid item that loaded successfully still shows its validation diagnostics.
953
+
954
+ - fe69471: Flow designer: start a new flow with a trigger, and stop the edge "+" overlapping branch labels
955
+
956
+ Two more dogfooding fixes for the Studio flow designer:
957
+
958
+ - **Empty flow → Start node.** An empty editable flow's "Add node" inserted a
959
+ generic `task` node; it now seeds a `start` (trigger) node — the canonical
960
+ entry point every flow needs — so the canvas opens on the trigger and the
961
+ author builds forward from there.
962
+ - **Edge insert handle no longer collides with the branch label.** The "insert
963
+ node" `+` button and the branch/condition label pill were both centered on the
964
+ edge midpoint, so on a labeled edge (`approve`, `if …`) the `+` sat on top of
965
+ the label. The `+` now slides to the right of the label when one is present
966
+ (unlabeled edges keep the centered `+`).
967
+
968
+ Verified in-browser: labeled edges show the label and a clear, separate insert
969
+ handle; `tsc --noEmit` clean.
970
+
971
+ - 0032b23: FlowRunner: close the runner when a resume ends in a terminal flow failure.
972
+
973
+ The engine consumes a run's suspension before executing downstream nodes
974
+ (resume-once semantics), so a resume whose `AutomationResult` is
975
+ `success: false` can never be retried — the old behavior left the dialog open
976
+ and a second Submit hit "No suspended run". Transport-level failures (network
977
+ / 5xx) still keep the dialog open for retry.
978
+
979
+ - e8d56ec: fix(form): honour the form view layout in the full-page record form
980
+
981
+ `RecordFormPage` hard-coded `formType: 'simple'`, so a record's declared form
982
+ view layout (`tabbed` / `wizard` / `split`) was ignored on the full-page
983
+ create/edit route — `ObjectForm` already renders every variant, the entry point
984
+ just never passed it through. It now reads the object's `form` / `formViews.default`
985
+ `type` + `sections` and forwards them (plus variant props: defaultTab, tabPosition,
986
+ allowSkip, showStepIndicator, split\*). Page-level layouts only — `drawer`/`modal`
987
+ are presentation/open-modes, not record-page layouts, so they fall back to `simple`.
988
+
989
+ Refs objectstack-ai/framework#1890
990
+
991
+ - 0ad72a6: fix: pass full gantt config to renderer, render multi-value lookups in gantt tooltips, persist `bodyExtra` on dataSource actions, and complete zh/en gantt labels
992
+
993
+ Four platform gaps that the EHR app previously worked around with `node_modules` patches:
994
+
995
+ - **app-shell / ObjectView** — the `config.gantt → renderer props` adapter was a hardcoded 6-field whitelist, so `parentField`/`typeField` (and `baseline*`, `groupByField`, `resourceView`, `tooltipFields`, `quickFilters`, …) never reached the renderer and the chart degraded to a flat list. It now spreads the full `viewDef.gantt` first, then applies the three required defaults last (mirroring the gallery branch).
996
+ - **plugin-gantt / ObjectGantt** — the tooltip value formatter only handled single-object lookups, so a multi-value lookup (a populated `[{name},{name}]` array) fell through to `'—'`. It now maps each array element to its display value and joins them.
997
+ - **app-shell / useConsoleActionRuntime** — `bodyExtra` was merged only on the absolute-HTTP path; the generic `dataSource.update` path ignored it, so a pure-confirmation action (no params array) left an empty payload and persisted nothing. `bodyExtra` is now merged last on that path too, matching the documented semantics.
998
+ - **i18n** — added the gantt labels the 9.x renderer references but the bundles lacked: `toolbar.thisWeek/thisMonth/exportPdf/saveLayout`, `viewMode.year`, `menu.add*/removeDependency/noCandidates`, the `linkType.*` and `conflict.*` blocks, and `readOnly*` — in both `en` (canonical key source) and `zh`.
999
+
1000
+ - e133fae: Gate the runtime report and dashboard editors behind an admin check. Editing a report or dashboard mutates the **shared** definition (it writes the single `sys_report` / `sys_dashboard` record, not a per-user copy), but the edit buttons were shown to every user — so any viewer could change a report/dashboard for everyone. The "Edit" affordance (and its config panel) is now admin-only, matching ObjectView's existing view-config gate. This is the first step of ADR-0034 (runtime edits are an admin quick-edit of the shared definition).
1001
+ - 18d0339: Relabel metadata-driven UI on a language switch without a page refresh (#1319)
1002
+
1003
+ Switching the UI language left server-resolved metadata labels (object/field/
1004
+ view labels, action-dialog text) in the old language until a hard refresh,
1005
+ because renderers cache those labels by object name and never refetch on a
1006
+ language change.
1007
+
1008
+ **`@object-ui/auth`** — `createAuthenticatedFetch` now folds the active
1009
+ `<html lang>` into `Accept-Language` on API calls (never clobbering an explicit
1010
+ header), so a switch carries the new locale on every subsequent request.
1011
+
1012
+ **`@object-ui/app-shell`** — `ConnectedShellInner` drops the adapter's
1013
+ locale-blind metadata cache in the render phase and remounts the metadata
1014
+ subtree via `key={language}`, so every renderer refetches in the new locale.
1015
+ The adapter and its connection sit above the key and are preserved — an in-app
1016
+ relabel, not a reconnect.
1017
+
1018
+ **`@object-ui/i18n`** — dev-mode missing-key warnings: `createI18n` gains
1019
+ `warnMissingKeys` (default on outside production) wiring a deduped i18next
1020
+ `missingKeyHandler`. `useObjectLabel`'s convention-key probes are flagged so
1021
+ their intentional misses (which fall back to server metadata) stay silent.
1022
+
1023
+ Pairs with the framework-side locale-aware metadata changes in
1024
+ `@objectstack/client` / `@objectstack/objectql` / `@objectstack/rest`.
1025
+
1026
+ - 59b6bbb: i18n the managed-by empty states for system / append-only / better-auth object lists.
1027
+
1028
+ `resolveManagedByEmptyState` previously hardcoded English titles and messages (e.g. "No identity records", "No events recorded"), so list views for managed objects (identity, audit logs, system-generated records) rendered English regardless of locale. It now takes the `t` translator and resolves `list.managedBy.{system,appendOnly,betterAuth}.{title,message}` (English kept as `defaultValue` fallbacks); `ObjectView` passes its `t` through. Added the keys to the `en` and `zh` locale packs.
1029
+
1030
+ - e95cc25: Fix the NavigationSyncEffect baseline race: lazily-loaded `page`/`dashboard` metadata (and the empty cache during `invalidate()` refetch) could seed a partial diff baseline, making platform `sys_` pages look "user added" — the effect then wrote them into every app's navigation, 403ing on ADR-0010 locked apps (red "Failed to update navigation" toasts) and polluting writable apps. The effect now diffs only while both types are `status === 'ready'` (new optional `MetadataContextValue.getTypeStatus`), never treats `sys_`-prefixed artifacts as user creations, and skips apps whose `_lock`/`protection.lock` is `full`/`no-overlay`.
1031
+ - e265a40: fix(app-shell): resolve 51 react-hooks/rules-of-hooks errors in ObjectView
1032
+
1033
+ ObjectView had a mid-component early return (`if (!objectDef) return …`) sitting before ~50 hooks, which violated the Rules of Hooks and risked a `Rendered fewer hooks than expected` crash if `objectDef` flipped present→absent→present on a live instance (object switch, metadata refresh, reload failure). Split the component so the missing-object empty state lives in a thin `ObjectView` wrapper, while `ObjectViewInner` (mounted only when the definition exists) calls all hooks unconditionally. Behavior is unchanged.
1034
+
1035
+ - 42e557a: "Your organization" Install routes by deployment shape: install-local runtimes (runtime-config `features.installLocal`) install via `/marketplace/install-local` into their OWN kernel (the bound oscc\_ credential fetches the org manifest — ADR-0008); cloud-managed environments keep the control-plane `/cloud-connection/install` path. Previously the org Install button always called the control-plane path, which 401s on self-hosted runtimes.
1036
+ - af74a5d: Add an admin-only "Edit in studio" affordance to the runtime PageView. Custom pages are authored in the metadata studio (canvas + inspector), not at runtime — so instead of embedding the heavyweight page canvas, PageView now shows a lightweight top-right button (admins only) that deep-links to the page's studio editor (`/apps/:app/metadata/page/:name`). This gives view/report/dashboard/page a consistent runtime admin edit entry point.
1037
+ - 3cc38fe: perf(detail/header): lazy + dedupe related-list fan-out, coalesce header polls
1038
+
1039
+ Opening a record detail fired ~50 concurrent `/api/v1` requests that
1040
+ head-of-line-blocked one another on a single control-plane container.
1041
+
1042
+ - `RecordDetailView` no longer eager-preloads reverse-reference children
1043
+ when the reference rail renders them (that data was discarded while the
1044
+ rail re-fetched the same collections).
1045
+ - `record:reference_rail` now gates fetching on visibility
1046
+ (`IntersectionObserver`; the rail is `hidden xl:flex`), caps concurrency
1047
+ at 3, and fetches once per `(parentId + entries)` via a signature guard,
1048
+ applying results through a mounted ref.
1049
+ - `AppHeader` inbox/notification, approvals, and activity pollers gained
1050
+ in-flight guards so bootstrap effect re-runs coalesce to one request; the
1051
+ approvals poll now sends one request with all identities comma-joined
1052
+ instead of one per identity.
1053
+
1054
+ Measured locally: opening an environment detail dropped from ~52 to ~17
1055
+ requests, related collections from ×3–5 each to ×1, approvals from ×9 to ≤3.
1056
+
1057
+ - 053a164: fix(metadata): keep form-family views out of the runtime list-view switcher
1058
+
1059
+ The backend now exposes each view as an independent **ViewItem** (ADR-0017,
1060
+ "Object has-many View"): `{ name: '<object>.<key>', object, viewKind:
1061
+ 'list' | 'form', config }`. The Studio preview was already taught this shape,
1062
+ but the runtime console path was not — `MetadataProvider.mergeViewsIntoObjects`
1063
+ only understood the legacy aggregated container (`{ list, form, listViews,
1064
+ formViews }`) and ignored `viewKind` entirely. As a result a form-family view
1065
+ (e.g. `crm_activity.default`, expanded from `formViews.default`) was neither
1066
+ recognized nor excluded: navigating to its `/view/<name>` URL silently fell
1067
+ back to the default grid list instead of being treated as a record form.
1068
+
1069
+ `mergeViewsIntoObjects` now recognizes the ViewItem shape and routes by
1070
+ `viewKind` — `'list'` → `objectDef.listViews`, `'form'` → `objectDef.formViews`
1071
+ — so FORM-family views never enter the list-view switcher (which reads only
1072
+ `listViews`). Each item's `config` body is flattened to the renderer shape so
1073
+ `type`/`columns`/`calendar`/… survive, the canonical `<object>.<key>` name is
1074
+ used as the view id (so `/view/<name>` resolves), and the legacy container is
1075
+ skipped for any object that already has expanded ViewItems (no double-listing).
1076
+ Objects served only as a legacy container are unaffected.
1077
+
1078
+ - db8cd00: feat(app-shell): global settle signal (window.\_\_objectui) + region aria-busy (ADR-0054 Phase 3)
1079
+
1080
+ Adds a single machine-readable "is the app idle?" predicate (ADR-0054 C5). The
1081
+ data layer wraps the adapter's `fetch` to count in-flight requests, mirrored onto
1082
+ `window.__objectui` with live `idle` / `pendingRequests` getters plus `whenIdle()`
1083
+ and `subscribe()`. New `useSettleSignal()` React hook and lower-level exports
1084
+ (`getPendingRequests`, `subscribeSettle`, `whenIdle`, `withSettleSignal`,
1085
+ `installSettleSignalGlobal`). The list view and record-picker results regions now
1086
+ set `aria-busy` while fetching and `data-state="loading|idle"` for region-level
1087
+ waiting. Lets an automated (AI) driver wait for settle instead of hardcoding
1088
+ timeouts.
1089
+
1090
+ - 2f31406: Refine Studio package-scoped navigation and home overview.
1091
+
1092
+ Studio now treats the selected package as the home overview scope, flattens the root Overview sidebar group, hides the duplicate all-metadata sidebar entry, redirects the invalid package metadata route to package management, preserves the selected package across package-management navigation, and adds a localized package-management sidebar label.
1093
+
1094
+ - d901f65: feat(app-shell): testability ratchet — ban synthetic-event triggers (ADR-0054 Phase 5)
1095
+
1096
+ Locks in the testability contract so it can't regress. A conformance test (in the
1097
+ gating `pnpm test` job) fails the build if a new synthetic-event trigger
1098
+ (`dispatchEvent(new KeyboardEvent/MouseEvent/PointerEvent)`) appears anywhere in
1099
+ `packages/*/src` or `apps/*/src`; a matching local ESLint rule
1100
+ (`object-ui/no-synthetic-event-trigger`) flags it in-editor. The last two
1101
+ offenders — the sidebar swipe-to-open gestures (`UnifiedSidebar`, `AppSidebar`)
1102
+ — are converted to a direct, idempotent `setOpenMobile(true)` (C1), so the tree
1103
+ is clean at zero. Completes the ADR-0054 rollout.
1104
+
1105
+ - 8d1195d: Fix `type: 'url'` actions so they actually reach the backend in split-origin dev setups, and so reveal-once result dialogs render.
1106
+
1107
+ - `ActionRunner.executeUrl`: when context provides `apiBase`, relative `/api/...`, `/_auth/...`, and `/_account/...` URLs are now promoted to absolute (`${apiBase}${path}`) before navigation. Same-origin API paths (with or without `apiBase`) trigger a full-page `window.location.href` rather than React-Router push — this is required for server-side OAuth redirect dances (e.g. better-auth `/sign-in/social`) that React Router would otherwise swallow into the SPA's fallback route.
1108
+ - `ActionRunner.buildInterpolationContext`: surfaces `ctx.apiBase` for action targets that want to template it explicitly.
1109
+ - `ObjectView`: passes `apiBase: import.meta.env.VITE_SERVER_URL` into the toolbar `ActionProvider` context so the above resolves.
1110
+ - `action-button` and `action-menu` renderers now forward `resultDialog` when invoking the runner. Previously this field was silently dropped by an explicit whitelist, breaking every "show once, then hide" flow (2FA QR/backup codes, OAuth client_secret, regenerated tokens).
1111
+
1112
+ - 5ab52c0: feat(app-shell): useUrlOverlay primitive + URL-addressable keyboard-shortcuts dialog (ADR-0054 Phase 2)
1113
+
1114
+ Adds `useUrlOverlay(key)` — a reusable, router-aware hook that stores a navigable
1115
+ overlay's open state in a `?<key>=1` URL param (idempotent open, deep-linkable,
1116
+ restore-on-reload, back/forward; `alias`/`value`/`replace` configurable). The
1117
+ command palette is refactored onto it (behavior unchanged: `?palette=1`, `?cmdk=1`
1118
+ alias). The keyboard-shortcuts dialog becomes URL-addressable (`?shortcuts=1`) and
1119
+ gains a click entry in the header Help menu — previously it was only reachable via
1120
+ the `?` key (which remains an accelerator). Generalizes ADR-0054 invariants C1/C3
1121
+ beyond the Phase 1 reference fix; the shared overlay primitives already carry
1122
+ `data-testid` + Radix `data-state`, documented in the README.
1123
+
1124
+ - ef3c654: Localize the View variant inspector labels. The inspector (the View "home" panel, also hosted by the runtime ObjectView right-rail view editor after the spec-driven migration) previously rendered hardcoded English labels — "Label", "View type", "Object", the view-type dropdown options, and the "spec schema unavailable" hint. These now route through the metadata-admin i18n catalog (en + zh) so the runtime console and the studio both display localized text.
1125
+ - Updated dependencies [5976ba3]
1126
+ - Updated dependencies [a00e16d]
1127
+ - Updated dependencies [eaccefd]
1128
+ - Updated dependencies [f7f325d]
1129
+ - Updated dependencies [c12986e]
1130
+ - Updated dependencies [71d7ce0]
1131
+ - Updated dependencies [0c95963]
1132
+ - Updated dependencies [30ee761]
1133
+ - Updated dependencies [81c0777]
1134
+ - Updated dependencies [053c948]
1135
+ - Updated dependencies [b99d9bd]
1136
+ - Updated dependencies [053c948]
1137
+ - Updated dependencies [89e113c]
1138
+ - Updated dependencies [ddbe4a2]
1139
+ - Updated dependencies [2d47e94]
1140
+ - Updated dependencies [c5a7d6f]
1141
+ - Updated dependencies [40c79df]
1142
+ - Updated dependencies [9049bbe]
1143
+ - Updated dependencies [053c948]
1144
+ - Updated dependencies [053c948]
1145
+ - Updated dependencies [77cc6bb]
1146
+ - Updated dependencies [6c0c92c]
1147
+ - Updated dependencies [97c6831]
1148
+ - Updated dependencies [cb2fdb1]
1149
+ - Updated dependencies [a58c6b8]
1150
+ - Updated dependencies [c3749eb]
1151
+ - Updated dependencies [39c89e7]
1152
+ - Updated dependencies [78f9c16]
1153
+ - Updated dependencies [92449ef]
1154
+ - Updated dependencies [c09f44e]
1155
+ - Updated dependencies [f6044fa]
1156
+ - Updated dependencies [3d036a9]
1157
+ - Updated dependencies [6cfa330]
1158
+ - Updated dependencies [ad8ade6]
1159
+ - Updated dependencies [e270c7d]
1160
+ - Updated dependencies [ab168e4]
1161
+ - Updated dependencies [d54346c]
1162
+ - Updated dependencies [5332639]
1163
+ - Updated dependencies [3870c20]
1164
+ - Updated dependencies [2eb3096]
1165
+ - Updated dependencies [b88c560]
1166
+ - Updated dependencies [0ad72a6]
1167
+ - Updated dependencies [bd398df]
1168
+ - Updated dependencies [3fa23a7]
1169
+ - Updated dependencies [18d0339]
1170
+ - Updated dependencies [66ed3ad]
1171
+ - Updated dependencies [c6445b6]
1172
+ - Updated dependencies [80c133c]
1173
+ - Updated dependencies [5e1b838]
1174
+ - Updated dependencies [59b6bbb]
1175
+ - Updated dependencies [d16566f]
1176
+ - Updated dependencies [69510df]
1177
+ - Updated dependencies [b148daf]
1178
+ - Updated dependencies [90acb7f]
1179
+ - Updated dependencies [7913390]
1180
+ - Updated dependencies [514f426]
1181
+ - Updated dependencies [586a027]
1182
+ - Updated dependencies [00f8d2d]
1183
+ - Updated dependencies [9aac2b8]
1184
+ - Updated dependencies [1394e34]
1185
+ - Updated dependencies [e95cc25]
1186
+ - Updated dependencies [abe8ebc]
1187
+ - Updated dependencies [300d755]
1188
+ - Updated dependencies [3cc38fe]
1189
+ - Updated dependencies [bd8b054]
1190
+ - Updated dependencies [053c948]
1191
+ - Updated dependencies [053c948]
1192
+ - Updated dependencies [4eb9cb6]
1193
+ - Updated dependencies [7c239fd]
1194
+ - Updated dependencies [858ad94]
1195
+ - Updated dependencies [c849d3b]
1196
+ - Updated dependencies [7b71cd8]
1197
+ - Updated dependencies [2270239]
1198
+ - Updated dependencies [db8cd00]
1199
+ - Updated dependencies [650bd1f]
1200
+ - Updated dependencies [f011479]
1201
+ - Updated dependencies [2f31406]
1202
+ - Updated dependencies [18728c1]
1203
+ - Updated dependencies [8426db7]
1204
+ - Updated dependencies [8d1195d]
1205
+ - Updated dependencies [9bef806]
1206
+ - @object-ui/core@7.0.0
1207
+ - @object-ui/components@7.0.0
1208
+ - @object-ui/plugin-grid@7.0.0
1209
+ - @object-ui/plugin-detail@7.0.0
1210
+ - @object-ui/react@7.0.0
1211
+ - @object-ui/plugin-report@7.0.0
1212
+ - @object-ui/data-objectstack@7.0.0
1213
+ - @object-ui/plugin-chatbot@7.0.0
1214
+ - @object-ui/plugin-list@7.0.0
1215
+ - @object-ui/i18n@7.0.0
1216
+ - @object-ui/types@7.0.0
1217
+ - @object-ui/plugin-form@7.0.0
1218
+ - @object-ui/fields@7.0.0
1219
+ - @object-ui/plugin-charts@7.0.0
1220
+ - @object-ui/plugin-dashboard@7.0.0
1221
+ - @object-ui/auth@7.0.0
1222
+ - @object-ui/plugin-view@7.0.0
1223
+ - @object-ui/layout@7.0.0
1224
+ - @object-ui/plugin-calendar@7.0.0
1225
+ - @object-ui/plugin-designer@7.0.0
1226
+ - @object-ui/plugin-editor@7.0.0
1227
+ - @object-ui/plugin-kanban@7.0.0
1228
+ - @object-ui/collaboration@7.0.0
1229
+ - @object-ui/permissions@7.0.0
1230
+ - @object-ui/providers@7.0.0
1231
+
3
1232
  ## 6.2.3
4
1233
 
5
1234
  ### Patch Changes