@object-ui/app-shell 6.2.3 → 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 +948 -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
@@ -0,0 +1,395 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
3
+ /**
4
+ * PackagesPage — the package management entry point for Studio.
5
+ *
6
+ * Studio previously exposed packages only through the sidebar `active_package`
7
+ * *filter* dropdown; there was no surface to see all packages, create one, or
8
+ * act on one (publish / revert / enable / disable). This page fills that gap.
9
+ *
10
+ * It is the authoring home for the Studio → package → publish workflow:
11
+ * 1. Create a package (POST /api/v1/packages with a minimal manifest).
12
+ * 2. Author metadata bound to it (via the sidebar scope + ResourceEditPage).
13
+ * 3. Publish it (POST /api/v1/packages/:id/publish).
14
+ *
15
+ * Backed entirely by the existing `/api/v1/packages` REST surface
16
+ * (see framework `http-dispatcher.handlePackages`).
17
+ */
18
+ import * as React from 'react';
19
+ import { Link, useLocation } from 'react-router-dom';
20
+ import { Package as PackageIcon, Plus, RefreshCw, Search, Upload, Download, FileUp, Undo2, Power, PowerOff, ExternalLink, AlertTriangle, Trash2, } from 'lucide-react';
21
+ import { Button, Input, Badge, Switch, Label, Separator, Skeleton, Empty, EmptyTitle, EmptyDescription, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '@object-ui/components';
22
+ import { detectLocale, t, tFormat } from './i18n';
23
+ const API = '/api/v1/packages';
24
+ async function apiJson(path, init) {
25
+ const res = await fetch(path, {
26
+ credentials: 'include',
27
+ headers: { Accept: 'application/json', ...(init?.headers || {}) },
28
+ ...init,
29
+ });
30
+ const text = await res.text();
31
+ const payload = text ? JSON.parse(text) : null;
32
+ if (!res.ok || payload?.success === false) {
33
+ const msg = payload?.error?.message ||
34
+ payload?.error ||
35
+ payload?.message ||
36
+ `Request failed (${res.status})`;
37
+ throw new Error(typeof msg === 'string' ? msg : `Request failed (${res.status})`);
38
+ }
39
+ // Runtime wraps successful payloads in { data, ... } or returns the object directly.
40
+ return (payload?.data ?? payload);
41
+ }
42
+ /* -------------------------------------------------------------------------- */
43
+ /* Scope badge */
44
+ /* -------------------------------------------------------------------------- */
45
+ function ScopeBadge({ scope }) {
46
+ const locale = React.useMemo(() => detectLocale(), []);
47
+ const s = scope ?? 'project';
48
+ const variant = s === 'project' ? 'default' : s === 'system' ? 'secondary' : 'outline';
49
+ const labelKey = s === 'project'
50
+ ? 'engine.packages.scope.project'
51
+ : s === 'system'
52
+ ? 'engine.packages.scope.system'
53
+ : s === 'cloud'
54
+ ? 'engine.packages.scope.cloud'
55
+ : '';
56
+ return _jsx(Badge, { variant: variant, children: labelKey ? t(labelKey, locale) : s });
57
+ }
58
+ function StatusBadge({ pkg }) {
59
+ const locale = React.useMemo(() => detectLocale(), []);
60
+ const enabled = pkg.enabled !== false && pkg.status !== 'disabled';
61
+ return (_jsx(Badge, { variant: enabled ? 'default' : 'outline', children: enabled ? t('engine.packages.status.enabled', locale) : t('engine.packages.status.disabled', locale) }));
62
+ }
63
+ /* -------------------------------------------------------------------------- */
64
+ /* Create-package dialog */
65
+ /* -------------------------------------------------------------------------- */
66
+ const ID_RE = /^[a-z0-9][a-z0-9._-]{1,254}$/i;
67
+ const VERSION_RE = /^\d+\.\d+\.\d+$/;
68
+ function CreatePackageDialog({ open, onOpenChange, onCreated, }) {
69
+ const locale = React.useMemo(() => detectLocale(), []);
70
+ const [id, setId] = React.useState('');
71
+ const [name, setName] = React.useState('');
72
+ const [version, setVersion] = React.useState('0.1.0');
73
+ const [busy, setBusy] = React.useState(false);
74
+ const [error, setError] = React.useState(null);
75
+ React.useEffect(() => {
76
+ if (open) {
77
+ setId('');
78
+ setName('');
79
+ setVersion('0.1.0');
80
+ setError(null);
81
+ setBusy(false);
82
+ }
83
+ }, [open]);
84
+ const idValid = ID_RE.test(id);
85
+ const versionValid = VERSION_RE.test(version);
86
+ const canSubmit = idValid && versionValid && !!name.trim() && !busy;
87
+ async function submit() {
88
+ if (!canSubmit)
89
+ return;
90
+ setBusy(true);
91
+ setError(null);
92
+ try {
93
+ await apiJson(API, {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json' },
96
+ body: JSON.stringify({
97
+ manifest: {
98
+ id: id.trim(),
99
+ name: name.trim(),
100
+ version: version.trim(),
101
+ type: 'app',
102
+ scope: 'project',
103
+ },
104
+ }),
105
+ });
106
+ onCreated(id.trim());
107
+ onOpenChange(false);
108
+ }
109
+ catch (e) {
110
+ setError(e?.message ?? t('engine.packages.create.failed', locale));
111
+ }
112
+ finally {
113
+ setBusy(false);
114
+ }
115
+ }
116
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t('engine.packages.create.title', locale) }), _jsx(DialogDescription, { children: tFormat('engine.packages.create.description', locale, { example: 'com.acme.crm' }) })] }), _jsxs("div", { className: "space-y-4 py-2", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "pkg-id", children: t('engine.packages.create.id', locale) }), _jsx(Input, { id: "pkg-id", placeholder: "com.acme.crm", value: id, onChange: (e) => setId(e.target.value), "aria-invalid": !!id && !idValid }), !!id && !idValid && (_jsx("p", { className: "text-xs text-destructive", children: t('engine.packages.create.idInvalid', locale) }))] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "pkg-name", children: t('engine.packages.create.name', locale) }), _jsx(Input, { id: "pkg-name", placeholder: "Acme CRM", value: name, onChange: (e) => setName(e.target.value) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(Label, { htmlFor: "pkg-version", children: t('engine.packages.create.version', locale) }), _jsx(Input, { id: "pkg-version", placeholder: "0.1.0", value: version, onChange: (e) => setVersion(e.target.value), "aria-invalid": !!version && !versionValid }), !!version && !versionValid && (_jsx("p", { className: "text-xs text-destructive", children: t('engine.packages.create.versionInvalid', locale) }))] }), error && (_jsxs("div", { className: "flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: error })] }))] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: busy, children: t('engine.cancel', locale) }), _jsx(Button, { onClick: submit, disabled: !canSubmit, children: busy ? t('engine.packages.create.creating', locale) : t('engine.packages.create.submit', locale) })] })] }) }));
117
+ }
118
+ /* -------------------------------------------------------------------------- */
119
+ /* Detail sheet — manifest + lifecycle actions */
120
+ /* -------------------------------------------------------------------------- */
121
+ function DetailRow({ label, children }) {
122
+ return (_jsxs("div", { className: "flex items-baseline justify-between gap-4 py-1.5", children: [_jsx("span", { className: "text-sm text-muted-foreground", children: label }), _jsx("span", { className: "text-sm font-medium text-right break-all", children: children })] }));
123
+ }
124
+ function PackageDetailSheet({ pkg, appBase, open, onOpenChange, onChanged, }) {
125
+ const locale = React.useMemo(() => detectLocale(), []);
126
+ const [busy, setBusy] = React.useState(null);
127
+ const [msg, setMsg] = React.useState(null);
128
+ // ADR-0033 — pending DRAFT items bound to this package. AI-authored metadata
129
+ // lands as drafts that the active-only browsers hide, so without this the
130
+ // package looks empty right after a build. We list them here with a link to
131
+ // the existing per-item review/diff (?review=1) so the user can publish them.
132
+ const [drafts, setDrafts] = React.useState(null);
133
+ React.useEffect(() => {
134
+ setMsg(null);
135
+ setBusy(null);
136
+ }, [pkg?.manifest.id]);
137
+ React.useEffect(() => {
138
+ const pid = pkg?.manifest.id;
139
+ if (!open || !pid) {
140
+ setDrafts(null);
141
+ return;
142
+ }
143
+ let cancelled = false;
144
+ apiJson(`/api/v1/meta/_drafts?packageId=${encodeURIComponent(pid)}`)
145
+ .then((r) => {
146
+ if (!cancelled)
147
+ setDrafts(r?.drafts ?? []);
148
+ })
149
+ .catch(() => {
150
+ if (!cancelled)
151
+ setDrafts([]);
152
+ });
153
+ return () => {
154
+ cancelled = true;
155
+ };
156
+ }, [open, pkg?.manifest.id]);
157
+ if (!pkg)
158
+ return null;
159
+ const id = pkg.manifest.id;
160
+ const enabled = pkg.enabled !== false && pkg.status !== 'disabled';
161
+ const isKernel = pkg.manifest.scope === 'system' || pkg.manifest.scope === 'cloud';
162
+ async function run(action, fn, okText) {
163
+ setBusy(action);
164
+ setMsg(null);
165
+ try {
166
+ await fn();
167
+ setMsg({ kind: 'ok', text: okText });
168
+ onChanged();
169
+ }
170
+ catch (e) {
171
+ setMsg({ kind: 'err', text: e?.message ?? t('engine.packages.detail.actionFailed', locale) });
172
+ }
173
+ finally {
174
+ setBusy(null);
175
+ }
176
+ }
177
+ const publish = () => run('publish', () => apiJson(`${API}/${encodeURIComponent(id)}/publish`, {
178
+ method: 'POST',
179
+ headers: { 'Content-Type': 'application/json' },
180
+ body: JSON.stringify({}),
181
+ }).then((r) => {
182
+ if (r && r.success === false) {
183
+ const n = r.validationErrors?.length ?? 0;
184
+ throw new Error(n
185
+ ? tFormat('engine.packages.detail.publishBlocked', locale, { count: n })
186
+ : r.validationErrors?.[0]?.message || t('engine.packages.detail.nothingToPublish', locale));
187
+ }
188
+ return r;
189
+ }), t('engine.packages.detail.published', locale));
190
+ // ADR-0033 — publish every pending draft of this app in one shot, then
191
+ // refresh the pending list (it should now be empty). Distinct from the
192
+ // registry-based `publish` above; this hits `/publish-drafts`.
193
+ const publishDrafts = () => run('publish-drafts', () => apiJson(`${API}/${encodeURIComponent(id)}/publish-drafts`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }).then(async (r) => {
194
+ try {
195
+ const fresh = await apiJson(`/api/v1/meta/_drafts?packageId=${encodeURIComponent(id)}`);
196
+ setDrafts(fresh?.drafts ?? []);
197
+ }
198
+ catch {
199
+ setDrafts([]);
200
+ }
201
+ if (r?.failedCount) {
202
+ throw new Error(tFormat('engine.packages.detail.publishDraftsPartial', locale, {
203
+ published: r.publishedCount ?? 0,
204
+ failed: r.failedCount,
205
+ }));
206
+ }
207
+ return r;
208
+ }), t('engine.packages.detail.publishDraftsOk', locale));
209
+ const revert = () => run('revert', () => apiJson(`${API}/${encodeURIComponent(id)}/revert`, { method: 'POST' }), t('engine.packages.detail.reverted', locale));
210
+ // ADR-0033 — discard every pending draft of this app in one shot, reverting
211
+ // it to the last published baseline. NON-destructive: published metadata and
212
+ // data are untouched. Distinct from the metadata-service `/revert` above —
213
+ // this hits the robust `/discard-drafts` (sys_metadata) path.
214
+ const discardDrafts = () => run('discard-drafts', () => apiJson(`${API}/${encodeURIComponent(id)}/discard-drafts`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }).then(async (r) => {
215
+ try {
216
+ const fresh = await apiJson(`/api/v1/meta/_drafts?packageId=${encodeURIComponent(id)}`);
217
+ setDrafts(fresh?.drafts ?? []);
218
+ }
219
+ catch {
220
+ setDrafts([]);
221
+ }
222
+ if (r?.failedCount) {
223
+ throw new Error(tFormat('engine.packages.detail.discardDraftsPartial', locale, {
224
+ discarded: r.discardedCount ?? 0,
225
+ failed: r.failedCount,
226
+ }));
227
+ }
228
+ return r;
229
+ }), t('engine.packages.detail.discardDraftsOk', locale));
230
+ // ADR-0033 — delete the WHOLE package: every metadata row (active + draft)
231
+ // plus each object's physical table (DESTRUCTIVE). Confirmed, then closes the
232
+ // sheet on success. Errors stay visible (sheet kept open).
233
+ const deleteApp = async () => {
234
+ const ok = window.confirm(tFormat('engine.packages.detail.deleteConfirm', locale, { name: pkg?.manifest.name || id }));
235
+ if (!ok)
236
+ return;
237
+ setBusy('delete');
238
+ setMsg(null);
239
+ try {
240
+ await apiJson(`${API}/${encodeURIComponent(id)}`, { method: 'DELETE' });
241
+ onChanged();
242
+ onOpenChange(false);
243
+ }
244
+ catch (e) {
245
+ setMsg({ kind: 'err', text: e?.message ?? t('engine.packages.detail.deleteFailed', locale) });
246
+ }
247
+ finally {
248
+ setBusy(null);
249
+ }
250
+ };
251
+ const toggleEnable = () => run('toggle', () => apiJson(`${API}/${encodeURIComponent(id)}/${enabled ? 'disable' : 'enable'}`, {
252
+ method: 'PATCH',
253
+ }), enabled ? t('engine.packages.detail.disabled', locale) : t('engine.packages.detail.enabled', locale));
254
+ const exportPkg = () => run('export', async () => {
255
+ const manifest = await apiJson(`${API}/${encodeURIComponent(id)}/export`);
256
+ const blob = new Blob([JSON.stringify(manifest, null, 2)], {
257
+ type: 'application/json',
258
+ });
259
+ const url = URL.createObjectURL(blob);
260
+ const a = document.createElement('a');
261
+ a.href = url;
262
+ a.download = `${id}.package.json`;
263
+ document.body.appendChild(a);
264
+ a.click();
265
+ a.remove();
266
+ URL.revokeObjectURL(url);
267
+ }, t('engine.packages.detail.exported', locale));
268
+ return (_jsx(Sheet, { open: open, onOpenChange: onOpenChange, children: _jsxs(SheetContent, { className: "w-full sm:max-w-md overflow-y-auto", children: [_jsxs(SheetHeader, { children: [_jsxs(SheetTitle, { className: "flex items-center gap-2", children: [_jsx(PackageIcon, { className: "h-4 w-4" }), pkg.manifest.name || id] }), _jsx(SheetDescription, { className: "font-mono text-xs", children: id })] }), _jsxs("div", { className: "mt-4", children: [_jsx(DetailRow, { label: t('engine.packages.col.version', locale), children: pkg.manifest.version || '—' }), _jsx(DetailRow, { label: t('engine.packages.detail.type', locale), children: pkg.manifest.type || '—' }), _jsx(DetailRow, { label: t('engine.packages.col.scope', locale), children: _jsx(ScopeBadge, { scope: pkg.manifest.scope }) }), _jsx(DetailRow, { label: t('engine.packages.col.status', locale), children: _jsx(StatusBadge, { pkg: pkg }) }), pkg.manifest.description && (_jsx(DetailRow, { label: t('engine.packages.detail.description', locale), children: pkg.manifest.description }))] }), _jsx(Separator, { className: "my-4" }), _jsxs(Link, { to: `${appBase}/metadata/object?package=${encodeURIComponent(id)}`, className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline", onClick: () => onOpenChange(false), children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5" }), t('engine.packages.detail.browseMetadata', locale)] }), drafts && drafts.length > 0 && (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { className: "space-y-2", children: [_jsxs("p", { className: "flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground", children: [t('engine.packages.detail.pendingChanges', locale), _jsx(Badge, { variant: "secondary", children: drafts.length })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: t('engine.packages.detail.pendingHint', locale) }), !isKernel && (_jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Button, { size: "sm", onClick: publishDrafts, disabled: !!busy, children: [_jsx(Upload, { className: "mr-1.5 h-3.5 w-3.5" }), busy === 'publish-drafts'
269
+ ? t('engine.packages.detail.publishing', locale)
270
+ : tFormat('engine.packages.detail.publishApp', locale, { count: drafts.length })] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: discardDrafts, disabled: !!busy, children: [_jsx(Undo2, { className: "mr-1.5 h-3.5 w-3.5" }), busy === 'discard-drafts'
271
+ ? t('engine.packages.detail.discarding', locale)
272
+ : tFormat('engine.packages.detail.discardChanges', locale, { count: drafts.length })] })] })), _jsx("ul", { className: "space-y-1", children: drafts.map((d) => (_jsx("li", { children: _jsxs(Link, { to: `${appBase}/metadata/${encodeURIComponent(d.type)}/${encodeURIComponent(d.name)}?review=1`, className: "inline-flex items-center gap-1.5 text-sm text-primary hover:underline", onClick: () => onOpenChange(false), children: [_jsx(FileUp, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "font-mono text-xs", children: d.type }), _jsx("span", { className: "text-muted-foreground", children: "\u00B7" }), d.name] }) }, `${d.type}/${d.name}`))) })] })] })), _jsx(Separator, { className: "my-4" }), isKernel ? (_jsx("p", { className: "text-sm text-muted-foreground", children: t('engine.packages.detail.kernelReadOnly', locale) })) : (_jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: t('engine.packages.detail.actions', locale) }), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsxs(Button, { size: "sm", onClick: publish, disabled: !!busy, children: [_jsx(Upload, { className: "mr-1.5 h-3.5 w-3.5" }), busy === 'publish' ? t('engine.packages.detail.publishing', locale) : t('engine.packages.detail.publish', locale)] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: revert, disabled: !!busy, children: [_jsx(Undo2, { className: "mr-1.5 h-3.5 w-3.5" }), t('engine.packages.detail.revert', locale)] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: toggleEnable, disabled: !!busy, children: [enabled ? (_jsx(PowerOff, { className: "mr-1.5 h-3.5 w-3.5" })) : (_jsx(Power, { className: "mr-1.5 h-3.5 w-3.5" })), enabled ? t('engine.packages.detail.disable', locale) : t('engine.packages.detail.enable', locale)] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: exportPkg, disabled: !!busy, children: [_jsx(Download, { className: "mr-1.5 h-3.5 w-3.5" }), busy === 'export' ? t('engine.packages.detail.exporting', locale) : t('engine.packages.detail.export', locale)] }), _jsxs(Button, { size: "sm", variant: "outline", onClick: deleteApp, disabled: !!busy, className: "text-destructive hover:bg-destructive/10 hover:text-destructive", children: [_jsx(Trash2, { className: "mr-1.5 h-3.5 w-3.5" }), busy === 'delete' ? t('engine.packages.detail.deleting', locale) : t('engine.packages.detail.deleteApp', locale)] })] })] })), msg && (_jsx("div", { className: `mt-4 rounded-md border p-2 text-sm ${msg.kind === 'ok'
273
+ ? 'border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400'
274
+ : 'border-destructive/40 bg-destructive/10 text-destructive'}`, children: msg.text }))] }) }));
275
+ }
276
+ /* -------------------------------------------------------------------------- */
277
+ /* Main page */
278
+ /* -------------------------------------------------------------------------- */
279
+ export function PackagesPage() {
280
+ const locale = React.useMemo(() => detectLocale(), []);
281
+ const { pathname } = useLocation();
282
+ // App base = path up to (and excluding) `/component/...`, so links to
283
+ // `/apps/:app/metadata/...` work regardless of nesting.
284
+ const appBase = React.useMemo(() => {
285
+ const idx = pathname.indexOf('/component');
286
+ return idx >= 0 ? pathname.slice(0, idx) : pathname;
287
+ }, [pathname]);
288
+ const [packages, setPackages] = React.useState([]);
289
+ const [loading, setLoading] = React.useState(true);
290
+ const [error, setError] = React.useState(null);
291
+ const [query, setQuery] = React.useState('');
292
+ const [showKernel, setShowKernel] = React.useState(false);
293
+ const [createOpen, setCreateOpen] = React.useState(false);
294
+ const [selected, setSelected] = React.useState(null);
295
+ const [detailOpen, setDetailOpen] = React.useState(false);
296
+ const fileRef = React.useRef(null);
297
+ const [importing, setImporting] = React.useState(false);
298
+ const [importMsg, setImportMsg] = React.useState(null);
299
+ const load = React.useCallback(async () => {
300
+ setLoading(true);
301
+ setError(null);
302
+ try {
303
+ const data = await apiJson(API);
304
+ const list = Array.isArray(data?.packages) ? data.packages : [];
305
+ list.sort((a, b) => {
306
+ // User (project) packages first, then by name.
307
+ const sa = a.manifest.scope === 'project' ? 0 : 1;
308
+ const sb = b.manifest.scope === 'project' ? 0 : 1;
309
+ if (sa !== sb)
310
+ return sa - sb;
311
+ return (a.manifest.name || a.manifest.id).localeCompare(b.manifest.name || b.manifest.id);
312
+ });
313
+ setPackages(list);
314
+ }
315
+ catch (e) {
316
+ setError(e?.message ?? t('engine.packages.loadFailed', locale));
317
+ }
318
+ finally {
319
+ setLoading(false);
320
+ }
321
+ }, [locale]);
322
+ React.useEffect(() => {
323
+ void load();
324
+ }, [load]);
325
+ // Keep the open detail sheet in sync with refreshed data.
326
+ React.useEffect(() => {
327
+ if (!selected)
328
+ return;
329
+ const fresh = packages.find((p) => p.manifest.id === selected.manifest.id);
330
+ if (fresh && fresh !== selected)
331
+ setSelected(fresh);
332
+ }, [packages, selected]);
333
+ const filtered = React.useMemo(() => {
334
+ const q = query.trim().toLowerCase();
335
+ return packages.filter((p) => {
336
+ const kernel = p.manifest.scope === 'system' || p.manifest.scope === 'cloud';
337
+ if (kernel && !showKernel)
338
+ return false;
339
+ if (!q)
340
+ return true;
341
+ return (p.manifest.id.toLowerCase().includes(q) ||
342
+ (p.manifest.name || '').toLowerCase().includes(q));
343
+ });
344
+ }, [packages, query, showKernel]);
345
+ const openDetail = (pkg) => {
346
+ setSelected(pkg);
347
+ setDetailOpen(true);
348
+ };
349
+ const onImportFile = async (e) => {
350
+ const file = e.target.files?.[0];
351
+ e.target.value = ''; // allow re-selecting the same file
352
+ if (!file)
353
+ return;
354
+ setImporting(true);
355
+ setImportMsg(null);
356
+ try {
357
+ const text = await file.text();
358
+ let manifest;
359
+ try {
360
+ manifest = JSON.parse(text);
361
+ }
362
+ catch {
363
+ throw new Error(t('engine.packages.import.invalidJson', locale));
364
+ }
365
+ if (!manifest || typeof manifest !== 'object' || (!manifest.id && !manifest.name)) {
366
+ throw new Error(t('engine.packages.import.invalidPackage', locale));
367
+ }
368
+ const res = await apiJson('/api/v1/marketplace/install-local', {
369
+ method: 'POST',
370
+ headers: { 'Content-Type': 'application/json' },
371
+ body: JSON.stringify({ manifest }),
372
+ });
373
+ setImportMsg({
374
+ kind: 'ok',
375
+ text: tFormat('engine.packages.import.success', locale, { id: res?.manifestId ?? manifest.id }),
376
+ });
377
+ await load();
378
+ }
379
+ catch (err) {
380
+ setImportMsg({ kind: 'err', text: err?.message ?? t('engine.packages.import.failed', locale) });
381
+ }
382
+ finally {
383
+ setImporting(false);
384
+ }
385
+ };
386
+ const kernelCount = packages.filter((p) => p.manifest.scope === 'system' || p.manifest.scope === 'cloud').length;
387
+ return (_jsxs("div", { className: "mx-auto w-full max-w-5xl px-6 py-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "rounded-lg bg-primary/10 p-2 text-primary", children: _jsx(PackageIcon, { className: "h-5 w-5" }) }), _jsxs("div", { children: [_jsx("h1", { className: "text-xl font-semibold tracking-tight", children: t('engine.packages.title', locale) }), _jsx("p", { className: "text-sm text-muted-foreground", children: t('engine.packages.description', locale) })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs(Button, { variant: "outline", size: "sm", onClick: () => void load(), disabled: loading, children: [_jsx(RefreshCw, { className: `mr-1.5 h-3.5 w-3.5 ${loading ? 'animate-spin' : ''}` }), t('engine.packages.refresh', locale)] }), _jsx("input", { ref: fileRef, type: "file", accept: "application/json,.json", className: "hidden", onChange: onImportFile }), _jsxs(Button, { variant: "outline", size: "sm", onClick: () => fileRef.current?.click(), disabled: importing, children: [_jsx(FileUp, { className: "mr-1.5 h-3.5 w-3.5" }), importing ? t('engine.packages.importing', locale) : t('engine.packages.import', locale)] }), _jsxs(Button, { size: "sm", onClick: () => setCreateOpen(true), children: [_jsx(Plus, { className: "mr-1.5 h-3.5 w-3.5" }), t('engine.packages.new', locale)] })] })] }), importMsg && (_jsx("div", { className: `mt-4 rounded-md border p-2 text-sm ${importMsg.kind === 'ok'
388
+ ? 'border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400'
389
+ : 'border-destructive/40 bg-destructive/10 text-destructive'}`, children: importMsg.text })), _jsxs("div", { className: "mt-5 flex flex-wrap items-center justify-between gap-3", children: [_jsxs("div", { className: "relative w-full max-w-xs", children: [_jsx(Search, { className: "absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { className: "pl-8", placeholder: t('engine.packages.search', locale), value: query, onChange: (e) => setQuery(e.target.value) })] }), kernelCount > 0 && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: "show-kernel", checked: showKernel, onCheckedChange: setShowKernel }), _jsx(Label, { htmlFor: "show-kernel", className: "text-sm text-muted-foreground", children: tFormat('engine.packages.showPlatform', locale, { count: kernelCount }) })] }))] }), _jsx("div", { className: "mt-4 rounded-lg border", children: loading ? (_jsx("div", { className: "space-y-2 p-4", children: [0, 1, 2].map((i) => (_jsx(Skeleton, { className: "h-10 w-full" }, i))) })) : error ? (_jsxs("div", { className: "flex items-start gap-2 p-4 text-sm text-destructive", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-4 w-4 shrink-0" }), _jsx("span", { children: error })] })) : filtered.length === 0 ? (_jsx("div", { className: "p-8", children: _jsxs(Empty, { children: [_jsx(EmptyTitle, { children: t('engine.packages.empty', locale) }), _jsx(EmptyDescription, { children: packages.length === 0
390
+ ? t('engine.packages.emptyCreate', locale)
391
+ : t('engine.packages.emptyFiltered', locale) })] }) })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [_jsx(TableHead, { children: t('engine.packages.col.name', locale) }), _jsx(TableHead, { children: "ID" }), _jsx(TableHead, { className: "w-24", children: t('engine.packages.col.version', locale) }), _jsx(TableHead, { className: "w-24", children: t('engine.packages.col.scope', locale) }), _jsx(TableHead, { className: "w-24", children: t('engine.packages.col.status', locale) })] }) }), _jsx(TableBody, { children: filtered.map((p) => (_jsxs(TableRow, { className: "cursor-pointer", onClick: () => openDetail(p), children: [_jsx(TableCell, { className: "font-medium", children: p.manifest.name || p.manifest.id }), _jsx(TableCell, { className: "font-mono text-xs text-muted-foreground", children: p.manifest.id }), _jsx(TableCell, { children: p.manifest.version || '—' }), _jsx(TableCell, { children: _jsx(ScopeBadge, { scope: p.manifest.scope }) }), _jsx(TableCell, { children: _jsx(StatusBadge, { pkg: p }) })] }, p.manifest.id))) })] })) }), _jsx(CreatePackageDialog, { open: createOpen, onOpenChange: setCreateOpen, onCreated: async () => {
392
+ await load();
393
+ } }), _jsx(PackageDetailSheet, { pkg: selected, appBase: appBase, open: detailOpen, onOpenChange: setDetailOpen, onChanged: () => void load() })] }));
394
+ }
395
+ export default PackagesPage;
@@ -31,4 +31,4 @@ export interface PageShellProps {
31
31
  /** Page body. */
32
32
  children: React.ReactNode;
33
33
  }
34
- export declare function PageShell({ entry, itemName, subtitle, stats, actions, children, }: PageShellProps): import("react/jsx-runtime").JSX.Element;
34
+ export declare function PageShell({ entry, itemName, subtitle, stats, actions, children, }: PageShellProps): React.JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
3
3
  /**
4
4
  * PageShell — common hero / breadcrumb / action bar for every metadata
@@ -18,7 +18,7 @@ import * as React from 'react';
18
18
  import { Link, useLocation } from 'react-router-dom';
19
19
  import { Badge } from '@object-ui/components';
20
20
  import { ChevronRight } from 'lucide-react';
21
- import { detectLocale, t, translateMetadataType } from './i18n';
21
+ import { detectLocale, t, translateMetadataType, translateMetadataDomain } from './i18n';
22
22
  export function PageShell({ entry, itemName, subtitle, stats, actions, children, }) {
23
23
  const type = entry?.type ?? '';
24
24
  const locale = React.useMemo(() => detectLocale(), []);
@@ -31,10 +31,15 @@ export function PageShell({ entry, itemName, subtitle, stats, actions, children,
31
31
  const idx = pathname.indexOf('/metadata');
32
32
  return idx >= 0 ? pathname.slice(0, idx + '/metadata'.length) : '/metadata';
33
33
  }, [pathname]);
34
- return (_jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [_jsxs("div", { className: "px-6 pt-5 pb-4 border-b bg-background", children: [_jsxs("nav", { className: "flex items-center gap-1.5 text-xs text-muted-foreground mb-2", children: [_jsx(Link, { to: metadataBase, className: "hover:text-foreground", children: t('engine.breadcrumb.allTypes', locale) }), _jsx(ChevronRight, { className: "h-3 w-3" }), _jsx(Link, { to: `${metadataBase}/${encodeURIComponent(type)}`, className: "hover:text-foreground", children: label }), itemName && (_jsxs(_Fragment, { children: [_jsx(ChevronRight, { className: "h-3 w-3" }), _jsx("span", { className: "text-foreground font-medium font-mono", children: itemName })] }))] }), _jsxs("div", { className: "flex items-start justify-between gap-3 flex-wrap", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("h1", { className: "text-xl font-semibold truncate", children: label }), _jsx("code", { className: "text-xs font-mono text-muted-foreground", children: type }), entry?.domain && (_jsx(Badge, { variant: "outline", className: "text-[10px] uppercase tracking-wider", children: entry.domain })), entry?.allowOrgOverride ? (_jsx(Badge, { className: 'text-[10px] ' +
34
+ return (_jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [itemName ? (_jsxs("div", { className: "px-6 py-2.5 border-b bg-background flex items-center gap-3 min-h-[44px]", children: [_jsxs("nav", { className: "flex items-center gap-1.5 text-xs text-muted-foreground min-w-0", children: [_jsx(Link, { to: metadataBase, className: "hover:text-foreground shrink-0", children: t('engine.breadcrumb.allTypes', locale) }), _jsx(ChevronRight, { className: "h-3 w-3 shrink-0" }), _jsx(Link, { to: `${metadataBase}/${encodeURIComponent(type)}`, className: "hover:text-foreground shrink-0", children: label }), _jsx(ChevronRight, { className: "h-3 w-3 shrink-0" }), _jsx("span", { className: "text-foreground font-medium font-mono truncate", title: itemName, children: itemName })] }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [entry?.domain && (_jsx(Badge, { variant: "outline", className: "text-[10px] uppercase tracking-wider h-5 px-1.5", children: translateMetadataDomain(entry.domain, locale) })), entry?.allowOrgOverride ? (_jsx(Badge, { className: 'text-[10px] h-5 px-1.5 ' +
35
+ (entry.overrideSource === 'env'
36
+ ? 'bg-amber-100 text-amber-800 hover:bg-amber-100'
37
+ : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-100'), title: entry.overrideSource === 'env'
38
+ ? 'Writable via OBJECTSTACK_METADATA_WRITABLE env var'
39
+ : 'Writable per ADR-0005 overlay opt-in', children: t('engine.badge.writable', locale) })) : entry?.allowRuntimeCreate ? (_jsx(Badge, { className: "text-[10px] h-5 px-1.5 bg-sky-100 text-sky-800 hover:bg-sky-100", title: "Code-shipped items are locked; new items can be created at runtime", children: t('engine.badge.createOnly', locale) })) : (_jsx(Badge, { variant: "outline", className: "text-[10px] h-5 px-1.5 text-muted-foreground", children: t('engine.badge.readOnly', locale) }))] }), subtitle && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: subtitle })), _jsx("div", { className: "flex-1" }), _jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [stats?.map((s, i) => (_jsxs("div", { className: "flex items-baseline gap-1 px-2 py-0.5 rounded border bg-muted/30", children: [_jsx("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: s.label }), _jsx("span", { className: "text-xs font-semibold tabular-nums", children: s.value })] }, i))), actions] })] })) : (_jsxs("div", { className: "px-6 pt-5 pb-4 border-b bg-background", children: [_jsxs("nav", { className: "flex items-center gap-1.5 text-xs text-muted-foreground mb-2", children: [_jsx(Link, { to: metadataBase, className: "hover:text-foreground", children: t('engine.breadcrumb.allTypes', locale) }), _jsx(ChevronRight, { className: "h-3 w-3" }), _jsx("span", { className: "text-foreground font-medium", children: label })] }), _jsxs("div", { className: "flex items-start justify-between gap-3 flex-wrap", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("h1", { className: "text-xl font-semibold truncate", children: label }), _jsx("code", { className: "text-xs font-mono text-muted-foreground", children: type }), entry?.domain && (_jsx(Badge, { variant: "outline", className: "text-[10px] uppercase tracking-wider", children: translateMetadataDomain(entry.domain, locale) })), entry?.allowOrgOverride ? (_jsx(Badge, { className: 'text-[10px] ' +
35
40
  (entry.overrideSource === 'env'
36
41
  ? 'bg-amber-100 text-amber-800 hover:bg-amber-100'
37
42
  : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-100'), title: entry.overrideSource === 'env'
38
43
  ? 'Writable via OBJECTSTACK_METADATA_WRITABLE env var'
39
- : 'Writable per ADR-0005 overlay opt-in', children: "writable" })) : (_jsx(Badge, { variant: "outline", className: "text-[10px] text-muted-foreground", children: "read-only" }))] }), subtitle && (_jsx("div", { className: "text-sm text-muted-foreground mt-1", children: subtitle })), !subtitle && entry?.description && (_jsx("div", { className: "text-sm text-muted-foreground mt-1 max-w-3xl", children: entry.description }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [stats?.map((s, i) => (_jsxs("div", { className: "flex flex-col items-end px-3 py-1 rounded border bg-muted/30 min-w-[64px]", children: [_jsx("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: s.label }), _jsx("span", { className: "text-sm font-semibold tabular-nums", children: s.value })] }, i))), actions] })] })] }), _jsx("div", { className: "flex-1 overflow-auto", children: children })] }));
44
+ : 'Writable per ADR-0005 overlay opt-in', children: t('engine.badge.writable', locale) })) : entry?.allowRuntimeCreate ? (_jsx(Badge, { className: "text-[10px] bg-sky-100 text-sky-800 hover:bg-sky-100", title: "Code-shipped items are locked; new items can be created at runtime", children: t('engine.badge.createOnly', locale) })) : (_jsx(Badge, { variant: "outline", className: "text-[10px] text-muted-foreground", children: t('engine.badge.readOnly', locale) }))] }), subtitle && (_jsx("div", { className: "text-sm text-muted-foreground mt-1", children: subtitle })), !subtitle && entry?.description && (_jsx("div", { className: "text-sm text-muted-foreground mt-1 max-w-3xl", children: entry.description }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [stats?.map((s, i) => (_jsxs("div", { className: "flex flex-col items-end px-3 py-1 rounded border bg-muted/30 min-w-[64px]", children: [_jsx("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground", children: s.label }), _jsx("span", { className: "text-sm font-semibold tabular-nums", children: s.value })] }, i))), actions] })] })] })), _jsx("div", { className: "flex-1 overflow-auto", children: children })] }));
40
45
  }
@@ -1,5 +1,39 @@
1
+ /**
2
+ * PermissionMatrixEditor — custom editor for `type=permission` (Phase 3e).
3
+ *
4
+ * Renders the Salesforce-style matrix that lives behind a Permission
5
+ * Set / Profile metadata item:
6
+ *
7
+ * • Top section — object-level CRUD + VAMA (View All / Modify All)
8
+ * + lifecycle (Transfer / Restore / Purge).
9
+ * • Lower section — field-level R/W for the fields of any object
10
+ * selected from the table above.
11
+ *
12
+ * Data model (matches `PermissionSetSchema` in
13
+ * `packages/spec/src/security/permission.zod.ts`):
14
+ *
15
+ * {
16
+ * name: string,
17
+ * label?: string,
18
+ * isProfile?: boolean,
19
+ * objects: { [object_name]: ObjectPermission },
20
+ * fields?: { [`${object_name}.${field_name}`]: FieldPermission },
21
+ * systemPermissions?: string[],
22
+ * tabPermissions?: Record<string, 'visible'|'hidden'|'default_on'|'default_off'>,
23
+ * }
24
+ *
25
+ * Wiring: registered from `builtinComponents.tsx` as
26
+ * registerMetadataResource({ type: 'permission', EditPage: PermissionMatrixEditPage })
27
+ *
28
+ * The component reads `/api/v1/meta/object` + `/api/v1/meta/field` to
29
+ * enumerate available objects and their fields. Saves through the
30
+ * standard metadata save flow (overlay-aware, OCC, destructive-change
31
+ * dialog already provided by the generic engine — we go through
32
+ * client.save() directly).
33
+ */
34
+ import * as React from 'react';
1
35
  export interface PermissionMatrixEditPageProps {
2
36
  type: string;
3
37
  name: string;
4
38
  }
5
- export declare function PermissionMatrixEditPage({ type, name }: PermissionMatrixEditPageProps): import("react/jsx-runtime").JSX.Element;
39
+ export declare function PermissionMatrixEditPage({ type, name }: PermissionMatrixEditPageProps): React.JSX.Element;
@@ -1,5 +1,25 @@
1
+ /**
2
+ * MetadataQuickFind — Cmd+K palette that searches across all
3
+ * metadata types (Phase 3c).
4
+ *
5
+ * Behaviour:
6
+ * • Mounted as a side-effect via `<MetadataQuickFindMount />`.
7
+ * • Listens for Cmd+K / Ctrl+K globally; opens a dialog with a
8
+ * search input.
9
+ * • Free-text search hits two pools:
10
+ * (a) Metadata types from `/meta/types` (jump to directory entry).
11
+ * (b) Items of any type — lazy-fetched the first time the palette
12
+ * opens, cached for the session.
13
+ * • Selecting a result navigates to the appropriate route.
14
+ *
15
+ * Trade-offs: For the MVP we eagerly fetch the item index on first
16
+ * open (one `/meta/:type` per writable type). For most workspaces
17
+ * that's a few hundred items total — well within a fast modal load.
18
+ * If usage grows we'll switch to server-side search.
19
+ */
20
+ import * as React from 'react';
1
21
  export interface MetadataQuickFindProps {
2
22
  /** Optional app slug for routing; defaults to "setup" if unknown. */
3
23
  appSlug?: string;
4
24
  }
5
- export declare function MetadataQuickFind({ appSlug }?: MetadataQuickFindProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function MetadataQuickFind({ appSlug }?: MetadataQuickFindProps): React.JSX.Element;
@@ -25,9 +25,9 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@object-ui/co
25
25
  import { Input } from '@object-ui/components';
26
26
  import { Badge } from '@object-ui/components';
27
27
  import { Kbd } from '@object-ui/components';
28
- import { Search, Loader2 } from 'lucide-react';
28
+ import { Search, Loader2, Lock } from 'lucide-react';
29
29
  import { useMetadataClient, useMetadataTypes, } from './useMetadata';
30
- import { detectLocale, t as tr } from './i18n';
30
+ import { detectLocale, t as tr, translateMetadataType } from './i18n';
31
31
  export function MetadataQuickFind({ appSlug } = {}) {
32
32
  const navigate = useNavigate();
33
33
  const client = useMetadataClient();
@@ -76,6 +76,8 @@ export function MetadataQuickFind({ appSlug } = {}) {
76
76
  name: String(name),
77
77
  label: item?.label,
78
78
  description: item?.description,
79
+ lock: typeof item?._lock === 'string' ? item._lock : undefined,
80
+ lockReason: typeof item?._lockReason === 'string' ? item._lockReason : undefined,
79
81
  });
80
82
  }
81
83
  }
@@ -105,6 +107,7 @@ export function MetadataQuickFind({ appSlug } = {}) {
105
107
  const typeHits = typeEntries
106
108
  .filter((e) => e.type.toLowerCase().includes(q) ||
107
109
  (e.label ?? '').toLowerCase().includes(q) ||
110
+ translateMetadataType(e.type, locale, e.label).toLowerCase().includes(q) ||
108
111
  (e.description ?? '').toLowerCase().includes(q))
109
112
  .slice(0, 8)
110
113
  .map((entry) => ({ kind: 'type', entry }));
@@ -146,7 +149,7 @@ export function MetadataQuickFind({ appSlug } = {}) {
146
149
  }
147
150
  }
148
151
  return (_jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsxs(DialogContent, { className: "max-w-2xl p-0 overflow-hidden", children: [_jsx(DialogHeader, { className: "sr-only", children: _jsx(DialogTitle, { children: tr('engine.quickfind.title', locale) }) }), _jsxs("div", { className: "border-b px-3 py-2 flex items-center gap-2", children: [_jsx(Search, { className: "h-4 w-4 text-muted-foreground" }), _jsx(Input, { autoFocus: true, placeholder: tr('engine.quickfind.placeholder', locale), value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: onKeyDown, className: "border-0 shadow-none focus-visible:ring-0 px-0" }), _jsx(Kbd, { children: "esc" })] }), _jsxs("div", { className: "max-h-[440px] overflow-auto", children: [itemsLoading && (_jsxs("div", { className: "px-3 py-4 text-xs text-muted-foreground flex items-center gap-2", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }), tr('engine.quickfind.indexing', locale), " ", typeEntries.length, "\u2026"] })), !itemsLoading && results.length === 0 && (_jsx("div", { className: "px-3 py-6 text-xs text-muted-foreground text-center", children: tr('engine.quickfind.noMatches', locale) })), _jsx("ul", { role: "listbox", children: results.map((r, i) => (_jsx("li", { children: _jsxs("button", { type: "button", onClick: () => navigateTo(r), onMouseEnter: () => setActiveIdx(i), className: 'w-full text-left px-3 py-2 flex items-center gap-3 hover:bg-accent ' +
149
- (i === activeIdx ? 'bg-accent' : ''), children: [_jsx(Badge, { variant: "outline", className: "text-[10px] font-mono shrink-0", children: r.kind === 'type' ? 'type' : r.type }), _jsx("div", { className: "min-w-0 flex-1", children: r.kind === 'type' ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-sm font-medium truncate", children: r.entry.label ?? r.entry.type }), r.entry.description && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.entry.description }))] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-sm font-mono truncate", children: [r.name, r.label && (_jsx("span", { className: "text-muted-foreground font-sans ml-2", children: r.label }))] }), r.description && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.description }))] })) })] }) }, r.kind === 'type'
152
+ (i === activeIdx ? 'bg-accent' : ''), children: [_jsx(Badge, { variant: "outline", className: "text-[10px] font-mono shrink-0", children: r.kind === 'type' ? 'type' : r.type }), _jsx("div", { className: "min-w-0 flex-1", children: r.kind === 'type' ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-sm font-medium truncate", children: translateMetadataType(r.entry.type, locale, r.entry.label) }), r.entry.description && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.entry.description }))] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-sm font-mono truncate flex items-center gap-1.5", children: [r.lock && r.lock !== 'none' && (_jsx("span", { className: "text-amber-600 dark:text-amber-400 shrink-0", title: r.lockReason ?? `_lock=${r.lock}`, "aria-label": "locked", children: _jsx(Lock, { className: "h-3 w-3" }) })), r.name, r.label && (_jsx("span", { className: "text-muted-foreground font-sans ml-2", children: r.label }))] }), r.description && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: r.description }))] })) })] }) }, r.kind === 'type'
150
153
  ? `t:${r.entry.type}`
151
154
  : `i:${r.type}:${r.name}`))) })] }), _jsxs("div", { className: "border-t px-3 py-1.5 flex items-center gap-3 text-[10px] text-muted-foreground", children: [_jsxs("span", { children: [_jsx(Kbd, { children: "\u2191" }), " ", _jsx(Kbd, { children: "\u2193" }), " navigate"] }), _jsxs("span", { children: [_jsx(Kbd, { children: "\u21B5" }), " open"] }), _jsxs("span", { className: "ml-auto", children: [_jsx(Kbd, { children: "\u2318" }), _jsx(Kbd, { children: "\u21E7" }), _jsx(Kbd, { children: "M" }), " toggle"] })] })] }) }));
152
155
  }
@@ -1,3 +1,26 @@
1
+ /**
2
+ * RelatedPanel — lists metadata items anchored to the current parent.
3
+ *
4
+ * Driven by the anchor registry (see `anchors.ts` / `registry.ts`). For
5
+ * each child type that declares it anchors at `parentType`, we issue
6
+ * one `client.list(childType)` call in parallel, filter the result with
7
+ * the anchor's match predicate, and render the survivors in collapsible
8
+ * groups.
9
+ *
10
+ * Why client-side filter? Anchoring lives in metadata bodies that are
11
+ * not indexed on the server today, and adding a parameterised list API
12
+ * for every potential anchor field would balloon the surface area. The
13
+ * Related tab is opened by humans on a specific object, so the cost of
14
+ * pulling 100-or-so items per child type is negligible — far cheaper
15
+ * than a network round-trip per row would have been.
16
+ *
17
+ * Visual model:
18
+ * - One <details> per group (default open if non-empty).
19
+ * - Rows are kebab-y: name, optional label, optional badge.
20
+ * - Click → call `onOpen({ type, name })`; parent owns the drawer.
21
+ * - A search input filters across all groups by name/label substring.
22
+ */
23
+ import * as React from 'react';
1
24
  export interface RelatedPanelProps {
2
25
  /** Parent metadata type, e.g. `object`. */
3
26
  type: string;
@@ -34,4 +57,4 @@ export type RelatedTarget = {
34
57
  /** Dotted path inside parent where this collection lives (e.g. 'fields'). */
35
58
  embeddedPath?: string;
36
59
  };
37
- export declare function RelatedPanel({ type, name, parentItem, onOpen, }: RelatedPanelProps): import("react/jsx-runtime").JSX.Element;
60
+ export declare function RelatedPanel({ type, name, parentItem, onOpen, }: RelatedPanelProps): React.JSX.Element;