Skip to content

Studio: an All metadata area in the builder — directory, lists, generic item page, history and diagnostics, per package and across packages; pillar types open their pillar #28561

Closed

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

Filing gate: ④ child of epic #28236 (P3, cut 2026-11-01 on the maintainer's 「四项提速措施全部按推荐执行」, schedule reviewed) · plan of record: ADR-0146 Rollout P3 "N-26 the metadata directory into Studio (D1)"; schedule review correction 7: the browse half can start now. ⛔ Not a claim.

Part of #28236 (P3, child N-26a) · governs: ADR-0146 D1 ("an 'All metadata' area joins [the pillars], per package and across packages, holding … the type directory, lists, the generic item page. A pillar type opened from the directory opens its pillar"; read-only tools on a read-only package) · lane: domain:ui · size: L.

Business reason. A developer in Studio on HotCRM sometimes needs a type the four pillars do not cover, such as a translation, a job or an agent. Today they leave Studio for Setup's metadata pages to browse it. Studio should hold the whole catalog, per package and across packages, so Setup can stop being a second metadata home.

Measured (35b178bd0a).

  • The catalog is ui/packages/app-shell/src/views/metadata-admin/: DirectoryPage.tsx (type tiles, domain chips, "Writable only", scope by ?package= limited to project packages, HIDDEN_TYPES field and package), ResourceListPage, ResourceEditPage, MetadataResourceHistoryPage, DiagnosticsPage. It is served under any app segment at /apps/:app/metadata[/_diagnostics|/:type[/new|/:name[/history]]] (console/AppContent.tsx:1499–1506; no-app branch :1385–1390).
  • The Studio builder is /studio/:packageId/:tab (ui/apps/console/src/components/StudioRoute.tsx:290). Its tabs are the four PILLARS (studio-design/StudioDesignSurface.tsx:436), and any other tab is a not-found state (:1529). Pillars open one item from ?surface=TYPE:NAME (useSurfaceDeepLink.ts).
  • Studio app navigation already has "All Metadata Types" (packages/platform-objects/src/apps/studio.app.ts:119–125). It renders the same page in app chrome at /apps/studio/metadata, outside the builder.
  • Setup's Access Control entries open environment-scope lists: position, capability, permission and sharing_rule with ?scope=environment (packages/plugins/plugin-security/src/security-plugin.ts:1643–1645, packages/plugins/plugin-sharing/src/sharing-plugin.ts:672; catalog-scope.ts:39–86).
  • The AI review deep link opens /apps/:app/metadata/:type/:name?review=1 (console/AppContent.tsx:241).
  • PR feat(console): an admin can open a read-only package's app in Studio to look at it #28076 (D5) landed the app → Studio browse entry into the pillars only. No directory is in the builder.

Wanted.

  1. An All metadata area in the builder for the open package: directory, type list, generic item page, history and diagnostics. These are the existing metadata-admin components mounted, not copied. The dev settles the route (e.g. /studio/:packageId/metadata/...) and registers it, so it is not a not-found tab.
  2. A cross-package leg of the same area with no package scope, which serves the environment-scope lists and items above with ?scope=environment.
  3. A pillar type opened from the area opens its pillar with ?surface=: object → Data; flow → Automations; page, dashboard, report and view → Interfaces; permission → Access. Every other type opens the generic item page in the area.
  4. The area keeps the query parameters ?package=, ?scope=environment and ?review=1 with today's meaning, so a later redirect (N-28) loses no deep link.
  5. On a read-only package the item page is read-only. Layers, references, history, audit and source are shown. No rollback, source save, reset, delete or "Customize with an overlay" save is offered in Studio (D1). On a writable package it saves exactly as the Setup page does with ?package= (same component, same doors). No new write path.
  6. Assignment sections (permission-set holders, position holders) are not drawn here. A link opens their Setup page (N-27, Setup: position holders and permission-set assignment as people-and-organization pages #28241). The datasource tile links out to Setup, which keeps datasources (D1).
  7. Setup's pages are not changed.

Tests.

  • The area mounts at its route for a writable and a read-only package, and in the cross-package leg.
  • Opening object, flow, view and permission lands in the right pillar with ?surface=.
  • A translation opens the generic page, read-only on a read-only package, with no overlay save.
  • A ?scope=environment permission list renders, and ?review=1 opens the review.
  • The existing metadata-admin tests stay green.

Release safety. Additive: a new area in Studio, nothing removed or redirected, server untouched. Safe with no Blocked-by:.

Not here. "Customized / added" marks (N-26b). The simplified translation and email-template editors (N-25). Setup redirects, Packaged automation retirement and re-pointing Studio app's nav_metadata_directory (N-28). Customization writes (N-17).

Dedupe. Searched metadata directory studio "all metadata", setup metadata redirect studio: only #28236, #28130 (closed) and QA runs.

Links back: #28236, #28076, #28241, ADR-0146 D1, D5, D7.


Generated by Claude Code

Activity

  1. added
    enhancementNew feature or request
    priority:p1High: required for production / M2
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Nov 1, 2026
  2. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Claim: PM loop round 1 · 2026-11-01T06:51Z
    Session: session_01QsR2jSErqBgsh8YbjzzqZ9 (card thread, os-dev); dispatched by seat session session_01QsR2jR7ZFkpqmm4U8S1f9y
    Account: zhuangjianguo
    Branch: claude/project-thread-ddww6q (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-28561
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: ui/packages/app-shell/src/views/metadata-admin/**, ui/packages/app-shell/src/views/studio-design/**, ui/apps/console/src/components/StudioRoute.tsx and console routing (stop on breach; explain in the report)
    Container & model: L, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: xhigh
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: none
    Premise: holds
    Serial constraints cleared: none (no open PR or live claim touches these paths; the last landings there are #28420, #28395, #28366, #28329, #28296, all merged; seat 1's live card #28469 is the record page tab row)

    Governing text: ADR-0146 D1, as quoted on this card. Sub-issue N-26a of #28236. The seat checks the size at review: over 3000 changed lines lands as Tier H.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    ACCEPT → PR #28623 comment 6555968635 · 2026-11-01T09:14Z · no contract-review face owed · landing through the merge queue. Out-of-scope finding filed as #28626.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jSErqBgsh8YbjzzqZ9
    os-dev-report

    {
      "issue": 28561,
      "status": "done",
      "branch": "claude/project-thread-ddww6q",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28623",
      "head": "db612603",
      "session": "session_01QsR2jSErqBgsh8YbjzzqZ9",
      "premise_still_valid": true,
      "measured": "Premise held at 310cb96d: only Setup mounted the metadata-admin pages (AppContent metadata/* routes); Studio's :packageId/:tab route matched one segment, so no Studio URL could reach them. Clause-2 on source: the six new strings live in @object-ui/i18n's studio namespace, whose table is declared Record<string, string> (namespaces/studio/en.ts) and is outside the locales packs, so no published literal type widens; the claim's 'Clause-②: no' holds and is copied verbatim. Main merged at a9c6eac6 (9 commits, no shared file).",
      "summary": "Studio's builder gains an 'All metadata' area beside the four pillars: /studio/<package>/metadata/* mounts Setup's metadata-admin pages (directory, list, generic item page, history, diagnostics) lazily through the specifier AppContent uses, and /studio/~all/metadata/* is the cross-package leg serving the environment catalog with ?scope=environment. The pages read a MetadataAreaHostContext that only the area provides (package pin, read-only, root), so Setup renders unchanged; ?package=, ?scope=environment and ?review=1 keep their Setup meaning via areaLocationRedirect. object/flow/page/dashboard/report/view/permission items open their pillar with ?surface= (Interfaces now opens an off-nav item by its link); a package GET /api/v1/packages lists as not writable gets a read-only item page, history, permission editor and list, assignments link to Setup and datasource URLs open Setup's Datasources page.",
      "tests": "New: metadataArea.test.ts 10, StudioMetadataArea.routes-28561 16, metadataAreaHost.gates-28561 9, metadataAreaHost.scope-28561 9, InterfacesPillar.offNavDeepLink-28561 5, StudioDesignSurface.metadataArea-28561 5, console StudioRoute.metadataArea-28561 8: all passed. Edited header tests (notFound-26708, accessSegment-12452, rightSlot-12725, narrowHeader-12509, pillarNavGuard) 43/43; packageLessFlows-11553 asserts no area link. Ablations (committed first, file restored by git checkout): area canWrite host gate removed -> 2 failed; off-nav deep link removed -> 3 failed; surface area prop removed -> 3 failed | 2 passed; the two new console routes removed -> 4 failed | 4 passed. Regression: the 283 existing test files that import a changed module, six batches under os-verify-lock, every VERDICT command-exit 0 (303+260+279+234+151+514 tests); the 8 console Studio route files 69/69; packages/i18n/ plus 4 studio-namespace files 98 files, 1632 passed | 13 skipped. Type-check app-shell (tsconfig.test.json included), console, i18n: exit 0. ESLint on the 29 changed ts/tsx: 0 errors, 0 findings on changed lines. Console vite build exit 0, check:eager-closure 2052.2 KB / 2431.6 KB budget, all per-chunk ceilings hold, 41 ineffective dynamic imports all pinned.",
      "gates": "dispatch-gates --commands derived 34 at the merged head; all 34 run, each exit 0 (check:type-check-debt under os-verify-lock, VERDICT 0, 0 raw tsc errors). --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. PR-body gates on the final body: check-closing-keyword-parity (GITHUB_EVENT_PATH) 0, check-partof-closing-keyword (PR_BODY) 0, check-changeset-no-major --base origin/main 0, check-adr-0087-registration --base origin/main 0. check-sdui-manifest 0; check:i18n-keys, check:i18n-drift, check:i18n-dead-keys 0. Pre-push check:commit-card-trailers passed on 7 messages. CI check-runs on #28623: not yet reported at report time.",
      "dogfood_battery": "n/a: no ! in the title and no (narrowing) arm",
      "line_budget": "30 files, +2134 / -58 = 2192 changed lines (873 source, 1319 tests), under the 3000-line Tier H threshold",
      "files_changed": [
        ".changeset/28561-studio-all-metadata-area.md",
        "ui/apps/console/src/components/StudioRoute.tsx",
        "ui/apps/console/src/components/StudioRoute.metadataArea-28561.test.tsx",
        "ui/apps/console/src/components/studioBuilder.ts",
        "ui/packages/app-shell/src/index.ts",
        "ui/packages/app-shell/src/views/item-tools/ResourceHistoryPage.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/{DirectoryPage,PageShell,PermissionMatrixEditor,QuickFind,ResourceEditPage,ResourceListPage}.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/{metadataAreaHost.ts,SetupAssignmentsLink.tsx}",
        "ui/packages/app-shell/src/views/metadata-admin/metadataAreaHost.{gates,scope}-28561.test.tsx",
        "ui/packages/app-shell/src/views/studio-design/{BuilderLanding,StudioDesignSurface,StudioMetadataArea}.tsx",
        "ui/packages/app-shell/src/views/studio-design/metadataArea.ts",
        "ui/packages/app-shell/src/views/studio-design/{metadataArea.test.ts,StudioMetadataArea.routes-28561.test.tsx,InterfacesPillar.offNavDeepLink-28561.test.tsx,StudioDesignSurface.metadataArea-28561.test.tsx}",
        "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.{notFound-26708,accessSegment-12452,rightSlot-12725,packageLessFlows-11553}.test.tsx",
        "ui/packages/i18n/src/namespaces/studio/{en,zh}.ts"
      ],
      "deviations": [
        "File surface breaches, each explained in the PR body: item-tools/ResourceHistoryPage.tsx (rollback gate and back link under the area), i18n studio en.ts/zh.ts (six strings and the not-found sentence), app-shell src/index.ts (barrel exports for the console), console studioBuilder.ts (the one lazy boundary).",
        "InterfacesPillar (in StudioDesignSurface.tsx, inside the surface) now opens a page/dashboard/report/view no nav entry opens by its ?surface= link; without it the card's Interfaces redirect landed on the first nav leaf instead of the item.",
        "The header names 'All metadata' from 1280 px (xl), the pillars from 1024 px as before: the 1024 px row was sized for four names.",
        "An unknown or failed GET /api/v1/packages read leaves the area ungated, as the pillars are; the server's write gate stays the authority.",
        "Not pinned by a test: QuickFind on the cross-package leg (reads the area root, filters item hits to the area's package).",
        "Left as Setup has them: type-level MetadataTypeActions, the permission set's 'Clone to customize', and the landing's 'Open in Setup' overlay link (N-28).",
        "For N-28: Setup->Studio redirects must exempt datasource, since the area sends every datasource URL to /apps/setup/metadata/datasource; redirecting both ways loops.",
        "PR opened without assignees or reviewers, per the seat's order; no GitHub MCP write."
      ],
      "mcp_calls": "2: GitHub MCP issue_read get_comments on #28561 x1 and #28552 x1 (report shape), both reads. No MCP write. Separately, 1 subscribe_pr_activity on #28623 (claude-code-remote, not GitHub MCP).",
      "api_writes": "2: relay repository_dispatch POST /repos/objectstack-ai/objectstack/dispatches x2 (pr_create #28623, run 41290885638, read-back identical 10860 bytes; this os-dev-report comment). git push x2 is not a REST write.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a · reach: Setup > Metadata > an item > History > the back-to-item button lands on /apps/setup/metadata/<name> (the :type list route for a type named after the item) instead of /apps/setup/metadata/<type>/<name>; reproduced at db612603 with the AppContent nesting (/apps/:appName > metadata > :type/:name/history), MetadataResourceHistoryPage type=translation name=ui_en, click -> pathname /apps/setup/metadata/ui_en · evidence: ResourceHistoryPage.tsx navigate(`../${name}`) is route-relative, so .. drops the whole :type/:name/history route · the area builds the link from its root, so Studio is not affected · dedupe words: history back to item, ResourceHistoryPage navigate ../, metadata history wrong route"
      ]
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y

    Landed · 2026-11-01T11:29Z · PR #28623 merged through the merge queue as 3694d3b8. Records: ACCEPT 6555968635 (at db612603) and its head-moved re-pin 6557187236 (at 5c4f96bb); no contract review owed.

    probe before (3694d3b8~1) now (origin/main)
    STUDIO_ALL_PACKAGES_SEGMENT in studio-design/StudioMetadataArea.tsx 0 (no file) 2
    MetadataAreaHostContext in metadata-admin/metadataAreaHost.ts 0 (no file) 2
    engine.studio.pillar.metadata in i18n/src/namespaces/studio/en.ts 0 1

    The card closed through Fixes. Out-of-scope finding filed as #28626. For N-28 (#28236): Setup → Studio redirects must exempt datasource, since the area sends datasource URLs to Setup. pm:dispatched comes off in the same stroke as this note.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:uienhancementNew feature or requestpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions