Skip to content

Console home: search in the top bar, a greeting with a work summary, compact builder actions and 56 px app tiles #12601

Closed

Description

@objectstack-fleet

Source

Measured on objectui main 1b3b5b102, /home at 1280 px, light and dark, zh-CN, signed in as an admin with HotCRM installed (packages/app-shell/src/console/home/HomePage.tsx, HomeRail.tsx, RecentApps.tsx). The top bar has no search entry (the Studio landing has one); the hero is a 30 px greeting and the tagline "从上次离开的地方继续,或者探索新的内容。"; below it two full-width bordered cards "构建应用 / 从模板开始" take the first screen although only an admin sees them; "我的应用 2" is a row of 48 px icons where "系统设置" counts as an app; everything on the page is a bordered white card of the same weight.

Target

Sections ① and ② of the artboard "系统首页 · 四段式" (1280 × 1040), in numbers; sections ③ and ④ are the two sibling cards.

  1. Top bar, 48 px, grid 1fr auto 1fr: left the product mark (28 px tile on --primary, 14 px / 600 name, the existing preview chip); centre a 420 × 32 px search field "搜索应用、记录、页面…" with a ⌘K kbd that opens the console's command palette; right bell with its count, help, 28 px avatar.
  2. Content column 1120 px centred, 28 px top padding, 28 px between sections.
  3. Greeting 24 px / 600 with the name in --primary; under it one 13 px muted line that summarises the work section: "今天有 N 项待审批、M 项分配给你的任务" (both counts from the same sources the work section reads; the line reads "今天没有待办" when both are 0).
  4. Admin actions sit at the right of the greeting as two 32 px chips: "从模板开始" outline, "构建应用" on --primary-soft with the primary-coloured icon. The two cover cards retire; their gate reasons (objectui#5521's visible reason) move to the chips' tooltip wrapper (objectui#12303 pattern) when disabled. A non-admin sees no chips.
  5. "我的应用" heading 15 px / 600 with a count pill; at the right "浏览应用市场" (12 px link, marketplace gated as today) and "系统设置" as a muted 12 px link with the gear icon. Setup leaves the app row.
  6. Tiles: 112 px wide, 56 px icon on the app's colour (14 px radius), 13 px / 500 name on one line with an ellipsis, 11 px muted "N 小时前打开" from the recent-items store; favourites first; an admin sees a trailing dashed "添加应用" tile that opens the same marketplace route.
  7. No bordered card around sections ① and ②.

File surface

packages/app-shell/src/console/home/HomePage.tsx, HomeRail.tsx (apps strip), RecentApps.tsx, the console top bar in packages/app-shell/src/layout/AppHeader.tsx (search entry on /home), packages/i18n/src/locales/*.ts, tests beside each.

Acceptance

  1. Tests: the search field opens the command palette; a non-admin renders no builder chips; a disabled chip explains itself through the tooltip wrapper; Setup is not among the tiles; a tile shows the last-opened time from the store.
  2. Screenshots at 1280 px, light and dark, admin and non-admin, as measurements in the PR text.
  3. pnpm --filter @object-ui/app-shell test green; pnpm check:i18n green.

Constraints

  • Existing data-testids (home-build-app, home-start-template, home-authoring-gate-reason, home-marketplace-disabled-reason) keep their names on the new elements.
  • Tailwind utilities and theme tokens only.
  • Lands before the two sibling cards (same file); they rebase on it.

Evidence

The artboards, as static HTML and 1280 px PNG renders, live on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit c4dfb417a, never merged; the maintainer ruled that design files and screenshots do not enter main). Files: Home.png · Home.html.

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 review of the console login page and home page with the maintainer, on objectui main 1b3b5b102 and HotCRM 63db83e2. The maintainer approved the artboards in that session, verbatim: 「同意设计稿,创建任务」.

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    and removed on Oct 16, 2026
  2. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (priority:p2; sections ① and ② of the artboard "系统首页 · 四段式", approved by the maintainer in the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12601-home-top-and-apps
    Worktree: objectui-issue-12601
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/app-shell/src/console/home/HomePage.tsx, HomeRail.tsx (the apps strip), RecentApps.tsx, packages/app-shell/src/layout/AppHeader.tsx (the search entry on /home only), packages/i18n/src/locales/*.ts, tests beside each, and one @object-ui/app-shell changeset (plus @object-ui/i18n if touched) (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: opus (default tier)
    Clause-②: yes
    Clause-② reason: AppHeader and HomePage are exported from @object-ui/app-shell. A search entry shown on /home only may need a new AppHeader prop, and the route is not chosen yet («拿不准 ⇒ 按 yes»). The seat's TIER_DEFAULT review comes before ready.
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: no open PR touches packages/app-shell/src/console/home/ or packages/app-shell/src/layout/ (scanned every open objectui PR's file list), and no in-flight claim names them. Per the card's own constraint this lands before its siblings objectui#12602 and #12604 (same HomeRail.tsx / HomePage.tsx). objectui#12605 (AppHeader.tsx) is held until this lands.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · takeover of claim 6207344600 (the claimant's session ran out of tokens mid-build)
    Release: claim 6207344600 · session session_01JZnppgHRp4sREcouhkQYDB · account sunhaolin · reason: the claimant is unreachable (token exhaustion; no PR, no os-dev-report) · destination: this claim, same branch, same declarations
    Provenance: the maintainer · in session session_011K9g23W67dy2zwnyzaoB6o, the /pm-dispatch UI seat 1 summons, read 2026-10-16T06:36Z · verbatim: 「前任没有token了,他的任务开发了一半你要接着处理。」
    Session: session_011K9g23W67dy2zwnyzaoB6o
    Account: os-tesla
    Branch: claude/issue-12601-home-top-and-apps
    Worktree: objectui-issue-12601
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/app-shell/src/console/home/ (the pushed tip touches HomePage.tsx, HomeLayout.tsx and HomeAppsStrip.tsx; claim 6207344600 named HomeRail.tsx and RecentApps.tsx in the same directory), packages/app-shell/src/layout/AppHeader.tsx (the search entry on /home only), packages/i18n/src/locales/*.ts, tests beside each, and one @object-ui/app-shell changeset (plus @object-ui/i18n if touched) (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui over the tip's 18 paths: no path-derived mandate)
    Clause-②: yes
    Clause-② reason: carried unchanged from 6207344600: AppHeader and HomePage are exported from @object-ui/app-shell, and a search entry shown on /home only may need a new AppHeader prop («拿不准 ⇒ 按 yes»). The seat's TIER_DEFAULT review comes before ready.
    Responsibility: n/a — not a defect card
    Thread-read: 6207344600
    Serial constraints cleared: the only open objectui PR besides dependabot and the release PR is #12630 (Studio automations rail), whose files are disjoint; the in-flight branches of objectui#12603, #12611, #12612, #12617, #12620, #12621 and #12626 touch none of this surface. Per the card, this lands before its siblings objectui#12602 and #12604 (same files); objectui#12605 (AppHeader.tsx) is held until it lands. objectui#12600 also adds keys to packages/i18n/src/locales/*.ts: ordinary concurrency.
    Resume-from: claude/issue-12601-home-top-and-apps@3cc9fa19d02b6b5bd028624077b997ca5708b011

    Handover record. Last pushed sha 3cc9fa19d0 (2026-10-16T03:51:28Z), one commit on base 33fbc861d2 carrying the feature, two new test files, one updated test, the changeset and the locale strings. No PR and no report exist. Everything on the branch is UNVERIFIED: the resuming dev reads the commit hunk by hunk, merges origin/main, re-runs every gate and the screenshots the acceptance names, and opens the draft PR.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 12601,
     "status": "done",
     "branch": "claude/issue-12601-home-top-and-apps",
     "pr": "https://github.com/objectstack-ai/objectui/pull/12638",
     "session": "session_011K9g23W67dy2zwnyzaoB6o",
     "premise_still_valid": true,
     "summary": "Resumed from 3cc9fa1 (dead dev, session_01JZnppgHRp4sREcouhkQYDB), merged origin/main 63d00da as f2ef2c1, read every inherited hunk against the card: all kept (HomeLayout mounts the existing CommandPalette scoped to Home's host app; AppHeader centres a 420 px home search only where a palette is mounted, no new prop; 24 px greeting + approvals summary line; two 32 px builder chips with the objectui#12303 tooltip wrapper; 1120 px column; 112 px tiles, Setup moved to a System Settings link, admin Add app tile). Missing piece added in 9aa8059: the tile's 11 px 'Opened 2 hours ago' line from the recent-items store (lastOpenedByApp: newest entry whose /apps/SEGMENT href resolves to the app via matchAppBySegment; new key home.appOpened in ten packs). efe6e9d removes the three keys the retired tagline and cover cards orphaned (home.heroTagline, home.build.subtitle, home.template.subtitle) and corrects the changeset's surface statement; 42e5761 drops a leftover blank line. Coordinator's mid-task input folded in: each of the five acceptance items has its own pin and each pin went red on ablation (table in the PR). Draft PR #12638, assignee os-tesla read back, body read back byte-identical (12475 bytes).",
     "tests": "At 42e5761, through os-verify-lock: `pnpm exec vitest run packages/app-shell/src/console/home/ packages/app-shell/src/layout/ packages/app-shell/src/console/__tests__/ packages/app-shell/src/__tests__/ packages/app-shell/src/chrome/ (+ views/__tests__/phase1-page-blocks.render.test.tsx, views/metadata-admin/previews/__tests__/exclusion-reason-truthfulness.test.ts) --maxWorkers=2` -> Test Files 171 passed (171), Tests 1476 passed (1476); `pnpm exec vitest run packages/i18n/` -> Test Files 83 passed (83), Tests 1321 passed | 13 skipped (1334); seven apps/console tests mounting DefaultHomeLayout/App -> Test Files 7 passed (7), Tests 277 passed (277). Ablations (source-resolved subjects, no dist; each through objectstack scripts/ablation-replace.mjs WRAP mode: anchor 1->0, blob changed, restored blob == HEAD, git diff HEAD empty; run at 9aa8059, later commits touch none of the anchors): A1 HomeLayout `{hostApp ? (`->`{false ? (` => searchOpensPalette 4 failed/1 passed (CONTROL stays green); A2 `{isAdmin && (`->`{true && (` => 'a non-admin renders no builder chips' failed (1 failed/13 passed); A3 `if (!disabled) return button;`->`return button;` => both tooltip-wrapper cases failed (2/12); A4 launcherApps=activeApps => 'Setup is not among the tiles' + last-opened case failed (2/12); A5 lastOpened={undefined} => 'a tile shows when its app was last opened' failed (1/13). H1 measured by building app-shell at HEAD and with packages/app-shell/src at 63d00da (trap restore, blob == HEAD proven): dist/index.d.ts closure 180 files both sides, same list, 2 differ (HomeLayout.d.ts, AppHeader.d.ts) in doc comments only; HomeAppsStrip.d.ts (+settingsHref, +lastOpened, optional) and new appLastOpened.d.ts are outside the closure.",
     "gates": "Local, hand-derived from objectui package.json + .github/workflows (objectui has no dispatch-gates.mjs), all at 42e5761, exit captured before any pipe: deps closure build `pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build` exit 0; `pnpm --filter @object-ui/i18n build` 0; `pnpm --filter @object-ui/app-shell type-check` 0 (script echoed: tsc --noEmit && tsc -p tsconfig.test.json); `pnpm --filter @object-ui/i18n type-check` 0; check:i18n-keys 0; check:i18n-drift 0 ('No en value changed in this range', 7 keys added at the earlier reading); check:i18n-dead-keys 0 (report-only; none of the new keys listed, the three removed no longer listed); check:test-path-roots 0; check:changeset-claims 0 (one read request on .changeset/11659-console-record-ux.md naming HomePage.tsx: read, still true); changeset:check 0; check-changeset-presence 0; check-changeset-overwrite 0; check-new-cross-file-line-citations 0 (0 new); check-control-bytes 0; check-vi-mock-inherit/override-shape/specifiers 0/0/0; check:unreferenced-sources 0; check:esm-specifiers 0; check:self-import 0; eslint over the 19 changed .ts/.tsx 0 (0 errors, 33 warnings of existing kinds). `pnpm check:i18n` named on the card does not exist. CI (PR #12638 check-runs at report time, head 42e5761): Changeset Bump Policy success, Changeset Fixed Group Check success, label success; in_progress: Build & E2E, Build Docs, Bundle Analysis, Changeset Claim Re-read, Changeset Declaration, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, Lint, Live E2E (informational), Repo Gates, Test (dist pins), Test (shard 1..16/16), Type Check; skipped: Test (coverage), Test (coverage shard), dependabot. NOT MEASURED locally: full app-shell package (1436 files) and full pnpm test -> CI shards; Bundle Analysis (needs full packages + console build) -> CI; screenshots -> the seat's shared browser reading.",
     "mcp_calls": "0",
     "api_writes": "2 REST writes, both through objectstack scripts/pm tools: (1) fleet relay POST /repos/objectstack-ai/objectstack/dispatches (run 38872200535, success) executing pr_create = POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12638/assignees [os-tesla]; (2) this report: post-stamped.mjs -> POST /repos/objectstack-ai/objectui/issues/12601/comments. Zero label writes. git push x4 (merge f2ef2c1, 9aa8059, efe6e9d, 42e5761), not REST.",
     "open_questions": [
      {
       "question": "The card's Target 1 asks for a 48 px top bar; Home's bar stays 56 px (h-14), the height AppShell, StudioRoute and HomeLayout all draw. Changing Home alone would make the bar jump on entering an app. Who carries the 48 px?",
       "options": [
        "A: fold it into objectui#12605 (holds AppHeader; its AppBar artboard is 48 px too) and change all frames together",
        "B: a follow-up on HomeLayout only, accepting a height change between Home and apps"
       ],
       "recommendation": "A, because the height is one number across four frames and objectui#12605 already owns the bar; B buys the artboard on one route at the cost of a visible jump."
      }
     ],
     "out_of_scope_findings": [
      "carrier: objectui#12602 (seat to fold into its scope) · noted, not filed — useSharedPendingApprovalsCount returns the value only, no read status, so the new summary line says 'Nothing is waiting for you today' while the approvals read is in flight or after it fails; HomeActionCenter's 'You're all caught up' on main treats the same count as an answer (it waits for the inbox status only). Not reproduced through a public door (no backend booted), so not a filing. objectui#12602 Target 4 needs that status anyway. Dedupe words: approvals count status, summary zero claim, all caught up approvals failure.",
      "carrier: the domain:ui seat for objectui#12605 · noted, not filed — Home top bar right side (help, 28 px avatar) and the search trigger's 8 px radius / 13 px label left as the shared AppHeader draws them, because AppHeader edits are limited to the /home search entry while #12605 holds the file.",
      "carrier: none · noted, not filed — tiles keep the launcher's per-app deterministic gradient (the artboard draws gradients too) and do not read branding.primaryColor; packages/i18n/src/__tests__/makerEmptyState-v1-scope-8329.test.ts keeps a scope comment naming the now-removed home.build.subtitle (comment only)."
     ],
     "deviations": [
      "The merge commit f2ef2c1 carries no Claude-Session/Co-authored-by trailer pair (git merge -m default); not amended, since the brief forbids amend.",
      "Ablations ran at 9aa8059, not the final head; efe6e9d (locale keys, changeset) and 42e5761 (one blank line) touch none of the anchors or mocked t() outputs.",
      "Local tests narrowed from the full app-shell package to 171 files (the directories importing the changed modules plus tests naming them); declared, CI runs the rest.",
      "Declared file surface widened by one new file inside it: packages/app-shell/src/console/home/appLastOpened.ts (+ its test). No file outside the claim's surface was edited.",
      "Lock queue: ~55 min waiting behind a full app-shell package run held by objectui-issue-12616 (pid 15496, ~49 min) and two other waiters; acquired on the sixth call."
     ],
     "files_changed": "20 vs origin/main 63d00da: .changeset/12601-home-top-and-apps.md; packages/app-shell/src/console/home/{HomeAppsStrip.tsx, HomeLayout.tsx, HomePage.tsx, appLastOpened.ts (new)}; packages/app-shell/src/console/home/__tests__/{HomeLayout.searchOpensPalette-12601.test.tsx (new), HomePage.authoringCapabilityGate.test.tsx, HomePage.greetingAndApps-12601.test.tsx (new), appLastOpened-12601.test.ts (new)}; packages/app-shell/src/layout/AppHeader.tsx; packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts. +1292 / -228 (git diff --stat)."
    }
  5. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    REWORK round 1 → PR #12638 · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T08:19Z

    Reviewed at head 42e5761957. Accepted as reviewed: the inherited hunks, the last-opened line (9aa8059), the key removal, H1 (no widening of the entry's declaration closure), H2 (approvals only; no source on main for "assigned to me"), H3–H5 and the five ablations. Patch round on the same claim (6209656150), same dev, same branch:

    1. CI red: job Type Check fails at pnpm check:spec-symbols: type AppLike in packages/app-shell/src/console/home/appLastOpened.ts:30 is a local declaration under a name @objectstack/spec/system owns.
    2. The summary's zero claim is a defect this PR introduces, so it is fixed here and not carried to objectui#12602: while the approvals read is loading, failed or unavailable, the line must not say "今天没有待办". The shared feed's snapshot already carries status (packages/app-shell/src/hooks/sharedUserFeeds.ts, SharedFeedSnapshot).
      • File surface widened for this item only: packages/app-shell/src/hooks/sharedUserFeeds.ts (an internal, non-exported read of the status; the exported surface of @object-ui/app-shell stays unchanged).

    Moved out of this card: Target 1's 48 px bar height is now objectui#12639. The height is shared by five bars on main, and both approved artboards draw 48 px. This card keeps everything else and still closes through PR #12638.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 12601,
     "round": 2,
     "status": "done",
     "branch": "claude/issue-12601-home-top-and-apps",
     "pr": "https://github.com/objectstack-ai/objectui/pull/12638",
     "session": "session_011K9g23W67dy2zwnyzaoB6o",
     "premise_still_valid": true,
     "summary": "Patch round 1, both items landed, head fc73410. Item 1: `pnpm check:spec-symbols` reproduced red at 42e5761 (type `AppLike` in console/home/appLastOpened.ts, exported by @objectstack/spec/system); lastOpenedByApp now takes `Parameters<typeof matchAppBySegment>[0]` (the resolver's own app-list type) and `ReadonlyArray<Pick<RecentItem, 'href' | 'visitedAt'>>`, no local shape; gate green. Item 2: the summary line speaks only when the approvals count is an answer. sharedUserFeeds.ts gains `useSharedPendingApprovals()` returning the store's SharedFeedSnapshot (not exported from the entry; `useSharedPendingApprovalsCount` now reads `.value` off it, return type unchanged, `useInboxBell` unchanged). On anything but `ready` the line keeps its height (`min-h-5`) and is EMPTY: no claim, no layout jump when the answer lands, nothing read to a screen reader. ROOT CAUSE of the CI red at 042577e (seven home test files, 'Found multiple elements'): 042577e had HomePage call the snapshot hook directly beside `useHomeInbox`; every HomePage harness mocks `useHomeInbox` and routes `fetch`, so the new direct read sent a real `/api/v1/approvals/requests` request, each file's afterEach no-escape assertion (`expected [ Array(1) ] to deeply equal []`) failed before its `cleanup()` ran, and the next case found the previous DOM still mounted. Not a double render, and not the seat's mock-factory hypothesis (those files do not mock sharedUserFeeds at all). Fix fc73410: the status travels the page's one inbox seam, `useHomeInbox` (new `pendingApprovalsStatus`, as it already returns `notificationsStatus`); HomePage reads only `useHomeInbox`; no harness weakened. The 'Nothing is waiting' text in the CI DOM dumps was those harnesses' 404 stub: the store reads a 404 (no approvals plugin) as `markUnavailable`, a ruled `ready` answer of 0. The 'Invalid time value' in the shard logs is a test TITLE in plugin-timeline (timeline-object-bound-gantt-refusal, passing), not a thrown error; the last-opened render path skips an unreadable visitedAt (pinned on HomePage now too). CI at fc73410: all 33 completed check-runs success, 3 skipped.",
     "tests": "At fc73410 through os-verify-lock: `pnpm exec vitest run packages/app-shell/src/console/home/ packages/app-shell/src/hooks/ packages/app-shell/src/layout/ --maxWorkers=2` -> Test Files 168 passed (168), Tests 1272 passed (1272); population control: `git ls-files` counts 168 test files in those three directories (whole directories, no selection; the seven files red in CI are in console/home/). New pins: HomePage.greetingAndApps-12601 'claims nothing while the approvals read is {in flight | failed | not asked | failed after an earlier answer}' (summary element empty, no home.summary key rendered); hooks/__tests__/useHomeInbox.approvalsStatus-12601.test.tsx (real store, stubbed fetch: loading while in flight, ready+2 on 200, error on 500, ready+0 on 404). Ablations via objectstack scripts/ablation-replace.mjs WRAP mode, restored blob == HEAD and git diff HEAD empty each: S1 HomePage `pendingApprovalsStatus !== 'ready'` -> `false` => 4 failed / 14 passed (the four no-claim cases); S2 useHomeInbox drops `pendingApprovalsStatus,` from its return => 4 failed (4). S2's FIRST attempt was a no-op: the replacement text already occurred once, so the tool saw the replacement count stay x1 -> x1, ran nothing and restored; rerun with a unique replacement, result above. item 1 reproduce: `pnpm check:spec-symbols` EXIT=1 at 42e5761 ('a spec-named symbol is hand-written, not derived: type AppLike'), EXIT=0 at 042577e and fc73410.",
     "gates": "Local at fc73410, exit captured before any pipe. Type Check job steps after check:spec-symbols (ci.yml order): check:spec-symbols 0, check:action-forward-parity 0, check:designer-field-key-parity 0, check:icon-record-names 0, check:i18n-keys 0, check:i18n-drift 0, check:i18n-designer-parity 0, type-check:scripts 0, type-check:vitest-config 0, scope selector `select-type-check-scope.mjs --base 63d00da` -> scope=affected (35 packages), `turbo run type-check --filter='...[63d00da]' --concurrency=2` 0 (Tasks: 70 successful, 70 total; 28 cached), root builds (components, fields, i18n, plugin-dashboard, plugin-grid) 0, type-check:vitest-setup 0. Steps before it re-run because app-shell changed again: check-type-check-coverage 0, check:phantom-deps 0, check:self-import 0, check:unreferenced-sources 0, check:doc-example-readers 0, check:handler-key-reads 0, check:metadata-write-doors 0, check:published-tsconfig-exclude 0, check:side-effects-array 0, check:element-data-source-declaration 0, check:esm-specifiers 0. Also: `pnpm --filter @object-ui/app-shell type-check` 0, check:i18n-dead-keys 0, vi-mock inherit/override-shape/specifiers 0/0/0, check:test-path-roots 0, check-new-cross-file-line-citations 0, check-control-bytes 0, check:changeset-claims 0, check-changeset-presence 0, changeset:check 0, eslint over the 23 changed .ts/.tsx 0 (0 errors, 34 warnings: the one more than round 1 is a pre-existing `any` in HomeActionCenter.unansweredInbox.test.tsx, newly linted because it is now in the diff). No locale file changed in round 2. CI at fc73410 (PR #12638 check-runs): 33 success (Build & E2E, Build Docs, Bundle Analysis, Changeset Bump Policy, Changeset Claim Re-read, Changeset Declaration, Changeset Fixed Group Check, Changeset Overwrite Report, Governed Surface Queue Guard, Line Citation Gate, Lint, Live E2E (informational), Repo Gates, Test, Test (dist pins), Test (shard 1..16/16), Type Check, label), 3 skipped (coverage x2, dependabot).",
     "mcp_calls": "2 — mcp__github__get_job_logs x2 (read-only: shard 5/16 and 14/16 job logs at 042577e, to root-cause; the REST log download is refused by the proxy's blob-storage policy). No MCP write.",
     "api_writes": "1 REST write this round: this report via post-stamped.mjs -> POST /repos/objectstack-ai/objectui/issues/12601/comments (fleet relay). git push x2 (042577e, fc73410), not REST. No PR body PATCH, no label write.",
     "open_questions": [
      {
       "question": "The patch note says the line must not claim 'nothing waiting' 'when the endpoint is unavailable'. A 404 (no approvals plugin) is, in the shared store's ruled vocabulary (#4235/#4300), `markUnavailable` = a `ready` answer of 0, so the line DOES say 'Nothing is waiting for you today' there; 5xx/403/network failures are `error` and the line is empty. Is that the reading the seat wants?",
       "options": [
        "A: keep it — a deployment without approvals has none waiting; the store's ruled 'missing resource is an answer' reading holds (no further change)",
        "B: no claim on a 404 either — needs the store to expose `unavailable` beside `status` (a new store field), which the store's #4235 doctrine argues against"
       ],
       "recommendation": "A, because the line only names approvals and a deployment with no approvals plugin genuinely has none waiting; B adds a second dialect to the one status vocabulary the store was ruled to speak."
      }
     ],
     "out_of_scope_findings": [],
     "deviations": [
      "File surface widened beyond the seat's grant: `packages/app-shell/src/hooks/useHomeInbox.ts` (additive `pendingApprovalsStatus` on the non-exported HomeInboxData; it now reads the snapshot hook) and its new test `hooks/__tests__/useHomeInbox.approvalsStatus-12601.test.tsx`; plus a one-mock change in `console/home/__tests__/HomeActionCenter.unansweredInbox.test.tsx` (its approvals dial moves from the count hook to the snapshot hook that useHomeInbox now reads). Reason: the root-cause fix for the CI red is one inbox seam for the page; the in-grant alternative (HomePage reading the snapshot hook directly) would have needed a second mock added to seven HomePage harnesses and every future one.",
      "The worktree was removed after round 1 and recreated for this round from the local branch at 42e5761 == origin; deps rebuilt (`turbo run build --filter='@object-ui/app-shell^...'`). No main merge (no conflict, no main-caused red).",
      "Ablation S2's first attempt was a refused no-op (replacement text not unique); rerun recorded in tests."
     ],
     "files_changed": "Round 2 (42e5761..fc73410, 2 commits): .changeset/12601-home-top-and-apps.md (ready-only line stated); packages/app-shell/src/console/home/{HomePage.tsx, appLastOpened.ts}; packages/app-shell/src/console/home/__tests__/{HomePage.greetingAndApps-12601.test.tsx, HomeActionCenter.unansweredInbox.test.tsx}; packages/app-shell/src/hooks/{sharedUserFeeds.ts, useHomeInbox.ts}; packages/app-shell/src/hooks/__tests__/useHomeInbox.approvalsStatus-12601.test.tsx (new). PR total vs 63d00da: 24 files."
    }
  7. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    REWORK round 2 → PR #12638 · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T09:03Z

    Reviewed round 2 at head fc73410a8a.

    Accepted:

    • Round 1's two items: check:spec-symbols green, and the summary line now speaks only on ready.
    • The root cause of the seven red home files: a direct approvals read escaped the harnesses' fetch guard, so cleanup() never ran. The fix routes the status through useHomeInbox.
    • CI at fc73410: 33 success, 3 skipped.
    • The dev's open question is ruled A: a 404 is the store's ruled ready answer of 0, so "Nothing is waiting for you today" stands there.
    • File surface widened: packages/app-shell/src/hooks/useHomeInbox.ts (additive pendingApprovalsStatus on the non-exported HomeInboxData), its new test, and one mock in console/home/__tests__/HomeActionCenter.unansweredInbox.test.tsx. This adds to the widening recorded at the round-1 REWORK (sharedUserFeeds.ts). Nothing is exported from @object-ui/app-shell's entry.

    Live Home reading (cloud reading session session_01CQVvdrcshAD3iT7azpF5NT; BEFORE main 8ed7e5a8fb, AFTER fc73410; PNGs at claude/issue-12616-evidence a261e30, evidence/12601/):

    AFTER
    Search field Centred, 420 px, with ⌘K. Click, Ctrl+K and Meta+K each open one palette.
    Greeting 24 px / 600, with the name in --primary.
    Summary "You have 3 approvals waiting today", matching GET /api/v1/approvals/requests?status=pending (3). While loading, the line is empty and never says "Nothing is waiting".
    Content column 1120 px; no bordered card.
    Tiles 112 px with a 56 px icon; no Setup tile.
    Mobile (390 px) Fits.

    Not measured live: the admin-gated chips, the Browse marketplace / System Settings links and the Add app tile. On this published-package stack the seeded admin's session reads role=user, isPlatformAdmin=false and member role member, so no account sees them. Their unit pins and ablations stand as the evidence.

    Patch round 2 (the last before escalation):

    1. The tile's 11 px last-opened line truncates in the 112 px tile: en reads "Opened 6 secon…". Make it fit for seconds, minutes, hours and days in every pack, without an ellipsis cut and without widening the tile.
    2. The changeset's Greeting bullet says the count comes "from the approvals count the bell badges". Live, the bell reads 4 (all inbox items) while the approvals number 3. Reword it to say what is read.

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 12601,
     "round": 3,
     "status": "done",
     "branch": "claude/issue-12601-home-top-and-apps",
     "pr": "https://github.com/objectstack-ai/objectui/pull/12638",
     "session": "session_011K9g23W67dy2zwnyzaoB6o",
     "premise_still_valid": true,
     "summary": "Patch round 2, both items landed, head 70bfa2f (commits 6c037e4, 3b80fed, 70bfa2f). Item 1, the tile line: it is now drawn in Intl's compact form, `TILE_OPENED_TIME_FORMAT = { style: 'short', numeric: 'always' }` (en '6 sec. ago', '3 hr. ago', '2 days ago'; zh '6秒前打开', '3小时前打开', '2天前打开'), through each pack's `home.appOpened`, which keeps a verb only where verb and time fit: zh, ko, ar unchanged; ja changed to the time plus 'に起動'; en, de, fr, es, pt, ru are the time alone. Tile stays 112 px, font stays 11 px, no ellipsis. Measured (Chromium, 11 px, this container): the old 'Opened 6 seconds ago' is 118.6 px in Inter against 96 px of text room; every pack's new line, 6 s to 12 y, measures at most 87.0 px (Inter) / 88.2 px (DejaVu Sans, the widest fallback), worst 'فُتح قبل سنة واحدة'. Mechanism: `formatRelativeTime` (@object-ui/i18n) and `timeAgo` (app-shell) take an optional `{ style, numeric }` passed to `Intl.RelativeTimeFormat` unchanged (default output unchanged), so one helper keeps the unit thresholds. Four axes: real need — measured truncation, live and here; long-term — Intl's own options through the one formatter, no second hand-rolled unit table, and the per-pack verb is an ordinary translation decision; AI-error-proofing — every pack's line is held to a derived budget, so a pack that re-adds a verb that does not fit goes red (ablation T2); startup scope — one optional argument, no new key, no tooltip. Why not `narrow`: fr and ru narrow read '-6 s' / '-59 мин'. Why `numeric: 'always'`: the auto phrases ('le mois dernier', 'l’année dernière', Arabic 'last year') are the longest any pack produces; the cost is zh '1天前打开' where the artboard illustrates '昨天打开' (same information). Item 2, the changeset's Greeting bullet now says the count comes from the shared pending-approvals read, the same read the bell uses for the approvals part of its badge, and that the badge adds the unread notification topics, so the two numbers can differ; the Apps bullet and the i18n surface sentence (formatRelativeTime's new optional argument) were corrected in the same pass, each sentence checked against the code.",
     "tests": "At 70bfa2f through os-verify-lock: `pnpm exec vitest run packages/app-shell/src/console/home/ packages/app-shell/src/hooks/ packages/app-shell/src/layout/ packages/i18n/ --maxWorkers=2` -> Test Files 252 passed (252), Tests 2596 passed | 13 skipped (2609); population control: `git ls-files` counts 252 test files in those four directories (whole directories). New pin `console/home/__tests__/appTileOpenedLine-12601.test.ts`: (1) every one of the ten packs' lines for 14 points (6 s, 45 s, 5 min, 59 min, 3 h, 23 h, 1 d, 2 d, 6 d, 29 d, 1 mo, 11 mo, 1 y, 12 y) within a 93 px budget; (2) en and zh exact at 6 s, 5 min, 3 h, 2 d; (3) CONTROL: the old 'Opened 6 seconds ago' is over budget. Budget derivation (stated in the test): `w-28` 112 px minus `px-2` 2 x 8 px = 96 px of text at 11 px; width estimated per character in em (Han/kana/Hangul/full-width 1.0, space 0.32, Arabic letter 0.53, combining mark 0, any other 0.62), calibrated against Chromium measurements in Inter and DejaVu Sans; over the final 140 lines the estimate fell short of a measured width by at most 2.4 px, so 3 px are reserved: 96 - 3 = 93 px; the estimate's largest final line is 92.2 px. Ablations via objectstack scripts/ablation-replace.mjs WRAP mode at 6c037e4, each restored to blob == HEAD with git diff HEAD empty: T1 `TILE_OPENED_TIME_FORMAT` style 'short' -> 'long' => budget and en/zh cases fail (2 failed / 1 passed; de, fr, es, ru lines over budget, e.g. fr 'il y a 45 secondes' about 109.6 px); T2 en `home.appOpened` back to 'Opened ' plus the time hole => both fail (en 'Opened 45 sec. ago' about 112.9 px). The later commits (3b80fed escape spelling of the same regex, 70bfa2f an allowlist entry) touch neither anchor. The greeting test's tile case now expects '2 hr. ago'.",
     "gates": "Local at 70bfa2f (exit captured before any pipe): `pnpm exec turbo run build --filter='@object-ui/app-shell^...'` 0 (at 6c037e4, rebuilding i18n with the new argument); `pnpm --filter @object-ui/app-shell type-check` 0; `pnpm --filter @object-ui/i18n type-check` 0; check:i18n-keys 0, check:i18n-drift 0 ('0 en value(s) changed (7 key(s) added, 3 removed)' against merge-base 63d00da; the en value change is inside a key this branch adds), check:i18n-dead-keys 0, check:i18n-designer-parity 0, check:changeset-claims 0, check:spec-symbols 0, check-changeset-presence 0, changeset:check 0, vi-mock inherit/override-shape/specifiers 0/0/0, check:test-path-roots 0, check:unreferenced-sources 0, check:esm-specifiers 0, check-new-cross-file-line-citations 0, check-control-bytes 0; eslint over the 27 changed .ts/.tsx: exit 0, 0 errors, 34 warnings (existing kinds). eslint first read 1 error at 6c037e4 (`no-irregular-whitespace`: the pin's CJK ranges had been written as raw characters, U+3000 among them); fixed in 3b80fed. CI at 70bfa2f at report time: 16 completed success, 3 skipped, 16 in_progress (reported as is; not waited on). At 6c037e4 the aggregate 'Test' failed: `untranslated-identity-4376` flagged ru's bare time hole, fixed in 70bfa2f.",
     "mcp_calls": "0 this round.",
     "api_writes": "1 REST write this round: this report via post-stamped.mjs -> POST /repos/objectstack-ai/objectui/issues/12601/comments (fleet relay). git push x3 (6c037e4, 3b80fed, 70bfa2f), not REST. No PR body PATCH, no label write.",
     "pr_body_changes_for_the_seat": [
      "Opening paragraph and 'What the tile's time reads': the line is the locale's compact relative time ('2 hr. ago', zh '2小时前打开'), `TILE_OPENED_TIME_FORMAT` = short/always, verb only where it fits; replace 'Opened 2 hours ago'.",
      "H1: the @object-ui/i18n half now also has `formatRelativeTime`'s optional third argument `{ style, numeric }` (default output unchanged).",
      "H2 / Acceptance notes: the 'summary's zero claim' note is obsolete — fixed in round 2 (line empty unless the approvals read is `ready`; a 404 is the store's ready 0, ruled A).",
      "Verification table: the readings above at 70bfa2f replace the 42e5761 ones; the ablation table gains S1/S2 (round 2) and T1/T2 (round 3)."
     ],
     "open_questions": [],
     "out_of_scope_findings": [],
     "deviations": [
      "File surface widened again, additively: `packages/i18n/src/utils/formatting.ts` (optional `options` on formatRelativeTime), `packages/app-shell/src/utils/relativeTime.ts` (timeAgo passes it), and `packages/i18n/src/__tests__/untranslated-identity-4376.test.ts` (one LEGITIMATE_IDENTITIES entry for `home.appOpened`, the remedy that test names for a pure format string, as `grid.summary.pattern`). Reason: one relative-time formatter instead of a second unit table in console/home.",
      "zh reads '1天前打开' for a day ago where the artboard illustrates '昨天打开' (numeric 'always'; see summary).",
      "en, de, fr, es, pt, ru tile lines carry the time without a verb: measured, no verb-plus-time form fits those packs in 96 px.",
      "Rounds 1 and 2 reported eslint 'EXIT=0' from an `echo` whose own command substitution ran before `$?` was read, so those exit codes were not eslint's; their logs printed '0 errors', so the verdict stands. This round's eslint exit is captured into a variable first.",
      "The worktree was recreated for this round from the branch at fc73410 == origin and will be removed after this report."
     ],
     "files_changed": "Round 3 (fc73410..70bfa2f, 3 commits): .changeset/12601-home-top-and-apps.md; packages/app-shell/src/console/home/{HomeAppsStrip.tsx, appLastOpened.ts}; packages/app-shell/src/console/home/__tests__/{HomePage.greetingAndApps-12601.test.tsx, appTileOpenedLine-12601.test.ts (new)}; packages/app-shell/src/utils/relativeTime.ts; packages/i18n/src/utils/formatting.ts; packages/i18n/src/locales/{en,de,fr,es,pt,ru,ja}.ts; packages/i18n/src/__tests__/untranslated-identity-4376.test.ts."
    }
  9. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12638 comment 6212643098 · contract review 6212627233 (TIER_DEFAULT PASS) · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T09:39Z


    Generated by Claude Code

  10. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T09:53Z


    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:recordsBusiness objects, records, the views that show data, usable forms, searchdomain: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