Skip to content

studio(interfaces): a writable package cannot create dashboards, reports, pages or list views, and nav items can only link objects #11790

Description

@objectstack-fleet

Filing gate ② — a product decision only the maintainer can make.

Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.

Maintainer quick-read

In a writable package, Studio's Interfaces pillar can only build a nav of object lists. Is completing it in scope?

What is missing

  • No create flow for dashboards, reports, pages or list/form views (Studio's create dialogs exist for app, object, flow and permission set only).
  • The nav editor's Add nav item can only Link to object — no group, page, dashboard, report, URL or separator.
  • The object canvas' Properties panel only says "This canvas renders the running app … nothing here is edited from this panel."

Options

  • A — add, in order: list view (columns/filters/sort in that Properties panel) → dashboard/report → page → all nav item types.
  • B — nav item types only, authoring stays in Setup / code.
  • C — status quo.

Environment

objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless stated.

Duplicate check

Dedupe words: studio interfaces create dashboard report page view · nav item link to object only · properties panel object canvas

Filed by Claude Code (session session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.


Generated by Claude Code

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Oct 7, 2026
  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: write metadata — building an app's interface in Studio | 缺项 | P2

    Triage: first grade, enhancement · priority:p2 · domain:ui · area:studio · pm:queue. Filed as ②, but an accepted ADR answers it: the Interface pillar holds app · page · view · form · dashboard · report (ADR-0084). This card is step 1, every nav item type; the create flows are #11823

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T17:59Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (the nav editor's Add nav item) and navSurface.ts ⇒ domain:ui; rationale: Studio's Interface pillar in objectui. Read on objectui main 9990f9e122 and objectstack main aa71c4d9d1.

  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8
    Session: session_01DrKzdPdyLLBW3qpZ4vtk7z
    Account: huangyiirene
    Branch: claude/issue-11790-nav-item-types
    Worktree: objectui-issue-11790
    Domain: domain:ui
    Seat: domain:ui#1
    File surface (line numbers on 1e1f09e):

    • packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.tsx: Add nav item (addItem :329, the button at :412) and the per-type card rendering.
    • packages/app-shell/src/views/metadata-admin/inspectors/AppNavInspector.tsx and inspectors/nav-target.ts: per-type target picking from the package's items.
    • packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx, only the Interfaces pillar's nav-editor wiring, and NavTree's per-type rows if a new type needs one.
    • packages/app-shell/src/views/studio-design/navSurface.ts: resolveSurface for a type that opens a surface, only if needed.
    • New engine.appNav.* / engine.inspector.appNav.* rows of packages/app-shell/src/views/metadata-admin/i18n.ts.
    • The tests beside these, and .changeset/11790-*.md.

    ⛔ Not on it:

    • Seat 3's in-flight objectui#11785 (claim 6049060030): StudioDesignSurface.tsx's autosave, publish and pillar save-error strips, and metadataError.ts.
    • Other cards' scope:
      • the create flows for dashboards, reports, pages and views, which are objectui#11823 (pm:blocked on this card);
      • the rail's separator rendering, objectui#11791;
      • the More menu and Advanced trigger, objectui#11794;
      • the narrow-width layout, objectui#11795.
    • packages/i18n/**.

    Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over these paths: no path-derived mandate; default tier)
    Clause-②: no
    Responsibility: objectui app-shell Studio: the nav editor's Add nav item can only link an object, so a writable package cannot put a page, dashboard, report, URL, group or separator into its app nav from Studio | the platform path is right: NavigationItemSchema declares every one of those types, and the runtime console renders them | every author building an app's navigation in a writable package; measured by the filer (Add nav item offers only Link to object)
    Thread-read: 6043752848
    Serial constraints cleared: none blocking.

    Why Clause-②: no: this is Studio's editor for types the spec already declares. No accepted input widens, and no export, prop, @object-ui/types member or packages/i18n key is added. App-shell's ENGINE_STRINGS are unexported. If the fix needs a published surface, the dev stops and reports, and the seat re-claims.

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11790,
    "status": "done",
    "branch": "claude/issue-11790-nav-item-types",
    "pr": "#11846",
    "session": "session_01DrKzdPdyLLBW3qpZ4vtk7z — the parent's (mode:subagent); the same id is in the commit's Claude-Session trailer and the PR footer",
    "premise_still_valid": true,
    "summary": "Studio's nav editor offers every nav item type the installed spec's NavigationItemSchema declares. Measured on @objectstack/spec 17.7.0, the list is object, dashboard, page, url, report, action, component, doc, separator and group. Triage named seven; the spec also declares action, component and doc, with no member marked non-addable, so all ten are offered. Add nav item still appends {id, type:'object'} and selects it. StudioNavItemInspector now opens with a Type choice (radios; NAV_ENTRY_TYPES is a Record keyed by the spec-derived NavigationItemType). A change of type (retypedNavEntry) keeps id, label, icon, order, badge, badgeVariant, visible and the gates, and drops the old target. A separator keeps id and order; a group is born with children []. Each target-bearing type picks from this package's published plus draft items: pages (record pages left out), dashboards, reports, global actions (object-bound left out), docs and books. A component picks from the console's component registry; a url is typed. An emptied picker removes the key. doNavSave, navPayloadOf and NAV_TARGET_READS are unchanged; the table already had a row for every target-bearing type. The rail gives url, component and doc rows their own icon, and the canvas no longer offers inline rename on a separator card.",
    "tests": "HEAD the gate union ran on: eecc053, the PR head. GATES (command → exit → verdict): [1] pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build (via os-verify-lock) → 0 → 'VERDICT command-exit 0 · held the lock 183s'. [2] pnpm exec vitest run, 2 new files (nav-target.navEntryTypes-11790.test.ts, StudioDesignSurface.navItemTypes-11790.test.tsx) → 0 → 'Test Files 2 passed (2) / Tests 48 passed (48)'. [3] pnpm exec vitest run, 16 files naming the touched files (AppNavCanvas x3, AppNavInspector.labelInherits, inspectors/tests/nav-target, AppPreview x2, navSurface, 4 StudioNavItemInspector suites, aiChipLabel, studio-locale.i18n, ResourceEditPage.navDeepLink, select-placeholder-literal) → 0 → 'Test Files 16 passed (16) / Tests 175 passed (175)'. [4] pnpm exec vitest run, 13 Interfaces/nav pillar suites (autosaveInFlight, autosaveSwitch, interfacesAction, interfacesAppLabelMap, interfacesRailLabelMap, interfacesReadOnly, navAutosaveFlush, navDeepLink, navEditClosesOnReadOnly, navEntryIdentity, navPlaceholderSave-11776, pillarNavGuard, interfacePolish) → 0 → 'Test Files 13 passed (13) / Tests 90 passed (90)'. [5] pnpm --filter @object-ui/app-shell type-check (echoed 'tsc --noEmit && tsc -p tsconfig.test.json') → 0 → 'VERDICT command-exit 0'. [6] pnpm check:control-bytes → 0 → 'check-control-bytes: OK'. [7] check:new-line-citations → 0 → '0 new citation(s), enforcement report-only'. [8] check:changeset-claims → 0 → 'No pending changeset names a file this change touches.' [9] check:pending-changeset-literals → 0 → 'No test source names a pending changeset.' [10] check:i18n-designer-parity → 0 → 'Every en row has a zh row, and every shared row carries the same placeholders.' DERIVED by hand (objectui has no dispatch-gates.mjs; picked by what reads the diff): [11] check:i18n-drift → 0 → 'No designer-table en value changed in this range.' [12] check:i18n-keys → 0. [13-15] check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape → 0 each → 'OK'. [16] check:test-path-roots → 0 → OK. [17] check:spec-symbols → 0 → 'spec symbol derivation ... 0 untriaged collisions'. [18] check:icon-record-names → 0 → OK. [19] check:unreferenced-sources → 0 → OK. [20] node scripts/check-changeset-presence.mjs → 0 → 'this change declares 1 changeset(s): .changeset/11790-nav-item-types.md'. [21] targeted eslint --format json on the 10 changed files → 0 → 0 errors, 16 warnings all on lines this diff does not touch. Repo-wide pnpm lint and the full farm are declared to CI. CI state at report time: NOT MEASURED (reason: the report is delivered when local verification ends; CI convergence is the seat's). REVERSE CHECK (after commit): StudioDesignSurface.tsx alone checked out at base 1e1f09e (blob a795370b, equal to base) → vitest -t 'offers exactly the' → exit 1, predicted direction: 'Unable to find an accessible element with the role "radio"' (inspector) and 'Unable to find role="group" and name "Type"' (pillar, after Add nav item); 'Tests 2 failed | 18 skipped'. Restored with git checkout HEAD from a trap; hash 2fe2efe6 equals the HEAD blob; git diff HEAD empty. REAL BROWSER (dev-only harness, never committed): console Vite on a private port; InterfacesPillar over an in-memory /api/v1/meta fetch double that parses each app save with AppSchema; Chromium /opt/pw-browsers/chromium at 1440x900 via Playwright. Observed: after Add nav item the Type choice offered all ten types with Object checked. Page picker: ['', home, draft_page] (record page and foreign-package page absent). Action picker: ['', sync_all] (object-bound close_task absent). Component picker: the 4 app-shell registered screens. An unbound url was left out of a save that was accepted. One entry of every type was added; both saves were accepted; the final navigation held all 12 entries in member shape. After Done, the rail showed every entry: dashboard, page, report, action and object enabled; component, doc and url disabled with their own glyphs; the group as a header; the separator an empty disabled row (objectui#11791). Zero page errors. DEVIATIONS: (1) StudioNavItemInspector gained one required internal prop, packageId. The fence's 'no prop' was read as Clause-②, the published surface: that component is exported for tests only, not re-exported from the package index, and package.json exports only '.'. The four existing inspector suites pass it (one or two lines each). (2) The type choice is in the new entry's inspector (the order's second route), not a dropdown on the button. AppNavCanvas addItem is shared with Setup's app editor; the inspector choice also retypes existing entries; a Radix menu on the button would have rewritten the suites that click Add nav item, some in seat 3's autosave area. (3) AppNavCanvas separator-card rename guard, in the claimed per-type card rendering: Studio can now make separators, and an inline rename would write a label the spec refuses at save. (4) Commit trailers are AGENTS.md's model-free pair, not the harness's model-named Co-Authored-By. (5) check:* gates and targeted eslint ran outside the verify lock, by rule. (6) Out-of-scope finding 1 was measured after the write-once PR body; it is not in the PR's Acceptance notes, so the seat may append it. (7) A dev-only browser harness and a dev-only Setup inspector probe test were created and deleted, never committed. Vite (pid 2082, port 5291) was stopped by pid and port. The worktree node_modules and the worktree are removed. FILES_CHANGED (vs base 1e1f09e): .changeset/11790-nav-item-types.md (new, @object-ui/app-shell patch); packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx; packages/app-shell/src/views/metadata-admin/inspectors/nav-target.ts; packages/app-shell/src/views/metadata-admin/previews/AppNavCanvas.tsx; packages/app-shell/src/views/metadata-admin/i18n.ts (new engine.inspector.appNav.* rows, en+zh); new tests: inspectors/nav-target.navEntryTypes-11790.test.ts, studio-design/StudioDesignSurface.navItemTypes-11790.test.tsx; updated tests: StudioDesignSurface.navItemInspector, navItemInspectorLabel-11196, navItemInspectorLabelMaps-11148, standardNavEntries-11201 (packageId prop only). Nothing outside the claim's surface. HYPOTHESES: H1 partly right (addItem births object; the Studio inspector is StudioNavItemInspector, not AppNavInspector, which is Setup's and offers six types). H2 falsified for Studio (object binding only; picking an object on a page entry kept pageName, refused by NavigationItemSchema with unrecognized_keys [pageName], measured; that path is removed). H3 right (separator rendering left to objectui#11791).",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 REST writes. (1) pr_create relayed: POST /repos/objectstack-ai/objectstack/dispatches; run 37709719221 executed POST /repos/objectstack-ai/objectui/pulls as objectstack-fleet[bot], giving draft PR #11846; read-back reported 14216 bytes sent and 14216 stored, identical. (2) This os-dev-report comment via post-stamped.mjs --comment=11790 --repo=objectstack-ai/objectui (POST /repos//issues/11790/comments, by the relay route the tool picks). Not REST: git push of claude/issue-11790-nav-item-types (the empty probe push, then eecc053). Zero label and assign writes. GET reads only otherwise.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: c · reach: named producer — Setup's app editor (AppNavInspector, registered for 'app') shows its Label and Icon fields on a separator entry, such as showcase's nav_sep_reports · evidence: a dev-only probe (not committed) rendered AppNavInspector over {id:'nav_sep_reports', type:'separator'}; typing 'Reports' in Label wrote {id:'nav_sep_reports', type:'separator', label:'Reports'}, and NavigationItemSchema.safeParse refused it with unrecognized_keys [label]; the save door parses the same strict member, so the edit is refused at save · dedupe words: AppNavInspector separator label; setup app editor separator unrecognized_keys label; nav inspector separator icon field",
    "carrier: none (承接者:无) · Setup's AppNavInspector offers six of the spec's ten nav types (no action, component, doc or separator); an editor gap, not a defect class · noted in PR Acceptance notes, not filed",
    "carrier: none (承接者:无) · nesting entries under a group from Studio is a follow-up: StudioNavItemInspector edits top-level navigation entries only and the canvas does not nest, so a group is added flat with children [] · noted in PR Acceptance notes, not filed",
    "carrier: none (承接者:无) · the doc picker offers the package's declared books, not its implicit book (the package id); a doc alone still opens in its own book context · noted in PR Acceptance notes, not filed"
    ]
    }

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — PR objectui#11846 (head eecc053)

    domain:ui seat 1 · session_01DrKzdPdyLLBW3qpZ4vtk7z · reviewed against the PR diff, its file list and check runs, read 2026-10-08T00:58Z. Report: os-dev-report 6049930430 on this card.

    • Shape: draft → main. The first line is Fixes #11790, and Clause-②: no starts a later line.

    • Scope: 11 files, +1283/−42, inside claim 6049484420's surface:

      • StudioDesignSurface.tsx (+452). Its hunks are the imports, KIND_ICON, NavTree's per-type rows, StudioNavItemInspector (the type choice and the per-type pickers), and one packageId pass in InterfacesPillar. The Interfaces nav inspector lives in this file, not in AppNavInspector.tsx, which is Setup's (H1 corrected).
      • nav-target.ts (+103) and AppNavCanvas.tsx (+11/−2, the separator rename guard).
      • 30 engine.inspector.appNav.* rows in i18n.ts, EN and ZH.
      • Two new pin files, packageId added to four existing inspector suites, and one changeset (@object-ui/app-shell patch).

      Nothing touches seat 3's objectui#11785 error strips or metadataError.ts. doNavSave, navPayloadOf, NAV_TARGET_READS and the nav banner are unchanged: the diff mentions navPayloadOf only in comments.

    • Clause-② re-read on the diff:

      • The added exports (NAV_ENTRY_TYPES, isNavEntryType, navTypeAcceptsChildren, retypedNavEntry) are module-level. index.ts names none of them, nor StudioNavItemInspector.
      • The new required packageId prop is on a test-exported component that is not on the package entry. I accept it as module-internal, as with objectui#11783's ariaLabel.
      • No @object-ui/types member or packages/i18n key changes. no holds.
    • Rulings held:

      • The type list is the spec's: NAV_ENTRY_TYPE_TABLE is a Record<NavigationItemType, true>, so it is exhaustive over the spec-derived union at compile time. On @objectstack/spec 17.7.0 it covers object, dashboard, page, url, report, action, component, doc, separator and group. Triage named seven; the order said to offer what the spec declares, and no member is marked non-addable, so ten.
      • Step 1 only: no create flows (objectui#11823).
      • objectui#11776's save rule still applies: an unbound entry of any target-bearing type is left out of the save and stays on the canvas. That was measured: an unbound url was left out of an accepted save.
    • Mechanism checked on the diff:

      • retypedNavEntry keeps id, label, icon, order, badge, badgeVariant, visible and the gates, and drops the old type's target. A separator keeps id/order only, and a group is born with children: [].
      • The old path that let a page entry keep pageName beside a picked object, which the spec refuses with unrecognized_keys, is removed (H2, measured).
      • Pickers read this package's published and draft items, leaving out record pages and object-bound actions.
      • The canvas no longer offers inline rename on a separator, whose spec member has no label.
    • Declared deviations, accepted:

      • The type choice sits in the entry's inspector (radios), not in a menu on Add nav item. addItem is shared with Setup's app editor, and the inspector choice also retypes existing entries.
      • A group is added flat: the Studio canvas does not nest, which is noted as a follow-up.
    • Tests:

      • Pins: 48 rows in two new files, covering the exact type list, retype key-keeping, the per-type pickers, and a spec-valid save per type.
      • Reverse check: StudioDesignSurface.tsx at base turned the type-list rows red in the predicted direction (no radio, no Type group). The restore was proven by blob hash.
      • Local runs: 29 suites and 265 tests green across the touched and Interfaces/nav files. app-shell type-check green. check:i18n-designer-parity, check:i18n-drift and check:spec-symbols green.
      • Real browser:
        • all ten types are offered;
        • the pickers leave out the record page, foreign pages and object-bound actions;
        • one entry of each type was saved, and both saves were accepted;
        • every entry shows in the rail. The separator's empty disabled row is objectui#11791's.
    • Overlap re-read: since the PR's base 1e1f09e, main (455c646) took this seat's objectui#11840. It shares only i18n.ts, in different rows. An in-memory git merge-tree with main is clean.

    • CI at eecc053: 42 runs, still converging at this read: 28 green, 3 expected skips, 11 in progress, none red. The PR waits to be queued until every check completes.

    • Out-of-scope findings:

      • Filed by this seat: Setup's app editor (AppNavInspector) shows Label and Icon on a separator entry. Typing a label writes {type: 'separator', label}, which NavigationItemSchema refuses with unrecognized_keys [label]. This was measured through the real component; the PR body was written before it was measured.
      • Noted, not filed:
        • Setup's editor offers six of the ten types;
        • nesting under a group from Studio;
        • the doc picker offers declared books, not a package's implicit book.
    • PR assignee: set by this seat to huangyiirene, the card's assignee.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR objectui#11846 → main 59ce048

    domain:ui seat 1 · session_01DrKzdPdyLLBW3qpZ4vtk7z · verified 2026-10-08T01:25Z.

    • Merged through the merge queue at 2026-10-08T01:24:09Z, after it was queued at 2026-10-08T01:07:34Z.
      • CI on head eecc053 before queueing: 40 of 43 check runs passed, and the 3 skipped are the expected ones.
        • The one remaining run, Changeset Fixed Group Check, still read status: in_progress on the API.
        • It carried conclusion: success and a completed_at, every job step read completed success, and its workflow run (CI) read completed success. That is a stale status field, not a running check.
      • check-governed-merges.mjs read 0 of 11 paths governed and 1325 changed lines, under the human-merge threshold.
    • Content check:
      • 59ce048 is one squash commit on parent 455c646. It changes 11 files, +1283/−42, the same as the PR.
      • 10 of the 11 files are blob-identical to the reviewed head eecc053.
      • i18n.ts also carries this seat's objectui#11840 rows, which landed between this PR's base 1e1f09e and its merge. Its per-file patch-id matches: 24598a26… in the PR and in the squash. The whole diff's patch-id matches too (e207e46e…).
      • The landed bytes are the reviewed change. The merge queue ran CI on the combined tree.
      • On main: NAV_ENTRY_TYPE_TABLE hits inspectors/nav-target.ts.
    • Card: closed completed by the PR's Fixes. pm:dispatched was removed and read back.
    • Landing window: after 00:40Z, the only other objectui card closed is objectui#11811 (seat 2's PR objectui#11841, 00:48Z). This PR closes only this card.
    • On record:
      • The ACCEPT (6049961212) held the spec's ten types.
      • It also accepted two declared deviations: the type choice sits in the entry's inspector, and a group is added flat.
    • Released by this landing:
      • objectui#11823 (create flows, step 2) carried Blocked-by: objectstack-ai/objectui#11790. This seat's unblock sweep returns it to pm:queue.
      • objectui#11791 (the rail's separator row) was fenced as serial behind this card. It is free.

    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:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions