@object-ui/app-shell 6.2.2 → 7.0.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 (468) hide show
  1. package/CHANGELOG.md +967 -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 +170 -37
  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 +743 -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 +22 -0
  27. package/dist/console/ai/LiveCanvas.js +78 -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 +107 -4
  90. package/dist/hooks/useChatConversation.js +253 -25
  91. package/dist/hooks/useConsoleActionRuntime.d.ts +70 -0
  92. package/dist/hooks/useConsoleActionRuntime.js +560 -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 +16 -7
  110. package/dist/index.js +12 -4
  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 +32 -2
  124. package/dist/layout/ConsoleFloatingChatbot.js +374 -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 +218 -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/observability/index.d.ts +1 -0
  140. package/dist/observability/index.js +1 -0
  141. package/dist/observability/settleSignal.d.ts +64 -0
  142. package/dist/observability/settleSignal.js +131 -0
  143. package/dist/preview/DraftChangesPanel.d.ts +19 -0
  144. package/dist/preview/DraftChangesPanel.js +114 -0
  145. package/dist/preview/DraftPreviewBar.d.ts +8 -0
  146. package/dist/preview/DraftPreviewBar.js +86 -0
  147. package/dist/preview/PreviewDraftEmptyState.d.ts +16 -0
  148. package/dist/preview/PreviewDraftEmptyState.js +47 -0
  149. package/dist/preview/PreviewModeContext.d.ts +57 -0
  150. package/dist/preview/PreviewModeContext.js +99 -0
  151. package/dist/preview/UnpublishedAppBar.d.ts +8 -0
  152. package/dist/preview/UnpublishedAppBar.js +79 -0
  153. package/dist/preview/draftStatus.d.ts +20 -0
  154. package/dist/preview/draftStatus.js +27 -0
  155. package/dist/preview/usePublishAllDrafts.d.ts +18 -0
  156. package/dist/preview/usePublishAllDrafts.js +106 -0
  157. package/dist/providers/AdapterProvider.d.ts +1 -1
  158. package/dist/providers/AdapterProvider.js +6 -1
  159. package/dist/providers/ExpressionProvider.d.ts +1 -1
  160. package/dist/providers/MetadataProvider.d.ts +17 -2
  161. package/dist/providers/MetadataProvider.js +183 -12
  162. package/dist/runtime-config.d.ts +46 -2
  163. package/dist/runtime-config.js +39 -2
  164. package/dist/services/builtinComponents.js +68 -59
  165. package/dist/skeletons/SkeletonDashboard.d.ts +1 -1
  166. package/dist/skeletons/SkeletonDetail.d.ts +1 -1
  167. package/dist/skeletons/SkeletonGrid.d.ts +1 -1
  168. package/dist/utils/appRoute.d.ts +21 -0
  169. package/dist/utils/appRoute.js +25 -0
  170. package/dist/utils/deriveRelatedLists.d.ts +54 -0
  171. package/dist/utils/deriveRelatedLists.js +91 -0
  172. package/dist/utils/index.d.ts +4 -0
  173. package/dist/utils/index.js +3 -0
  174. package/dist/utils/managedByEmptyState.d.ts +8 -1
  175. package/dist/utils/managedByEmptyState.js +13 -7
  176. package/dist/utils/preferLocal.d.ts +18 -0
  177. package/dist/utils/preferLocal.js +24 -0
  178. package/dist/views/ActionConfirmDialog.d.ts +1 -1
  179. package/dist/views/ActionConfirmDialog.js +3 -1
  180. package/dist/views/ActionParamDialog.d.ts +6 -1
  181. package/dist/views/ActionParamDialog.js +9 -3
  182. package/dist/views/ActionResultDialog.d.ts +13 -0
  183. package/dist/views/ActionResultDialog.js +134 -0
  184. package/dist/views/ComponentNavView.d.ts +14 -1
  185. package/dist/views/CreateViewDialog.d.ts +1 -1
  186. package/dist/views/DashboardConfigPanel.d.ts +28 -0
  187. package/dist/views/DashboardConfigPanel.js +81 -0
  188. package/dist/views/DashboardView.d.ts +4 -3
  189. package/dist/views/DashboardView.js +38 -239
  190. package/dist/views/FlowRunner.d.ts +59 -0
  191. package/dist/views/FlowRunner.js +153 -0
  192. package/dist/views/InterfaceListPage.d.ts +49 -0
  193. package/dist/views/InterfaceListPage.js +347 -0
  194. package/dist/views/MetadataInspector.d.ts +2 -2
  195. package/dist/views/ObjectView.d.ts +1 -1
  196. package/dist/views/ObjectView.js +209 -532
  197. package/dist/views/PageView.d.ts +8 -3
  198. package/dist/views/PageView.js +45 -32
  199. package/dist/views/RecordDetailView.d.ts +1 -1
  200. package/dist/views/RecordDetailView.js +363 -148
  201. package/dist/views/RecordFormPage.d.ts +1 -1
  202. package/dist/views/RecordFormPage.js +26 -1
  203. package/dist/views/ReportConfigPanel.d.ts +37 -0
  204. package/dist/views/ReportConfigPanel.js +85 -0
  205. package/dist/views/ReportView.d.ts +1 -1
  206. package/dist/views/ReportView.js +116 -7
  207. package/dist/views/RuntimeDraftBar.d.ts +30 -0
  208. package/dist/views/RuntimeDraftBar.js +112 -0
  209. package/dist/views/SearchResultsPage.d.ts +1 -1
  210. package/dist/views/SearchResultsPage.js +8 -18
  211. package/dist/views/ViewConfigPanel.d.ts +24 -17
  212. package/dist/views/ViewConfigPanel.js +121 -77
  213. package/dist/views/index.d.ts +1 -1
  214. package/dist/views/index.js +1 -1
  215. package/dist/views/metadata-admin/AuditPanel.d.ts +28 -0
  216. package/dist/views/metadata-admin/AuditPanel.js +79 -0
  217. package/dist/views/metadata-admin/DiagnosticsPage.d.ts +20 -0
  218. package/dist/views/metadata-admin/DiagnosticsPage.js +69 -0
  219. package/dist/views/metadata-admin/DirectoryPage.d.ts +16 -1
  220. package/dist/views/metadata-admin/DirectoryPage.js +113 -24
  221. package/dist/views/metadata-admin/DraftReviewPanel.d.ts +33 -0
  222. package/dist/views/metadata-admin/DraftReviewPanel.js +77 -0
  223. package/dist/views/metadata-admin/EmbeddedItemEditor.d.ts +17 -1
  224. package/dist/views/metadata-admin/EmbeddedItemEditor.js +15 -8
  225. package/dist/views/metadata-admin/JsonSourceEditor.d.ts +37 -0
  226. package/dist/views/metadata-admin/JsonSourceEditor.js +178 -0
  227. package/dist/views/metadata-admin/LayeredDiff.d.ts +39 -1
  228. package/dist/views/metadata-admin/LayeredDiff.js +171 -5
  229. package/dist/views/metadata-admin/MetadataDetailDrawer.d.ts +15 -1
  230. package/dist/views/metadata-admin/MetadataTypeActions.d.ts +48 -0
  231. package/dist/views/metadata-admin/MetadataTypeActions.js +165 -0
  232. package/dist/views/metadata-admin/PackagesPage.d.ts +18 -0
  233. package/dist/views/metadata-admin/PackagesPage.js +395 -0
  234. package/dist/views/metadata-admin/PageShell.d.ts +1 -1
  235. package/dist/views/metadata-admin/PageShell.js +9 -4
  236. package/dist/views/metadata-admin/PermissionMatrixEditor.d.ts +35 -1
  237. package/dist/views/metadata-admin/QuickFind.d.ts +21 -1
  238. package/dist/views/metadata-admin/QuickFind.js +6 -3
  239. package/dist/views/metadata-admin/RelatedPanel.d.ts +24 -1
  240. package/dist/views/metadata-admin/RelatedPanel.js +20 -18
  241. package/dist/views/metadata-admin/ResourceEditPage.d.ts +40 -1
  242. package/dist/views/metadata-admin/ResourceEditPage.js +1223 -60
  243. package/dist/views/metadata-admin/ResourceHistoryPage.d.ts +39 -1
  244. package/dist/views/metadata-admin/ResourceHistoryPage.js +66 -16
  245. package/dist/views/metadata-admin/ResourceListPage.d.ts +13 -1
  246. package/dist/views/metadata-admin/ResourceListPage.js +266 -30
  247. package/dist/views/metadata-admin/ResourceRouter.d.ts +23 -1
  248. package/dist/views/metadata-admin/SchemaForm.d.ts +34 -1
  249. package/dist/views/metadata-admin/SchemaForm.js +559 -49
  250. package/dist/views/metadata-admin/StudioHomePage.d.ts +22 -0
  251. package/dist/views/metadata-admin/StudioHomePage.js +213 -0
  252. package/dist/views/metadata-admin/anchors.js +237 -24
  253. package/dist/views/metadata-admin/clientValidation.d.ts +50 -0
  254. package/dist/views/metadata-admin/clientValidation.js +169 -0
  255. package/dist/views/metadata-admin/color-variant-field.d.ts +30 -0
  256. package/dist/views/metadata-admin/color-variant-field.js +38 -0
  257. package/dist/views/metadata-admin/createDerive.d.ts +75 -0
  258. package/dist/views/metadata-admin/createDerive.js +179 -0
  259. package/dist/views/metadata-admin/dashboard-schema.d.ts +12 -0
  260. package/dist/views/metadata-admin/dashboard-schema.js +80 -0
  261. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.d.ts +35 -0
  262. package/dist/views/metadata-admin/datasource/DatasourceResourcePage.js +327 -0
  263. package/dist/views/metadata-admin/datasource/register.d.ts +1 -0
  264. package/dist/views/metadata-admin/datasource/register.js +24 -0
  265. package/dist/views/metadata-admin/default-inspector-registry.d.ts +49 -0
  266. package/dist/views/metadata-admin/default-inspector-registry.js +8 -0
  267. package/dist/views/metadata-admin/default-schemas.js +115 -10
  268. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.d.ts +27 -0
  269. package/dist/views/metadata-admin/external/ExternalDatasourcePanel.js +69 -0
  270. package/dist/views/metadata-admin/external/ImportObjectDialog.d.ts +27 -0
  271. package/dist/views/metadata-admin/external/ImportObjectDialog.js +77 -0
  272. package/dist/views/metadata-admin/external/SchemaBrowser.d.ts +16 -0
  273. package/dist/views/metadata-admin/external/SchemaBrowser.js +74 -0
  274. package/dist/views/metadata-admin/external/ValidationPanel.d.ts +16 -0
  275. package/dist/views/metadata-admin/external/ValidationPanel.js +68 -0
  276. package/dist/views/metadata-admin/external/api.d.ts +100 -0
  277. package/dist/views/metadata-admin/external/api.js +124 -0
  278. package/dist/views/metadata-admin/i18n.d.ts +1 -0
  279. package/dist/views/metadata-admin/i18n.js +1166 -2
  280. package/dist/views/metadata-admin/index.d.ts +8 -5
  281. package/dist/views/metadata-admin/index.js +12 -2
  282. package/dist/views/metadata-admin/inspector-registry.d.ts +51 -0
  283. package/dist/views/metadata-admin/inspector-registry.js +11 -0
  284. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.d.ts +30 -0
  285. package/dist/views/metadata-admin/inspectors/ActionDefaultInspector.js +180 -0
  286. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +16 -0
  287. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +110 -0
  288. package/dist/views/metadata-admin/inspectors/ConditionBuilder.d.ts +29 -0
  289. package/dist/views/metadata-admin/inspectors/ConditionBuilder.js +154 -0
  290. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.d.ts +28 -0
  291. package/dist/views/metadata-admin/inspectors/DashboardDefaultInspector.js +110 -0
  292. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.d.ts +18 -0
  293. package/dist/views/metadata-admin/inspectors/DashboardWidgetInspector.js +139 -0
  294. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.d.ts +21 -0
  295. package/dist/views/metadata-admin/inspectors/DatasetDefaultInspector.js +107 -0
  296. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.d.ts +16 -0
  297. package/dist/views/metadata-admin/inspectors/FlowEdgeInspector.js +45 -0
  298. package/dist/views/metadata-admin/inspectors/FlowInspector.d.ts +12 -0
  299. package/dist/views/metadata-admin/inspectors/FlowInspector.js +9 -0
  300. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.d.ts +30 -0
  301. package/dist/views/metadata-admin/inspectors/FlowKeyValueField.js +125 -0
  302. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.d.ts +18 -0
  303. package/dist/views/metadata-admin/inspectors/FlowNodeConfigField.js +40 -0
  304. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.d.ts +14 -0
  305. package/dist/views/metadata-admin/inspectors/FlowNodeInspector.js +140 -0
  306. package/dist/views/metadata-admin/inspectors/FlowObjectListField.d.ts +26 -0
  307. package/dist/views/metadata-admin/inspectors/FlowObjectListField.js +105 -0
  308. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +83 -0
  309. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +181 -0
  310. package/dist/views/metadata-admin/inspectors/FlowStringListField.d.ts +21 -0
  311. package/dist/views/metadata-admin/inspectors/FlowStringListField.js +60 -0
  312. package/dist/views/metadata-admin/inspectors/InspectorComboField.d.ts +40 -0
  313. package/dist/views/metadata-admin/inspectors/InspectorComboField.js +61 -0
  314. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.d.ts +21 -0
  315. package/dist/views/metadata-admin/inspectors/ObjectDefaultInspector.js +54 -0
  316. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.d.ts +23 -0
  317. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +330 -0
  318. package/dist/views/metadata-admin/inspectors/PageBlockInspector.d.ts +48 -0
  319. package/dist/views/metadata-admin/inspectors/PageBlockInspector.js +332 -0
  320. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.d.ts +58 -0
  321. package/dist/views/metadata-admin/inspectors/ReportDefaultInspector.js +160 -0
  322. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.d.ts +19 -0
  323. package/dist/views/metadata-admin/inspectors/ViewColumnInspector.js +144 -0
  324. package/dist/views/metadata-admin/inspectors/ViewInspector.d.ts +19 -0
  325. package/dist/views/metadata-admin/inspectors/ViewInspector.js +21 -0
  326. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.d.ts +54 -0
  327. package/dist/views/metadata-admin/inspectors/ViewVariantInspector.js +191 -0
  328. package/dist/views/metadata-admin/inspectors/_shared.d.ts +124 -0
  329. package/dist/views/metadata-admin/inspectors/_shared.js +113 -0
  330. package/dist/views/metadata-admin/inspectors/expression-validate.d.ts +26 -0
  331. package/dist/views/metadata-admin/inspectors/expression-validate.js +66 -0
  332. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +143 -0
  333. package/dist/views/metadata-admin/inspectors/flow-node-config.js +461 -0
  334. package/dist/views/metadata-admin/inspectors/index.d.ts +1 -0
  335. package/dist/views/metadata-admin/inspectors/index.js +45 -0
  336. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.d.ts +40 -0
  337. package/dist/views/metadata-admin/inspectors/json-schema-to-fields.js +227 -0
  338. package/dist/views/metadata-admin/inspectors/useDatasetFields.d.ts +72 -0
  339. package/dist/views/metadata-admin/inspectors/useDatasetFields.js +0 -0
  340. package/dist/views/metadata-admin/mergeServerFields.d.ts +65 -0
  341. package/dist/views/metadata-admin/mergeServerFields.js +56 -0
  342. package/dist/views/metadata-admin/preview-registry.d.ts +55 -0
  343. package/dist/views/metadata-admin/previews/ActionPreview.d.ts +25 -0
  344. package/dist/views/metadata-admin/previews/ActionPreview.js +238 -0
  345. package/dist/views/metadata-admin/previews/AddWidgetPicker.d.ts +12 -0
  346. package/dist/views/metadata-admin/previews/AddWidgetPicker.js +56 -0
  347. package/dist/views/metadata-admin/previews/AgentPreview.d.ts +24 -0
  348. package/dist/views/metadata-admin/previews/AgentPreview.js +100 -0
  349. package/dist/views/metadata-admin/previews/AppNavCanvas.d.ts +31 -0
  350. package/dist/views/metadata-admin/previews/AppNavCanvas.js +260 -0
  351. package/dist/views/metadata-admin/previews/AppPreview.d.ts +16 -1
  352. package/dist/views/metadata-admin/previews/AppPreview.js +23 -14
  353. package/dist/views/metadata-admin/previews/BookPreview.d.ts +20 -0
  354. package/dist/views/metadata-admin/previews/BookPreview.js +132 -0
  355. package/dist/views/metadata-admin/previews/DashboardPreview.d.ts +16 -1
  356. package/dist/views/metadata-admin/previews/DashboardPreview.js +110 -8
  357. package/dist/views/metadata-admin/previews/DatasetPreview.d.ts +18 -0
  358. package/dist/views/metadata-admin/previews/DatasetPreview.js +89 -0
  359. package/dist/views/metadata-admin/previews/DatasourcePreview.d.ts +23 -0
  360. package/dist/views/metadata-admin/previews/DatasourcePreview.js +68 -0
  361. package/dist/views/metadata-admin/previews/EmailTemplatePreview.d.ts +14 -1
  362. package/dist/views/metadata-admin/previews/FieldStub.d.ts +30 -0
  363. package/dist/views/metadata-admin/previews/FieldStub.js +104 -0
  364. package/dist/views/metadata-admin/previews/FieldsListEditor.d.ts +50 -0
  365. package/dist/views/metadata-admin/previews/FieldsListEditor.js +97 -0
  366. package/dist/views/metadata-admin/previews/FlowCanvas.d.ts +43 -0
  367. package/dist/views/metadata-admin/previews/FlowCanvas.js +328 -0
  368. package/dist/views/metadata-admin/previews/FlowPreview.d.ts +20 -0
  369. package/dist/views/metadata-admin/previews/FlowPreview.js +92 -0
  370. package/dist/views/metadata-admin/previews/FlowRunsPanel.d.ts +46 -0
  371. package/dist/views/metadata-admin/previews/FlowRunsPanel.js +97 -0
  372. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.d.ts +25 -0
  373. package/dist/views/metadata-admin/previews/FlowSimulatorPanel.js +170 -0
  374. package/dist/views/metadata-admin/previews/JobPreview.d.ts +28 -0
  375. package/dist/views/metadata-admin/previews/JobPreview.js +290 -0
  376. package/dist/views/metadata-admin/previews/ObjectFormCanvas.d.ts +30 -0
  377. package/dist/views/metadata-admin/previews/ObjectFormCanvas.js +547 -0
  378. package/dist/views/metadata-admin/previews/ObjectPreview.d.ts +14 -1
  379. package/dist/views/metadata-admin/previews/ObjectPreview.js +5 -30
  380. package/dist/views/metadata-admin/previews/OutlineStrip.d.ts +32 -0
  381. package/dist/views/metadata-admin/previews/OutlineStrip.js +8 -0
  382. package/dist/views/metadata-admin/previews/PageBlockCanvas.d.ts +49 -0
  383. package/dist/views/metadata-admin/previews/PageBlockCanvas.js +510 -0
  384. package/dist/views/metadata-admin/previews/PagePreview.d.ts +10 -1
  385. package/dist/views/metadata-admin/previews/PagePreview.js +90 -4
  386. package/dist/views/metadata-admin/previews/PermissionPreview.d.ts +27 -0
  387. package/dist/views/metadata-admin/previews/PermissionPreview.js +115 -0
  388. package/dist/views/metadata-admin/previews/PreviewShell.d.ts +29 -6
  389. package/dist/views/metadata-admin/previews/PreviewShell.js +16 -3
  390. package/dist/views/metadata-admin/previews/ReportPreview.d.ts +18 -1
  391. package/dist/views/metadata-admin/previews/ReportPreview.js +23 -15
  392. package/dist/views/metadata-admin/previews/RolePreview.d.ts +19 -0
  393. package/dist/views/metadata-admin/previews/RolePreview.js +14 -0
  394. package/dist/views/metadata-admin/previews/SkillPreview.d.ts +22 -0
  395. package/dist/views/metadata-admin/previews/SkillPreview.js +34 -0
  396. package/dist/views/metadata-admin/previews/ToolPreview.d.ts +25 -0
  397. package/dist/views/metadata-admin/previews/ToolPreview.js +122 -0
  398. package/dist/views/metadata-admin/previews/TranslationPreview.d.ts +25 -0
  399. package/dist/views/metadata-admin/previews/TranslationPreview.js +52 -0
  400. package/dist/views/metadata-admin/previews/ValidationPreview.d.ts +27 -0
  401. package/dist/views/metadata-admin/previews/ValidationPreview.js +110 -0
  402. package/dist/views/metadata-admin/previews/ViewColumnPanes.d.ts +62 -0
  403. package/dist/views/metadata-admin/previews/ViewColumnPanes.js +140 -0
  404. package/dist/views/metadata-admin/previews/ViewPreview.d.ts +23 -1
  405. package/dist/views/metadata-admin/previews/ViewPreview.js +101 -73
  406. package/dist/views/metadata-admin/previews/block-config.d.ts +82 -0
  407. package/dist/views/metadata-admin/previews/block-config.js +324 -0
  408. package/dist/views/metadata-admin/previews/block-types.d.ts +40 -0
  409. package/dist/views/metadata-admin/previews/block-types.js +110 -0
  410. package/dist/views/metadata-admin/previews/field-types.d.ts +53 -0
  411. package/dist/views/metadata-admin/previews/field-types.js +97 -0
  412. package/dist/views/metadata-admin/previews/flow-canvas-layout.d.ts +88 -0
  413. package/dist/views/metadata-admin/previews/flow-canvas-layout.js +190 -0
  414. package/dist/views/metadata-admin/previews/flow-canvas-parts.d.ts +88 -0
  415. package/dist/views/metadata-admin/previews/flow-canvas-parts.js +358 -0
  416. package/dist/views/metadata-admin/previews/form-preview.d.ts +24 -0
  417. package/dist/views/metadata-admin/previews/form-preview.js +29 -0
  418. package/dist/views/metadata-admin/previews/index.js +43 -0
  419. package/dist/views/metadata-admin/previews/object-fields-bridge.d.ts +66 -0
  420. package/dist/views/metadata-admin/previews/object-fields-bridge.js +171 -0
  421. package/dist/views/metadata-admin/previews/object-fields-io.d.ts +109 -0
  422. package/dist/views/metadata-admin/previews/object-fields-io.js +208 -0
  423. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.d.ts +91 -0
  424. package/dist/views/metadata-admin/previews/simulator/flow-sim-types.js +2 -0
  425. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.d.ts +8 -0
  426. package/dist/views/metadata-admin/previews/simulator/flow-sim-validate.js +113 -0
  427. package/dist/views/metadata-admin/previews/simulator/flow-simulator.d.ts +44 -0
  428. package/dist/views/metadata-admin/previews/simulator/flow-simulator.js +316 -0
  429. package/dist/views/metadata-admin/previews/useDatasetCatalog.d.ts +47 -0
  430. package/dist/views/metadata-admin/previews/useDatasetCatalog.js +133 -0
  431. package/dist/views/metadata-admin/previews/useFlowNodePalette.d.ts +44 -0
  432. package/dist/views/metadata-admin/previews/useFlowNodePalette.js +124 -0
  433. package/dist/views/metadata-admin/previews/useMetaOptions.d.ts +8 -0
  434. package/dist/views/metadata-admin/previews/useMetaOptions.js +50 -0
  435. package/dist/views/metadata-admin/previews/useObjectFields.d.ts +23 -0
  436. package/dist/views/metadata-admin/previews/useObjectFields.js +79 -0
  437. package/dist/views/metadata-admin/previews/useObjectOptions.d.ts +8 -0
  438. package/dist/views/metadata-admin/previews/useObjectOptions.js +43 -0
  439. package/dist/views/metadata-admin/previews/view-column-io.d.ts +42 -0
  440. package/dist/views/metadata-admin/previews/view-column-io.js +73 -0
  441. package/dist/views/metadata-admin/previews/widget-types.d.ts +24 -0
  442. package/dist/views/metadata-admin/previews/widget-types.js +40 -0
  443. package/dist/views/metadata-admin/registry.d.ts +140 -19
  444. package/dist/views/metadata-admin/report-schema.d.ts +26 -0
  445. package/dist/views/metadata-admin/report-schema.js +121 -0
  446. package/dist/views/metadata-admin/useMetadata.d.ts +100 -2
  447. package/dist/views/metadata-admin/useMetadata.js +155 -4
  448. package/dist/views/metadata-admin/view-item-normalize.d.ts +20 -0
  449. package/dist/views/metadata-admin/view-item-normalize.js +68 -0
  450. package/dist/views/metadata-admin/view-schema.d.ts +16 -0
  451. package/dist/views/metadata-admin/view-schema.js +107 -0
  452. package/dist/views/metadata-admin/view-variant-model.d.ts +23 -0
  453. package/dist/views/metadata-admin/view-variant-model.js +64 -0
  454. package/dist/views/metadata-admin/widgets.d.ts +89 -1
  455. package/dist/views/metadata-admin/widgets.js +491 -17
  456. package/dist/views/runtime-metadata-persistence.d.ts +78 -0
  457. package/dist/views/runtime-metadata-persistence.js +89 -0
  458. package/dist/views/useOpenRecordList.d.ts +18 -0
  459. package/dist/views/useOpenRecordList.js +36 -0
  460. package/dist/views/userFilterUrlState.d.ts +15 -0
  461. package/dist/views/userFilterUrlState.js +53 -0
  462. package/dist/views/view-config-adapter.d.ts +38 -0
  463. package/dist/views/view-config-adapter.js +80 -0
  464. package/package.json +52 -34
  465. package/dist/views/DesignDrawer.d.ts +0 -28
  466. package/dist/views/DesignDrawer.js +0 -51
  467. package/dist/views/metadata-admin/DesignerEditorWrapper.d.ts +0 -68
  468. package/dist/views/metadata-admin/DesignerEditorWrapper.js +0 -158
@@ -8,15 +8,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  import { useEffect, useState } from 'react';
9
9
  import { useNavigate, useParams } from 'react-router-dom';
10
10
  import { Button, Badge, Card, CardContent, CardHeader, CardTitle, Skeleton, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Label, Checkbox, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, } from '@object-ui/components';
11
- import { ArrowLeft, ExternalLink, Download, AlertCircle, Package, Trash2, MoreHorizontal, CheckCircle2 } from 'lucide-react';
11
+ import { ArrowLeft, ExternalLink, Download, AlertCircle, Package, Trash2, MoreHorizontal, CheckCircle2, ArrowUpCircle, Database, Loader2 } from 'lucide-react';
12
12
  import { useIsWorkspaceAdmin } from '@object-ui/auth';
13
13
  import { useObjectTranslation } from '@object-ui/i18n';
14
14
  import { PackageIcon } from './PackageIcon';
15
15
  import { MarkdownText } from './MarkdownText';
16
+ import { PluginDisclosure } from './PluginDisclosure';
16
17
  import { MarketplaceAccessDenied } from './MarketplaceAccessDenied';
17
18
  import { localizePackage } from './usePackageL10n';
18
- import { getMarketplacePackage, installPackage, installLocal, uninstallLocal, listLocalInstalls, listCloudEnvironments, listInstallableOrgIds, cloudInstallDeepLink, } from './marketplaceApi';
19
+ import { getMarketplacePackage, installPackage, installLocal, uninstallLocal, listLocalInstalls, listCloudEnvironments, listInstallableOrgIds, cloudInstallDeepLink, getCloudInstallationInfo, reseedSampleData, purgeSampleData, reseedLocalSampleData, purgeLocalSampleData, } from './marketplaceApi';
19
20
  import { getRuntimeConfig } from '../../runtime-config';
21
+ import { emitMetadataRefresh } from '../../assistant/assistantBus';
20
22
  import { useMetadata } from '../../providers/MetadataProvider';
21
23
  export function MarketplacePackagePage() {
22
24
  const navigate = useNavigate();
@@ -33,9 +35,27 @@ export function MarketplacePackagePage() {
33
35
  const [envsLoading, setEnvsLoading] = useState(false);
34
36
  const [envsError, setEnvsError] = useState(null);
35
37
  const [selectedEnv, setSelectedEnv] = useState('');
38
+ // env id -> installed version, for annotating the picker with each env's
39
+ // current install state ("Installed v1.0.0" / "Update → v1.0.1"). Lets a
40
+ // multi-env operator see at a glance where this app already lives and which
41
+ // copies are out of date before choosing a target.
42
+ const [envInstallMap, setEnvInstallMap] = useState({});
36
43
  const [seedSampleData, setSeedSampleData] = useState(false);
44
+ // PD4: a code-bearing package requires explicit acknowledgement of its
45
+ // requested permissions before the install button is enabled.
46
+ const [acknowledged, setAcknowledged] = useState(false);
37
47
  const [installing, setInstalling] = useState(false);
38
48
  const [installResult, setInstallResult] = useState(null);
49
+ // Tracks whether the package has been installed into the current
50
+ // environment via the cloud install path. Used to flip the primary
51
+ // CTA from "Install to Cloud" → "Installed" so the user gets
52
+ // immediate feedback after a successful install. Seeded from the
53
+ // install response (which echoes the installation row) and from a
54
+ // boot-time fetch of sys_package_installation for the current env.
55
+ const [cloudInstalledVersion, setCloudInstalledVersion] = useState(null);
56
+ const [cloudInstall, setCloudInstall] = useState(null);
57
+ const [sampleDataBusy, setSampleDataBusy] = useState(null);
58
+ const [sampleDataMsg, setSampleDataMsg] = useState(null);
39
59
  // Local-install state (this runtime's own kernel — separate flow from cloud).
40
60
  const [localInstalls, setLocalInstalls] = useState([]);
41
61
  const [installingLocal, setInstallingLocal] = useState(false);
@@ -51,6 +71,29 @@ export function MarketplacePackagePage() {
51
71
  })();
52
72
  return () => { cancelled = true; };
53
73
  }, [packageId, localResult]);
74
+ // Seed cloud-install state so the primary CTA renders as "Installed" on
75
+ // first paint instead of inviting another install.
76
+ // NOTE: a tenant runtime (per-subdomain ObjectOS) has NO
77
+ // `defaultEnvironmentId` — but getCloudInstallationInfo's same-origin
78
+ // `/cloud-connection/installation` path resolves the env by hostname and
79
+ // does not need an explicit id (only the cloud-control-plane path needs
80
+ // one, and it no-ops on an empty id internally). So do NOT gate the probe
81
+ // on `currentEnvId` — that left the detail CTA stuck on "Install to
82
+ // cloud…" for every already-installed package in an env console.
83
+ useEffect(() => {
84
+ if (!packageId)
85
+ return;
86
+ const currentEnvId = getRuntimeConfig().defaultEnvironmentId ?? '';
87
+ let cancelled = false;
88
+ (async () => {
89
+ const info = await getCloudInstallationInfo(packageId, currentEnvId);
90
+ if (cancelled || !info)
91
+ return;
92
+ setCloudInstall(info);
93
+ setCloudInstalledVersion(info.version);
94
+ })();
95
+ return () => { cancelled = true; };
96
+ }, [packageId]);
54
97
  useEffect(() => {
55
98
  let cancelled = false;
56
99
  (async () => {
@@ -104,6 +147,26 @@ export function MarketplacePackagePage() {
104
147
  return orgId ? adminOrgIds.has(String(orgId)) : false;
105
148
  });
106
149
  setEnvs(installable);
150
+ // Annotate each installable env with its current install state (best
151
+ // effort, parallel; a failed lookup just omits the annotation).
152
+ setEnvInstallMap({});
153
+ const pkgId = packageId;
154
+ if (pkgId)
155
+ void Promise.all(installable.map(async (env) => {
156
+ try {
157
+ const info = await getCloudInstallationInfo(pkgId, env.id);
158
+ return info ? [env.id, info.version] : null;
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ })).then((pairs) => {
164
+ const map = {};
165
+ for (const pair of pairs)
166
+ if (pair)
167
+ map[pair[0]] = pair[1];
168
+ setEnvInstallMap(map);
169
+ });
107
170
  if (list.length > 0 && installable.length === 0) {
108
171
  setEnvsError(t('marketplace.install.noPermission'));
109
172
  }
@@ -130,7 +193,28 @@ export function MarketplacePackagePage() {
130
193
  setInstalling(true);
131
194
  setInstallResult(null);
132
195
  try {
133
- await installPackage({ packageId, environmentId: selectedEnv, seedSampleData });
196
+ const installResp = await installPackage({ packageId, environmentId: selectedEnv, seedSampleData });
197
+ // Flip the primary CTA to "Installed" so the user sees the state
198
+ // change without a page refresh. Response includes the install
199
+ // row when the cloud handler echoes it; fall back to the package's
200
+ // latest version when it doesn't.
201
+ const installedVersion = installResp?.installation?.version
202
+ ?? data?.package?.latest_version?.version
203
+ ?? data?.versions?.[0]?.version
204
+ ?? '';
205
+ setCloudInstalledVersion(installedVersion || 'installed');
206
+ // Refresh the installation handle so reseed/purge can target it
207
+ // without the user having to reload the page.
208
+ try {
209
+ const currentEnvId = getRuntimeConfig().defaultEnvironmentId;
210
+ const envId = currentEnvId || selectedEnv;
211
+ if (envId) {
212
+ const info = await getCloudInstallationInfo(packageId, envId);
213
+ if (info)
214
+ setCloudInstall(info);
215
+ }
216
+ }
217
+ catch { /* non-fatal */ }
134
218
  // Invalidate the metadata cache so the newly-installed app's
135
219
  // objects/views/menus are fetched fresh on next access. Without
136
220
  // this the user sees the new app in the switcher (the `app` list
@@ -161,6 +245,7 @@ export function MarketplacePackagePage() {
161
245
  }
162
246
  }
163
247
  setInstallResult({ ok: true, message: t('marketplace.install.success') });
248
+ emitMetadataRefresh();
164
249
  }
165
250
  catch (e) {
166
251
  setInstallResult({ ok: false, message: e?.message ?? String(e) });
@@ -195,6 +280,7 @@ export function MarketplacePackagePage() {
195
280
  name: data?.package ? localizePackage(data.package, language).displayName : result.manifestId,
196
281
  }),
197
282
  });
283
+ emitMetadataRefresh();
198
284
  }
199
285
  catch (e) {
200
286
  const code = e?.code;
@@ -248,6 +334,124 @@ export function MarketplacePackagePage() {
248
334
  setInstallingLocal(false);
249
335
  }
250
336
  };
337
+ /**
338
+ * Re-seed sample data into the cloud environment for this install.
339
+ * Used when the user forgot to tick "Include sample data" during the
340
+ * original install. SeedLoaderService upserts by id, so calling this
341
+ * multiple times is safe.
342
+ */
343
+ const doReseedSampleData = async () => {
344
+ if (!cloudInstall)
345
+ return;
346
+ setSampleDataBusy('reseed');
347
+ setSampleDataMsg(null);
348
+ try {
349
+ const r = await reseedSampleData(cloudInstall.installationId);
350
+ if (r.ok) {
351
+ setCloudInstall({ ...cloudInstall, withSampleData: true });
352
+ setSampleDataMsg({
353
+ ok: true,
354
+ text: t('marketplace.detail.reseedQueued') || 'Sample data will be re-seeded on next environment access.',
355
+ });
356
+ }
357
+ else {
358
+ setSampleDataMsg({ ok: false, text: r.error || 'Re-seed failed' });
359
+ }
360
+ }
361
+ finally {
362
+ setSampleDataBusy(null);
363
+ }
364
+ };
365
+ /**
366
+ * Delete the sample data this package seeded. Use before going live
367
+ * with a clean production environment. Only records declared in the
368
+ * package's seed datasets are removed; user-added rows are untouched.
369
+ */
370
+ const doPurgeSampleData = async () => {
371
+ if (!cloudInstall)
372
+ return;
373
+ if (!confirm(t('marketplace.detail.purgeConfirm')
374
+ || 'Delete all sample records seeded by this package? User-added records will NOT be touched.')) {
375
+ return;
376
+ }
377
+ setSampleDataBusy('purge');
378
+ setSampleDataMsg(null);
379
+ try {
380
+ const r = await purgeSampleData(cloudInstall.installationId);
381
+ if (r.ok) {
382
+ setCloudInstall({ ...cloudInstall, withSampleData: false });
383
+ const removed = r.deleted ?? 0;
384
+ setSampleDataMsg({
385
+ ok: true,
386
+ text: removed > 0
387
+ ? (t('marketplace.detail.purgeSuccess', { count: removed })
388
+ || `Removed ${removed} sample record(s).`)
389
+ : (t('marketplace.detail.purgeNoData') || 'No sample records found to purge.'),
390
+ });
391
+ }
392
+ else {
393
+ setSampleDataMsg({ ok: false, text: r.error || 'Purge failed' });
394
+ }
395
+ }
396
+ finally {
397
+ setSampleDataBusy(null);
398
+ }
399
+ };
400
+ const doReseedLocalSampleData = async () => {
401
+ if (!localInstall)
402
+ return;
403
+ setSampleDataBusy('reseed');
404
+ setSampleDataMsg(null);
405
+ try {
406
+ const r = await reseedLocalSampleData(localInstall.manifestId);
407
+ setLocalInstalls((prev) => prev.map((i) => i.manifestId === localInstall.manifestId ? { ...i, withSampleData: true } : i));
408
+ const inserted = r.inserted ?? 0;
409
+ const updated = r.updated ?? 0;
410
+ const errored = r.errors ?? 0;
411
+ const base = t('marketplace.detail.reseedLocalSuccess', { inserted, updated })
412
+ || `Sample data re-seeded (inserted=${inserted}, updated=${updated}).`;
413
+ // A reseed can land some rows and fail others (the server only hard-fails
414
+ // when ZERO rows write). Don't hide the partial failures behind a green
415
+ // success toast — flag them so the user knows the data is incomplete.
416
+ setSampleDataMsg(errored > 0
417
+ ? { ok: false, text: `${base} ${t('marketplace.detail.reseedPartialErrors', { count: errored }) || `(${errored} record(s) failed to write)`}` }
418
+ : { ok: true, text: base });
419
+ }
420
+ catch (err) {
421
+ setSampleDataMsg({ ok: false, text: err?.message || 'Re-seed failed' });
422
+ }
423
+ finally {
424
+ setSampleDataBusy(null);
425
+ }
426
+ };
427
+ const doPurgeLocalSampleData = async () => {
428
+ if (!localInstall)
429
+ return;
430
+ if (!confirm(t('marketplace.detail.purgeConfirm')
431
+ || 'Delete all sample records seeded by this package? User-added records will NOT be touched.')) {
432
+ return;
433
+ }
434
+ setSampleDataBusy('purge');
435
+ setSampleDataMsg(null);
436
+ try {
437
+ const r = await purgeLocalSampleData(localInstall.manifestId);
438
+ setLocalInstalls((prev) => prev.map((i) => i.manifestId === localInstall.manifestId ? { ...i, withSampleData: false } : i));
439
+ const removed = r.deleted ?? 0;
440
+ setSampleDataMsg({
441
+ ok: true,
442
+ text: removed > 0
443
+ ? (t('marketplace.detail.purgeSuccess', { count: removed })
444
+ || `Removed ${removed} sample record(s).`)
445
+ : (t('marketplace.detail.purgeNoData') || 'No sample records found to purge.'),
446
+ });
447
+ }
448
+ catch (err) {
449
+ setSampleDataMsg({ ok: false, text: err?.message || 'Purge failed' });
450
+ }
451
+ finally {
452
+ setSampleDataBusy(null);
453
+ }
454
+ };
251
455
  if (loading) {
252
456
  return (_jsxs("div", { className: "mx-auto w-full max-w-6xl flex flex-col gap-6 p-4 sm:p-6", children: [_jsx(Skeleton, { className: "h-8 w-32" }), _jsx(Skeleton, { className: "h-16 w-full" }), _jsx(Skeleton, { className: "h-64 w-full" })] }));
253
457
  }
@@ -258,8 +462,16 @@ export function MarketplacePackagePage() {
258
462
  const loc = localizePackage(pkg, language);
259
463
  const latestVersion = pkg.latest_version?.version ?? data.versions[0]?.version ?? null;
260
464
  const localInstall = localInstalls.find((i) => i.manifestId === pkg.manifest_id) ?? null;
465
+ // PD4 (ADR-0025 §3.11): code-bearing packages must disclose + be acknowledged.
466
+ const containsCode = !!pkg.latest_version?.contains_code;
467
+ // ADR-0010 version lifecycle: installed cloud env is on an OLDER version than
468
+ // the package's latest published → surface an update affordance.
469
+ const cloudUpdateAvailable = !!cloudInstalledVersion
470
+ && cloudInstalledVersion !== 'installed'
471
+ && !!latestVersion
472
+ && cloudInstalledVersion !== latestVersion;
261
473
  const supportsLocal = getRuntimeConfig().features.installLocal;
262
- const primaryDisabled = !latestVersion || installingLocal || installing;
474
+ const primaryDisabled = !latestVersion || installingLocal || installing || (!supportsLocal && !!cloudInstalledVersion && !cloudUpdateAvailable);
263
475
  const primaryAction = supportsLocal
264
476
  ? {
265
477
  label: installingLocal
@@ -270,7 +482,13 @@ export function MarketplacePackagePage() {
270
482
  onClick: doInstallLocal,
271
483
  }
272
484
  : {
273
- label: installing ? t('marketplace.action.installing') : t('marketplace.action.installToCloud'),
485
+ label: installing
486
+ ? t('marketplace.action.installing')
487
+ : cloudInstalledVersion
488
+ ? (cloudUpdateAvailable
489
+ ? t('marketplace.action.updateTo', { defaultValue: 'Update', version: latestVersion })
490
+ : t('marketplace.action.installed', { defaultValue: 'Installed' }))
491
+ : t('marketplace.action.installToCloud'),
274
492
  onClick: openInstall,
275
493
  };
276
494
  const categoryLabel = pkg.category
@@ -278,8 +496,31 @@ export function MarketplacePackagePage() {
278
496
  : null;
279
497
  if (!isAdmin)
280
498
  return _jsx(MarketplaceAccessDenied, {});
281
- return (_jsxs("div", { className: "mx-auto w-full max-w-6xl flex flex-col gap-6 p-4 sm:p-6", children: [_jsxs(Button, { variant: "ghost", size: "sm", className: "self-start -ml-2 text-muted-foreground hover:text-foreground", onClick: () => navigate(`${basePath}/system/marketplace`), children: [_jsx(ArrowLeft, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.back')] }), _jsxs("div", { className: "flex items-start gap-5 flex-wrap sm:flex-nowrap rounded-2xl border bg-gradient-to-br from-primary/5 via-background to-background p-6 sm:p-8", children: [_jsx(PackageIcon, { iconUrl: pkg.icon_url, displayName: loc.displayName, manifestId: pkg.manifest_id, className: "h-20 w-20 rounded-2xl shadow-sm ring-1 ring-border shrink-0", initialClassName: "text-3xl font-bold" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("h1", { className: "text-2xl sm:text-3xl font-bold tracking-tight truncate", children: loc.displayName || pkg.manifest_id }), pkg.homepage_url && (_jsxs("a", { href: pkg.homepage_url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors", title: t('marketplace.detail.homepage'), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), _jsx("span", { className: "hidden sm:inline", children: t('marketplace.detail.homepage') })] }))] }), _jsxs("div", { className: "text-sm text-muted-foreground mt-2 flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "font-mono text-xs px-1.5 py-0.5 rounded bg-muted", children: pkg.manifest_id }), latestVersion && _jsx(Badge, { variant: "outline", children: t('marketplace.versionBadge', { version: latestVersion }) }), pkg.publisher && pkg.publisher !== 'private' && (_jsx(Badge, { variant: pkg.publisher === 'objectstack' ? 'default' : 'secondary', children: pkg.publisher })), categoryLabel && _jsx(Badge, { variant: "outline", children: categoryLabel }), pkg.license && _jsx(Badge, { variant: "outline", className: "font-normal", children: pkg.license }), localInstall && (_jsxs(Badge, { variant: "default", className: "bg-green-600 hover:bg-green-600 gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.installedV', { version: localInstall.version })] }))] }), loc.description && (_jsx("p", { className: "text-sm sm:text-base text-foreground/80 mt-3 max-w-2xl leading-relaxed", children: loc.description }))] }), _jsxs("div", { className: "flex items-center gap-2 shrink-0 self-start", children: [_jsxs(Button, { onClick: primaryAction.onClick, disabled: primaryDisabled, size: "lg", className: "min-w-[8rem]", children: [_jsx(Download, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), primaryAction.label] }), localInstall && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "lg", className: "px-2.5", "aria-label": t('marketplace.detail.moreOptions'), children: _jsx(MoreHorizontal, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), _jsx(DropdownMenuContent, { align: "end", className: "w-56", children: _jsxs(DropdownMenuItem, { onSelect: doUninstallLocal, disabled: installingLocal, className: "text-destructive focus:text-destructive", children: [_jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.uninstallFromRuntime')] }) })] }))] })] }), localResult && (_jsxs("div", { role: "status", className: `flex items-start gap-2 rounded-md border p-3 text-sm whitespace-pre-wrap ${localResult.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: [localResult.ok ? _jsx(CheckCircle2, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }) : _jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: localResult.message }), _jsx("button", { type: "button", className: "text-xs underline opacity-60 hover:opacity-100", onClick: () => setLocalResult(null), children: t('marketplace.action.dismiss') })] })), _jsxs("div", { className: "grid gap-4 lg:grid-cols-3", children: [_jsx("div", { className: "lg:col-span-2 space-y-4", children: _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('marketplace.detail.about') }) }), _jsx(CardContent, { children: loc.readme ? (_jsx(MarkdownText, { source: loc.readme })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.detail.noReadme') })) })] }) }), _jsx("div", { className: "space-y-4", children: _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('marketplace.detail.versions') }) }), _jsx(CardContent, { children: data.versions.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.detail.noApprovedVersions') })) : (_jsx("ul", { className: "space-y-2", children: data.versions.map((v) => (_jsxs("li", { className: "flex items-center justify-between gap-2 text-sm", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Package, { className: "h-3.5 w-3.5 text-muted-foreground", "aria-hidden": "true" }), _jsxs("code", { className: "font-mono", children: ["v", v.version] }), v.is_prerelease && _jsx(Badge, { variant: "outline", className: "text-xs", children: t('marketplace.detail.prerelease') })] }), _jsx("span", { className: "text-xs text-muted-foreground", children: v.published_at ? new Date(v.published_at).toLocaleDateString() : '—' })] }, v.id))) })) })] }) })] }), _jsx(Dialog, { open: installOpen, onOpenChange: (o) => { setInstallOpen(o); if (!o)
282
- setInstallResult(null); }, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('marketplace.install.dialogTitle', { name: loc.displayName || pkg.manifest_id }) }), _jsx(DialogDescription, { children: getRuntimeConfig().defaultEnvironmentId
499
+ return (_jsxs("div", { className: "mx-auto w-full max-w-6xl flex flex-col gap-6 p-4 sm:p-6", children: [_jsxs(Button, { variant: "ghost", size: "sm", className: "self-start -ml-2 text-muted-foreground hover:text-foreground", onClick: () => navigate(`${basePath}/system/marketplace`), children: [_jsx(ArrowLeft, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.back')] }), _jsxs("div", { className: "flex items-start gap-5 flex-wrap sm:flex-nowrap rounded-2xl border bg-gradient-to-br from-primary/5 via-background to-background p-6 sm:p-8", children: [_jsx(PackageIcon, { iconUrl: pkg.icon_url, displayName: loc.displayName, manifestId: pkg.manifest_id, className: "h-20 w-20 rounded-2xl shadow-sm ring-1 ring-border shrink-0", initialClassName: "text-3xl font-bold" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("h1", { className: "text-2xl sm:text-3xl font-bold tracking-tight truncate", children: loc.displayName || pkg.manifest_id }), pkg.homepage_url && (_jsxs("a", { href: pkg.homepage_url, target: "_blank", rel: "noopener noreferrer", className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors", title: t('marketplace.detail.homepage'), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), _jsx("span", { className: "hidden sm:inline", children: t('marketplace.detail.homepage') })] }))] }), _jsxs("div", { className: "text-sm text-muted-foreground mt-2 flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "font-mono text-xs px-1.5 py-0.5 rounded bg-muted", children: pkg.manifest_id }), latestVersion && _jsx(Badge, { variant: "outline", children: t('marketplace.versionBadge', { version: latestVersion }) }), pkg.publisher && pkg.publisher !== 'private' && (_jsx(Badge, { variant: pkg.publisher === 'objectstack' ? 'default' : 'secondary', children: pkg.publisher })), categoryLabel && _jsx(Badge, { variant: "outline", children: categoryLabel }), pkg.license && _jsx(Badge, { variant: "outline", className: "font-normal", children: pkg.license }), localInstall && (_jsxs(Badge, { variant: "default", className: "bg-green-600 hover:bg-green-600 gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.installedV', { version: localInstall.version })] })), !localInstall && cloudInstalledVersion && (_jsxs(Badge, { variant: "default", className: "bg-green-600 hover:bg-green-600 gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.installedV', { version: cloudInstalledVersion })] })), cloudUpdateAvailable && (_jsxs(Badge, { variant: "default", className: "bg-amber-500 hover:bg-amber-500 gap-1", children: [_jsx(ArrowUpCircle, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.detail.updateAvailable', { defaultValue: 'Update available' }), " \u2192 v", latestVersion] }))] }), loc.description && (_jsx("p", { className: "text-sm sm:text-base text-foreground/80 mt-3 max-w-2xl leading-relaxed", children: loc.description }))] }), _jsxs("div", { className: "flex items-center gap-2 shrink-0 self-start", children: [_jsxs(Button, { onClick: primaryAction.onClick, disabled: primaryDisabled, size: "lg", className: "min-w-[8rem]", children: [_jsx(Download, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), primaryAction.label] }), localInstall && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "lg", className: "px-2.5", "aria-label": t('marketplace.detail.moreOptions'), children: _jsx(MoreHorizontal, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [_jsxs(DropdownMenuItem, { onSelect: doReseedLocalSampleData, disabled: sampleDataBusy !== null, children: [sampleDataBusy === 'reseed'
500
+ ? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
501
+ : _jsx(Database, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), localInstall.withSampleData
502
+ ? (t('marketplace.detail.reseedAgain') || 'Re-seed sample data')
503
+ : (t('marketplace.detail.addSampleData') || 'Add sample data')] }), _jsxs(DropdownMenuItem, { onSelect: doPurgeLocalSampleData, disabled: sampleDataBusy !== null || !localInstall.withSampleData, className: "text-destructive focus:text-destructive", children: [sampleDataBusy === 'purge'
504
+ ? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
505
+ : _jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.purgeSampleData') || 'Purge sample data'] }), _jsxs(DropdownMenuItem, { onSelect: doUninstallLocal, disabled: installingLocal, className: "text-destructive focus:text-destructive", children: [_jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.uninstallFromRuntime')] })] })] })), !localInstall && cloudInstall && !getRuntimeConfig().cloudUrl && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "lg", className: "px-2.5", "aria-label": t('marketplace.detail.moreOptions') || 'More options', children: _jsx(MoreHorizontal, { className: "h-4 w-4", "aria-hidden": "true" }) }) }), _jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [_jsxs(DropdownMenuItem, { onSelect: doReseedSampleData, disabled: sampleDataBusy !== null, children: [sampleDataBusy === 'reseed'
506
+ ? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
507
+ : _jsx(Database, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), cloudInstall.withSampleData
508
+ ? (t('marketplace.detail.reseedAgain') || 'Re-seed sample data')
509
+ : (t('marketplace.detail.addSampleData') || 'Add sample data')] }), _jsxs(DropdownMenuItem, { onSelect: doPurgeSampleData, disabled: sampleDataBusy !== null || !cloudInstall.withSampleData, className: "text-destructive focus:text-destructive", children: [sampleDataBusy === 'purge'
510
+ ? _jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin", "aria-hidden": "true" })
511
+ : _jsx(Trash2, { className: "h-4 w-4 mr-2", "aria-hidden": "true" }), t('marketplace.detail.purgeSampleData') || 'Purge sample data'] })] })] }))] })] }), sampleDataMsg && (_jsxs("div", { role: "status", className: `flex items-start gap-2 rounded-md border p-3 text-sm ${sampleDataMsg.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: [sampleDataMsg.ok ? _jsx(CheckCircle2, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }) : _jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: sampleDataMsg.text }), _jsx("button", { type: "button", className: "text-xs underline opacity-60 hover:opacity-100", onClick: () => setSampleDataMsg(null), children: t('marketplace.action.dismiss') })] })), localResult && (_jsxs("div", { role: "status", className: `flex items-start gap-2 rounded-md border p-3 text-sm whitespace-pre-wrap ${localResult.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: [localResult.ok ? _jsx(CheckCircle2, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }) : _jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 shrink-0", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: localResult.message }), _jsx("button", { type: "button", className: "text-xs underline opacity-60 hover:opacity-100", onClick: () => setLocalResult(null), children: t('marketplace.action.dismiss') })] })), _jsxs("div", { className: "grid gap-4 lg:grid-cols-3", children: [_jsx("div", { className: "lg:col-span-2 space-y-4", children: _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('marketplace.detail.about') }) }), _jsx(CardContent, { children: loc.readme ? (_jsx(MarkdownText, { source: loc.readme })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.detail.noReadme') })) })] }) }), _jsx("div", { className: "space-y-4", children: _jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { className: "text-base", children: t('marketplace.detail.versions') }) }), _jsx(CardContent, { children: data.versions.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.detail.noApprovedVersions') })) : (_jsx("ul", { className: "space-y-3", children: data.versions.map((v) => (_jsxs("li", { className: "space-y-1 text-sm", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Package, { className: "h-3.5 w-3.5 text-muted-foreground", "aria-hidden": "true" }), _jsxs("code", { className: "font-mono", children: ["v", v.version] }), v.is_prerelease && _jsx(Badge, { variant: "outline", className: "text-xs", children: t('marketplace.detail.prerelease') })] }), _jsx("span", { className: "text-xs text-muted-foreground", children: v.published_at ? new Date(v.published_at).toLocaleDateString() : '\u2014' })] }), v.release_notes && v.release_notes.trim() && (_jsx("p", { className: "whitespace-pre-line pl-5 text-xs text-muted-foreground", children: v.release_notes.trim() }))] }, v.id))) })) })] }) })] }), _jsx(Dialog, { open: installOpen, onOpenChange: (o) => { setInstallOpen(o); if (!o) {
512
+ setInstallResult(null);
513
+ setAcknowledged(false);
514
+ } }, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('marketplace.install.dialogTitle', { name: loc.displayName || pkg.manifest_id }) }), _jsx(DialogDescription, { children: getRuntimeConfig().defaultEnvironmentId
283
515
  ? t('marketplace.install.dialogDescCurrent', { host: typeof window !== 'undefined' ? window.location.host : '' })
284
- : t('marketplace.install.dialogDescPicker') })] }), envsLoading ? (_jsx(Skeleton, { className: "h-10 w-full" })) : envsError ? (_jsxs("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 p-3 text-sm space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 text-amber-600", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: envsError })] }), _jsx("a", { href: cloudInstallDeepLink(pkg.id), target: "_blank", rel: "noopener noreferrer", children: _jsxs(Button, { variant: "outline", size: "sm", className: "w-full", children: [_jsx(ExternalLink, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.action.openOnCloud')] }) })] })) : getRuntimeConfig().defaultEnvironmentId ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })) : envs.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.install.noEnvs') })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "env-select", children: t('marketplace.install.environment') }), _jsxs(Select, { value: selectedEnv, onValueChange: setSelectedEnv, children: [_jsx(SelectTrigger, { id: "env-select", children: _jsx(SelectValue, { placeholder: t('marketplace.install.environmentPlaceholder') }) }), _jsx(SelectContent, { children: envs.map((e) => (_jsxs(SelectItem, { value: e.id, children: [e.display_name || e.hostname || e.id, e.plan && _jsxs("span", { className: "text-muted-foreground", children: [" \u00B7 ", e.plan] })] }, e.id))) })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })] })), installResult && (_jsx("div", { className: `rounded-md border p-3 text-sm ${installResult.ok ? 'border-green-500/30 bg-green-500/5 text-green-700' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: installResult.message })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setInstallOpen(false), children: t('marketplace.action.close') }), !envsError && (_jsx(Button, { onClick: doInstall, disabled: !selectedEnv || installing || installResult?.ok === true, children: installing ? t('marketplace.action.installing') : t('marketplace.action.install') }))] })] }) })] }));
516
+ : t('marketplace.install.dialogDescPicker') })] }), envsLoading ? (_jsx(Skeleton, { className: "h-10 w-full" })) : envsError ? (_jsxs("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 p-3 text-sm space-y-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 text-amber-600", "aria-hidden": "true" }), _jsx("div", { className: "flex-1", children: envsError })] }), _jsx("a", { href: cloudInstallDeepLink(pkg.id), target: "_blank", rel: "noopener noreferrer", children: _jsxs(Button, { variant: "outline", size: "sm", className: "w-full", children: [_jsx(ExternalLink, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.action.openOnCloud')] }) })] })) : getRuntimeConfig().defaultEnvironmentId ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })) : envs.length === 0 ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('marketplace.install.noEnvs') })) : (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "env-select", children: t('marketplace.install.environment') }), _jsxs(Select, { value: selectedEnv, onValueChange: setSelectedEnv, children: [_jsx(SelectTrigger, { id: "env-select", children: _jsx(SelectValue, { placeholder: t('marketplace.install.environmentPlaceholder') }) }), _jsx(SelectContent, { children: envs.map((e) => {
517
+ const installedHere = envInstallMap[e.id];
518
+ const hasUpdate = !!installedHere && !!latestVersion
519
+ && installedHere !== 'installed' && installedHere !== latestVersion;
520
+ return (_jsxs(SelectItem, { value: e.id, children: [e.display_name || e.hostname || e.id, e.plan && _jsxs("span", { className: "text-muted-foreground", children: [" \u00B7 ", e.plan] }), installedHere && (hasUpdate
521
+ ? _jsxs("span", { className: "text-amber-600", children: [" \u00B7 ", t('marketplace.install.updateTo', { defaultValue: 'Update \u2192 v{{version}}', version: latestVersion })] })
522
+ : _jsxs("span", { className: "text-muted-foreground", children: [" \u00B7 ", t('marketplace.install.installedVersion', { defaultValue: 'Installed v{{version}}', version: installedHere })] }))] }, e.id));
523
+ }) })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: "seed", checked: seedSampleData, onCheckedChange: (c) => setSeedSampleData(c === true) }), _jsx(Label, { htmlFor: "seed", className: "text-sm font-normal cursor-pointer", children: t('marketplace.install.includeSampleData') })] })] })), containsCode && !envsError && (_jsxs("div", { className: "space-y-3", children: [_jsx(PluginDisclosure, { version: pkg.latest_version }), _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Checkbox, { id: "ack-perms", checked: acknowledged, onCheckedChange: (c) => setAcknowledged(c === true) }), _jsx(Label, { htmlFor: "ack-perms", className: "text-sm font-normal cursor-pointer leading-snug", children: t('marketplace.disclosure.acknowledge', {
524
+ defaultValue: 'I understand this package runs code and grants the permissions above.',
525
+ }) })] })] })), installResult && (_jsx("div", { className: `rounded-md border p-3 text-sm ${installResult.ok ? 'border-green-500/30 bg-green-500/5 text-green-700' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: installResult.message })), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setInstallOpen(false), children: t('marketplace.action.close') }), !envsError && (_jsx(Button, { onClick: doInstall, disabled: !selectedEnv || installing || installResult?.ok === true || (containsCode && !acknowledged), children: installing ? t('marketplace.action.installing') : t('marketplace.action.install') }))] })] }) })] }));
285
526
  }
@@ -5,4 +5,4 @@
5
5
  * `/api/v1/marketplace/packages` proxy (which forwards to the configured
6
6
  * cloud control plane). Click-through opens the package detail page.
7
7
  */
8
- export declare function MarketplacePage(): import("react/jsx-runtime").JSX.Element;
8
+ export declare function MarketplacePage(): import("react").JSX.Element;
@@ -15,7 +15,9 @@ import { useObjectTranslation } from '@object-ui/i18n';
15
15
  import { PackageIcon } from './PackageIcon';
16
16
  import { MarketplaceAccessDenied } from './MarketplaceAccessDenied';
17
17
  import { localizePackage } from './usePackageL10n';
18
- import { listMarketplacePackages, listLocalInstalls, } from './marketplaceApi';
18
+ import { listMarketplacePackages, listLocalInstalls, listOrgPackages, listInstalledPackages, installPackage, installLocal, } from './marketplaceApi';
19
+ import { getRuntimeConfig } from '../../runtime-config';
20
+ import { emitMetadataRefresh } from '../../assistant/assistantBus';
19
21
  /**
20
22
  * Format a published-at timestamp as a localized relative string.
21
23
  *
@@ -64,6 +66,12 @@ export function MarketplacePage() {
64
66
  const [query, setQuery] = useState('');
65
67
  const [category, setCategory] = useState('');
66
68
  const [installed, setInstalled] = useState([]);
69
+ // ADR-0007 step ②: the org's own packages (visibility org/private), shown in
70
+ // a "Your organization" section and installable inline (no public listing).
71
+ const [orgItems, setOrgItems] = useState([]);
72
+ const [orgInstalling, setOrgInstalling] = useState(null);
73
+ const [orgMsg, setOrgMsg] = useState(null);
74
+ const [installedIds, setInstalledIds] = useState(new Set());
67
75
  const installedByManifestId = useMemo(() => {
68
76
  const m = new Map();
69
77
  for (const e of installed)
@@ -74,12 +82,21 @@ export function MarketplacePage() {
74
82
  setLoading(true);
75
83
  setError(null);
76
84
  try {
77
- const [resp, installs] = await Promise.all([
85
+ const [resp, installs, org, cloudInstalled] = await Promise.all([
78
86
  listMarketplacePackages({ limit: 100 }),
79
87
  listLocalInstalls(),
88
+ listOrgPackages(),
89
+ listInstalledPackages(),
80
90
  ]);
81
91
  setItems(resp.items ?? []);
82
92
  setInstalled(installs);
93
+ setOrgItems(org.items ?? []);
94
+ const ids = new Set();
95
+ for (const e of installs)
96
+ ids.add(e.manifestId);
97
+ for (const e of cloudInstalled.items)
98
+ ids.add(e.manifestId);
99
+ setInstalledIds(ids);
83
100
  }
84
101
  catch (e) {
85
102
  setError(e?.message ?? String(e));
@@ -90,6 +107,41 @@ export function MarketplacePage() {
90
107
  }
91
108
  };
92
109
  useEffect(() => { void load(); }, []);
110
+ // Install an org package into the current environment (ADR-0007 step ②).
111
+ //
112
+ // Two deployment shapes, two semantically-correct routes:
113
+ // - install-local runtimes (single-env / self-hosted, runtime-config
114
+ // features.installLocal=true): the runtime OWNS its desired state —
115
+ // install merges into ITS kernel via /marketplace/install-local; the
116
+ // bound oscc_ credential lets it fetch the org manifest (ADR-0008).
117
+ // The control-plane /cloud-connection/install path would 401 here
118
+ // (no env→cloud service key) and is the wrong semantics anyway.
119
+ // - cloud-managed environments: desired state lives in the control
120
+ // plane — /cloud-connection/install resolves the env by hostname.
121
+ const doOrgInstall = async (pkg) => {
122
+ setOrgInstalling(pkg.id);
123
+ setOrgMsg(null);
124
+ try {
125
+ if (getRuntimeConfig().features.installLocal) {
126
+ await installLocal({ packageId: pkg.manifest_id || pkg.id, versionId: 'latest' });
127
+ }
128
+ else {
129
+ await installPackage({ packageId: pkg.id, environmentId: '', seedSampleData: true });
130
+ }
131
+ setOrgMsg({ ok: true, text: t('marketplace.org.installed', { defaultValue: `Installed ${pkg.display_name}`, name: pkg.display_name }) });
132
+ await load();
133
+ // The install merged a package into the live registry. Pulse every
134
+ // mounted MetadataProvider so the new app appears in the nav (and its
135
+ // objects/views resolve) without a manual browser refresh.
136
+ emitMetadataRefresh();
137
+ }
138
+ catch (e) {
139
+ setOrgMsg({ ok: false, text: e?.message ?? String(e) });
140
+ }
141
+ finally {
142
+ setOrgInstalling(null);
143
+ }
144
+ };
93
145
  const categories = useMemo(() => {
94
146
  const s = new Set();
95
147
  for (const it of items) {
@@ -123,7 +175,12 @@ export function MarketplacePage() {
123
175
  ? t('marketplace.installedCount', { count: installed.length })
124
176
  : t('marketplace.installed')] }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void load(), disabled: loading, children: [_jsx(RefreshCcw, { className: "h-4 w-4 mr-1.5", "aria-hidden": "true" }), t('marketplace.refresh')] })] })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground", "aria-hidden": "true" }), _jsx(Input, { value: query, onChange: (e) => setQuery(e.target.value), placeholder: t('marketplace.searchPlaceholder'), className: "pl-9", "aria-label": t('marketplace.searchAria') })] }), categories.length > 0 && (_jsxs("div", { className: "flex flex-wrap gap-1.5", children: [_jsx(Button, { size: "sm", variant: category === '' ? 'default' : 'outline', onClick: () => setCategory(''), children: t('marketplace.all') }), categories.map((cat) => (_jsx(Button, { size: "sm", variant: category === cat ? 'default' : 'outline', onClick: () => setCategory(cat), children: categoryLabel(cat) }, cat)))] }))] }), error && (_jsxs("div", { className: "flex items-start gap-3 rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm", children: [_jsx(AlertCircle, { className: "h-4 w-4 mt-0.5 text-destructive", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("div", { className: "font-medium text-destructive", children: t('marketplace.load.failed') }), _jsx("div", { className: "text-muted-foreground mt-1", children: error }), _jsx("div", { className: "text-xs text-muted-foreground mt-2",
125
177
  // Hint message contains an inline <code> tag — render translated HTML safely from our own bundle.
126
- dangerouslySetInnerHTML: { __html: t('marketplace.load.failedHint') } })] })] })), loading && items.length === 0 ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsx(Skeleton, { className: "h-10 w-10 rounded-lg mb-2" }), _jsx(Skeleton, { className: "h-5 w-3/4" }), _jsx(Skeleton, { className: "h-4 w-1/2 mt-1" })] }), _jsx(CardContent, { children: _jsx(Skeleton, { className: "h-12 w-full" }) })] }, i))) })) : filtered.length === 0 ? (_jsx("div", { className: "text-center py-12 text-sm text-muted-foreground", children: items.length === 0 ? t('marketplace.noApprovedYet') : t('marketplace.noMatchFilters') })) : (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filtered.map((pkg) => {
178
+ dangerouslySetInnerHTML: { __html: t('marketplace.load.failedHint') } })] })] })), orgItems.length > 0 && (_jsxs("section", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Store, { className: "h-5 w-5 text-primary", "aria-hidden": "true" }), _jsx("h2", { className: "text-sm font-semibold", children: t('marketplace.org.heading', { defaultValue: 'Your organization' }) }), _jsx(Badge, { variant: "secondary", className: "text-xs", children: orgItems.length })] }), orgMsg && (_jsx("div", { className: `rounded-md border p-3 text-sm ${orgMsg.ok ? 'border-green-500/30 bg-green-500/5 text-green-700 dark:text-green-400' : 'border-destructive/30 bg-destructive/5 text-destructive'}`, children: orgMsg.text })), _jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: orgItems.map((pkg) => {
179
+ const isInstalled = installedIds.has(pkg.manifest_id);
180
+ return (_jsxs(Card, { className: "flex flex-col", "data-testid": `org-card-${pkg.manifest_id}`, children: [_jsxs(CardHeader, { className: "flex flex-row items-start gap-3 pb-2", children: [_jsx(PackageIcon, { iconUrl: pkg.icon_url, displayName: pkg.display_name, manifestId: pkg.manifest_id }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(CardTitle, { className: "text-base truncate", children: pkg.display_name }), _jsx(CardDescription, { className: "text-xs truncate", children: _jsx("code", { className: "font-mono", children: pkg.manifest_id }) })] }), pkg.visibility && (_jsx(Badge, { variant: "outline", className: "shrink-0 text-xs", children: pkg.visibility }))] }), _jsxs(CardContent, { className: "flex-1 flex flex-col gap-2", children: [_jsx("p", { className: "text-sm text-muted-foreground line-clamp-2", children: pkg.description || t('marketplace.noDescription') }), _jsxs("div", { className: "flex items-center gap-2 mt-auto pt-2 flex-wrap", children: [pkg.latest_version && (_jsxs(Badge, { variant: "outline", className: "text-xs", children: [_jsx(Package, { className: "h-3 w-3 mr-1", "aria-hidden": "true" }), t('marketplace.versionBadge', { version: pkg.latest_version })] })), _jsx("div", { className: "ml-auto", children: isInstalled ? (_jsxs(Badge, { variant: "default", className: "text-xs bg-green-600 hover:bg-green-600", children: [_jsx(CheckCircle2, { className: "h-3 w-3 mr-1", "aria-hidden": "true" }), t('marketplace.org.installedBadge', { defaultValue: 'Installed' })] })) : (_jsx(Button, { size: "sm", onClick: () => void doOrgInstall(pkg), disabled: orgInstalling === pkg.id, children: orgInstalling === pkg.id
181
+ ? t('marketplace.org.installing', { defaultValue: 'Installing…' })
182
+ : t('marketplace.org.install', { defaultValue: 'Install' }) })) })] })] })] }, pkg.id));
183
+ }) }), _jsx("div", { className: "border-b pt-2" })] })), loading && items.length === 0 ? (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-2", children: [_jsx(Skeleton, { className: "h-10 w-10 rounded-lg mb-2" }), _jsx(Skeleton, { className: "h-5 w-3/4" }), _jsx(Skeleton, { className: "h-4 w-1/2 mt-1" })] }), _jsx(CardContent, { children: _jsx(Skeleton, { className: "h-12 w-full" }) })] }, i))) })) : filtered.length === 0 ? (_jsx("div", { className: "text-center py-12 text-sm text-muted-foreground", children: items.length === 0 ? t('marketplace.noApprovedYet') : t('marketplace.noMatchFilters') })) : (_jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: filtered.map((pkg) => {
127
184
  const localEntry = installedByManifestId.get(pkg.manifest_id);
128
185
  const loc = localizePackage(pkg, language);
129
186
  return (_jsxs(Card, { className: "cursor-pointer transition-colors hover:bg-accent/50 flex flex-col", onClick: () => navigate(`${basePath}/system/marketplace/${pkg.id}`), role: "link", tabIndex: 0, onKeyDown: (e) => {
@@ -16,4 +16,4 @@ export interface PackageIconProps {
16
16
  /** Text size for the initial-letter fallback. */
17
17
  initialClassName?: string;
18
18
  }
19
- export declare function PackageIcon({ iconUrl, displayName, manifestId, className, initialClassName, }: PackageIconProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function PackageIcon({ iconUrl, displayName, manifestId, className, initialClassName, }: PackageIconProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Plugin permission disclosure (ADR-0025 PD4 §3.5 / §3.11).
3
+ *
4
+ * Rendered in the install dialog for a code-bearing package. Shows what the
5
+ * user is consenting to BEFORE install: that the package contains code, the
6
+ * trust tier it runs under, whether it is signed / marketplace-reviewed, and
7
+ * the exact structured permission set it requests. The control plane exposes
8
+ * verification STATUS only (never raw signatures); see cloud
9
+ * marketplace.projectVersion.
10
+ */
11
+ import type { MarketplacePackageVersion } from './marketplaceApi';
12
+ export declare function PluginDisclosure({ version }: {
13
+ version?: MarketplacePackageVersion | null;
14
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Plugin permission disclosure (ADR-0025 PD4 §3.5 / §3.11).
4
+ *
5
+ * Rendered in the install dialog for a code-bearing package. Shows what the
6
+ * user is consenting to BEFORE install: that the package contains code, the
7
+ * trust tier it runs under, whether it is signed / marketplace-reviewed, and
8
+ * the exact structured permission set it requests. The control plane exposes
9
+ * verification STATUS only (never raw signatures); see cloud
10
+ * marketplace.projectVersion.
11
+ */
12
+ import { Badge } from '@object-ui/components';
13
+ import { Boxes, CheckCircle2, Code2, FolderTree, Network, ShieldAlert, ShieldCheck, Webhook } from 'lucide-react';
14
+ import { useObjectTranslation } from '@object-ui/i18n';
15
+ const RUNTIME_FALLBACK = {
16
+ node: 'In-process · full trust',
17
+ sandbox: 'Sandboxed',
18
+ worker: 'Out-of-process',
19
+ };
20
+ function PermissionGroup({ icon: Icon, label, items, }) {
21
+ if (!items || items.length === 0)
22
+ return null;
23
+ return (_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Icon, { className: "h-3.5 w-3.5 mt-0.5 text-muted-foreground shrink-0", "aria-hidden": "true" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "text-xs font-medium", children: label }), _jsx("div", { className: "flex flex-wrap gap-1 mt-0.5", children: items.map((it) => (_jsx("code", { className: "font-mono text-[11px] px-1 py-0.5 rounded bg-muted break-all", children: it }, it))) })] })] }));
24
+ }
25
+ export function PluginDisclosure({ version }) {
26
+ const { t } = useObjectTranslation();
27
+ if (!version?.contains_code)
28
+ return null;
29
+ const perms = version.permissions ?? {};
30
+ const hasAny = (perms.services?.length ?? 0) +
31
+ (perms.hooks?.length ?? 0) +
32
+ (perms.network?.length ?? 0) +
33
+ (perms.fs?.length ?? 0) >
34
+ 0;
35
+ return (_jsxs("div", { className: "rounded-md border border-amber-500/30 bg-amber-500/5 p-3 space-y-3 text-sm", children: [_jsxs("div", { className: "flex items-center gap-2 font-medium", children: [_jsx(Code2, { className: "h-4 w-4 text-amber-600 shrink-0", "aria-hidden": "true" }), t('marketplace.disclosure.containsCode', { defaultValue: 'This package contains code' })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [version.runtime && (_jsx(Badge, { variant: "outline", children: t(`marketplace.disclosure.runtime.${version.runtime}`, {
36
+ defaultValue: RUNTIME_FALLBACK[version.runtime] ?? version.runtime,
37
+ }) })), version.platform_verified ? (_jsxs(Badge, { variant: "outline", className: "gap-1 border-green-500/40 text-green-700 dark:text-green-400", children: [_jsx(ShieldCheck, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.disclosure.reviewed', { defaultValue: 'Reviewed & approved' })] })) : (_jsxs(Badge, { variant: "outline", className: "gap-1 border-amber-500/40 text-amber-700 dark:text-amber-400", children: [_jsx(ShieldAlert, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.disclosure.unreviewed', { defaultValue: 'Not yet reviewed' })] })), version.signed && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3", "aria-hidden": "true" }), t('marketplace.disclosure.signed', { defaultValue: 'Signed' })] }))] }), hasAny ? (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-xs text-muted-foreground", children: t('marketplace.disclosure.grantsIntro', { defaultValue: 'On install, this package will be granted:' }) }), _jsx(PermissionGroup, { icon: Boxes, label: t('marketplace.disclosure.services', { defaultValue: 'Platform services' }), items: perms.services ?? undefined }), _jsx(PermissionGroup, { icon: Webhook, label: t('marketplace.disclosure.hooks', { defaultValue: 'Lifecycle hooks' }), items: perms.hooks ?? undefined }), _jsx(PermissionGroup, { icon: Network, label: t('marketplace.disclosure.network', { defaultValue: 'Network access' }), items: perms.network ?? undefined }), _jsx(PermissionGroup, { icon: FolderTree, label: t('marketplace.disclosure.fs', { defaultValue: 'Filesystem access' }), items: perms.fs ?? undefined })] })) : (_jsx("div", { className: "text-xs text-muted-foreground", children: t('marketplace.disclosure.noPermissions', { defaultValue: 'Requests no special permissions.' }) }))] }));
38
+ }