You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
record page: the Related tab gives an empty related list ("客户 0 暂无相关记录") a full row, and record:path squeezes two terminal stages ("× 已取消 客户未到") into one cell at the right edge #25895
Filing gate ① a user-visible defect with a named landing site; two record-page polish items from one pass, split if triage prefers. Batch-of: 2026-10-25 browser pass on @objectstack/* 18.1.0 (23 cards: hotcrm 10, objectui 10, objectstack 3). Filed by the maintainer's account (os-steve) from the HotCRM pass driven in session session_01AwpXhq2nFKU6J7GmbCEmZu; ⛔ not a claim. Grade and routing are objectui triage's.
What is seen (HotCRM on @objectstack/console 18.1.0, 1440×900)
Related tab, account Acme Corporation. Between 报价单 (2) and 活动 (7) sits a full-height row 「客户 0 · 暂无相关记录 · + 新建」 (child accounts), and after 活动 another 「线索 0 · 暂无相关记录 · + 新建」. With 26 related records in nine lists, two of the rows a reader scrolls past are empty. 50-account-related.png. Expected: empty lists fold to a one-line footer (「其他 2 个为空:客户、线索」) or sort last, keeping their 新建 action.
record:path on an event. The stage bar has three stages 已计划 / 已举行 / 已取消 plus the terminal 客户未到; the last segment reads × 已取消 客户未到 in one narrow cell at the right edge while the first two stages take the width. 60-event-tall.png. The opportunity bar does the same with 成交 / × 失败, less visibly because it has seven stages. Expected: terminal states share the width equally or wrap, so each label is legible.
reach: the public UI, measured once as the dev admin.
Transferred 2026-10-26T02:59Z from objectstack-ai/objectui#13519, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the ui/ workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.
Paths. The body names no file paths; the UI code it describes lives under ui/ here (the Console is ui/apps/console, the libraries ui/packages/*).
Claim: PM loop round 8 · 2026-10-27T00:54Z
Session: session_01SMps7wq7rBTk53e8KTSEup
Account: os-steve
Branch: claude/issue-25895-related-empty-path-terminal
Worktree: objectstack-issue-25895
Domain: domain:ui
Seat: domain:ui#2
File surface: ui/packages/plugin-detail/src/renderers/record-related-list.tsx and the Related-tab composition that stacks the lists (plugin-detail/src/synth/buildDefaultPageSchema.ts and/or app-shell/src/views/RecordDetailView.tsx, whichever owns the stack), ui/packages/plugin-detail/src/renderers/record-path.tsx, plugin-detail/src/useDetailTranslation.ts (fallback strings), tests beside them, scripts/sdui-manifest.sources/plugin-detail.json, root .changeset/. ⛔ DetailSection.tsx / HeaderHighlight.tsx (#25883, PR #26325), locale packs under ui/packages/i18n (on the i18n line behind #26326), ui/.github/**, root ci.yml.
Container & model: M, mode:subagent, model: default tier, effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: a reader scrolling a record's Related tab, and a reader of a record's stage bar | RecordRelatedListComponent and RecordPathComponent rendering (no spec key) | every record page with related lists or a path
Thread-read: none
Premise: holds 2026-10-27T00:54Z at origin/mainf02e644343, read from the card's two HotCRM shots: an empty related list takes a full row, and the path's terminal states share one narrow cell.
Serial constraints cleared: seat 1's #26182 (PR #26277, record-related-list.tsx) MERGED 2026-10-27T00:52Z. No open PR touches these files. plugin-detail record: lands after #26325 (#25883).
Writes: PR only via the relay op pr_create; comments only via the relay write tools; ⛔ no GitHub MCP writes.
Seat's route:
Item 1: on the Related tab, lists with zero records fold into one line after the non-empty lists, naming them and keeping each one's New action (the card's first expected shape). A list that loads later with rows unfolds. A page with only empty lists shows them as today.
Item 2: on the path bar, terminal states get legible width (share equally with the stages or wrap); each terminal label is readable at 1440 and at narrow widths.
New strings use useDetailTranslation's fallback defaults; locale-pack keys go to a follow-up after the i18n line drains. Say so in the PR.
{
"issue": 25895,
"status": "done",
"branch": "claude/issue-25895-related-empty-path-terminal",
"pr": "https://github.com/objectstack-ai/objectstack/pull/26414",
"head": "8271adf9d12b65cd5b740679c5187f6c27787866",
"session": "session_01SMps7wq7rBTk53e8KTSEup",
"premise_still_valid": true,
"summary": "Item 1: record:related_list blocks that share a DOM container (the Related tab's page:tabs panel, or any authored container) coordinate through a small store in the new ui/packages/plugin-detail/src/RelatedListEmptyFold.tsx; once every list has answered and at least one has records, empty lists that offer only New are hidden in place (kept mounted) and the stack's last list draws one line naming them, each with its own New. RelatedList gains an optional onEmptyChange callback; the block keeps the last answer across a refetch. All-empty stacks, single lists and lists with add/toolbar actions/notices are unchanged; a folded list that gains a record unfolds. Item 2: record-path desktop rail groups grow by stage count from a zero basis and every stage is flex-1, so terminal stages get an equal share; terminal labels (won terminus and the alt group) wrap instead of truncating/nowrap. Seam chosen: the block itself, because the synthesizer (buildDefaultTabs) only emits children, page:tabs (components) draws them as plain siblings, and RecordDetailView only passes related; none knows row counts. No new i18n key: reuses detail.noRelatedRecords and detail.new; a dedicated count phrase is a follow-up for the locale packs.",
"tests": "Red-first: tests committed aba3b5ca; red leg with the 3 impl files restored to base f02e6443 (markers counted 0): 9 failed / 3 passed (the 3 passing are CONTROL legs: all-empty stack, single list, ordinary forward stage); restore proven by blob hashes equal to HEAD; green leg 12/12. plugin-detail full suite at 5cf6e03e: 306 passed, 1 failed (spec-symbol-batch7: props type in renderers/ not spelled ...RendererProps) -> module moved to src/ in 47121545. Post-merge at 8271adf9 under the lock (VERDICT command-exit 0): spec build exit 0; spec-symbol-batch7 + all record-path*, record-related-list*, recordComponentAria*, RelatedList* tests: 59/59 files, 396/396 tests; plugin-detail type-check exit 0. Consumer set at 5cf6e03e (34 files under app-shell, apps/console, components that render record:related_list or empty related lists, incl. RecordDetailView related files, not the full app-shell suite): 34/34 files, 293/293 tests. gen-sdui-manifest at 5cf6e03e: sdui.manifest.json byte-unchanged (sha256 1f6e1ccb925a); the sources record it wrote was discarded per the seat (records retired by #26367).",
"gates": "At head 8271adf9: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35 families; all 35 run, each exit 0 (incl. node scripts/check-sdui-manifest.mjs and its --self-test); --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED (derived zero, exit codes recorded). CI check-runs: in_progress / not yet read (draft just opened).",
"line_budget": "7 files, +680 / -11 (691 changed lines) vs origin/main merge base b33dd25b; source +93 net in 3 existing files, new module 251 lines, tests 335 lines, changeset 13",
"files_changed": [
".changeset/25895-related-empty-fold-path-terminal.md",
"ui/packages/plugin-detail/src/RelatedList.tsx",
"ui/packages/plugin-detail/src/RelatedListEmptyFold.tsx",
"ui/packages/plugin-detail/src/renderers/record-path.tsx",
"ui/packages/plugin-detail/src/renderers/record-related-list.tsx",
"ui/packages/plugin-detail/src/renderers/__tests__/record-path.terminalWidth-25895.test.tsx",
"ui/packages/plugin-detail/src/renderers/__tests__/record-related-list.emptyFold-25895.test.tsx"
],
"deviations": [
"File surface extended within plugin-detail: RelatedList.tsx (one optional prop onEmptyChange + one effect) and the new src/RelatedListEmptyFold.tsx; neither synth/buildDefaultPageSchema.ts nor app-shell is touched.",
"No useDetailTranslation fallback strings were added: ui/scripts/check-i18n-call-site-keys.mjs refuses any t() key absent from the en pack (empty ratchet baseline; an inline defaultValue is explicitly not a fix), so a new key without the locale packs would red CI. Existing keys reused instead; the dedicated phrase is a follow-up.",
"sdui sources re-record dropped per the seat's mid-run update (#26367 retired them); origin/main merged as merge commit 8271adf9."
],
"dogfood_battery": "n/a - no ! in the PR title and Clause-2 is no with no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 - relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST issues/26414/assignees, one dispatch fw-20261027T025959Z-c3cbf6), and this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/25895/comments via post-stamped). git push is not counted.",
"open_questions": [
{
"question": "Fold line copy: reuse 'No related records found' + titles, or add a count phrase (e.g. 'N more with no records: A, B')?",
"options": [
"A keep the reused keys (no pack change)",
"B add detail.relatedEmptyFold to all ten packs on the i18n line"
],
"recommendation": "A now, B as the follow-up once the i18n line drains, because check:i18n-keys forbids a key the packs lack."
}
],
"out_of_scope_findings": [
"class: none filed - RelatedList shows the empty state when its read FAILS (catch only logs), so a failed list also folds as empty; pre-existing read-path behaviour, noted in the PR Acceptance notes · carrier: none (承接者:无)"
]
}
Status: on the Related tab, empty lists that offer only New fold into one line after the lists with records, each keeping its New; the path bar gives terminal stages an equal share with wrapping labels. A failed related read still shows as empty and now folds too: #26415. pm:dispatched removed.
Activity
objectstack-fleet commentedon Oct 25, 2026
Triage: first grade —
bug·priority:p3·domain:ui·area:records·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-25T12:56Z⛔ Not a claim, ⛔ not a dispatch.
findingcomes off.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Transferred 2026-10-26T02:59Z from objectstack-ai/objectui#13519, with its comments and timeline; the old URL redirects here. objectui moved into this repository as the
ui/workspace (epic #25677) and is being archived (#25854). The body is left exactly as filed.Paths. The body names no file paths; the UI code it describes lives under
ui/here (the Console isui/apps/console, the librariesui/packages/*).References. The bare issue numbers in the body were written in objectui and now resolve against this repository by mistake; read them as objectstack-ai/objectui#5916, objectstack-ai/objectui#5957, objectstack-ai/objectui#11613, objectstack-ai/objectui#11768, objectstack-ai/objectui#12245, objectstack-ai/objectui#12870, objectstack-ai/objectui#12930, objectstack-ai/objectui#12965, objectstack-ai/objectui#13063.
No stale
pm:dispatchedor assignee to strip.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 8 · 2026-10-27T00:54Z
Session:
session_01SMps7wq7rBTk53e8KTSEupAccount:
os-steveBranch:
claude/issue-25895-related-empty-path-terminalWorktree:
objectstack-issue-25895Domain:
domain:uiSeat:
domain:ui#2File surface:
ui/packages/plugin-detail/src/renderers/record-related-list.tsxand the Related-tab composition that stacks the lists (plugin-detail/src/synth/buildDefaultPageSchema.tsand/orapp-shell/src/views/RecordDetailView.tsx, whichever owns the stack),ui/packages/plugin-detail/src/renderers/record-path.tsx,plugin-detail/src/useDetailTranslation.ts(fallback strings), tests beside them,scripts/sdui-manifest.sources/plugin-detail.json, root.changeset/. ⛔DetailSection.tsx/HeaderHighlight.tsx(#25883, PR #26325), locale packs underui/packages/i18n(on the i18n line behind #26326),ui/.github/**, rootci.yml.Container & model:
M,mode:subagent,model: default tier,effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
a reader scrolling a record's Related tab, and a reader of a record's stage bar|RecordRelatedListComponent and RecordPathComponent rendering (no spec key)|every record page with related lists or a pathThread-read: none
Premise: holds 2026-10-27T00:54Z at
origin/mainf02e644343, read from the card's two HotCRM shots: an empty related list takes a full row, and the path's terminal states share one narrow cell.Serial constraints cleared: seat 1's #26182 (PR #26277,
record-related-list.tsx) MERGED 2026-10-27T00:52Z. No open PR touches these files. plugin-detail record: lands after #26325 (#25883).Writes: PR only via the relay op
pr_create; comments only via the relay write tools; ⛔ no GitHub MCP writes.useDetailTranslation's fallback defaults; locale-pack keys go to a follow-up after the i18n line drains. Say so in the PR.Fixes #25895.objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 25895, "status": "done", "branch": "claude/issue-25895-related-empty-path-terminal", "pr": "https://github.com/objectstack-ai/objectstack/pull/26414", "head": "8271adf9d12b65cd5b740679c5187f6c27787866", "session": "session_01SMps7wq7rBTk53e8KTSEup", "premise_still_valid": true, "summary": "Item 1: record:related_list blocks that share a DOM container (the Related tab's page:tabs panel, or any authored container) coordinate through a small store in the new ui/packages/plugin-detail/src/RelatedListEmptyFold.tsx; once every list has answered and at least one has records, empty lists that offer only New are hidden in place (kept mounted) and the stack's last list draws one line naming them, each with its own New. RelatedList gains an optional onEmptyChange callback; the block keeps the last answer across a refetch. All-empty stacks, single lists and lists with add/toolbar actions/notices are unchanged; a folded list that gains a record unfolds. Item 2: record-path desktop rail groups grow by stage count from a zero basis and every stage is flex-1, so terminal stages get an equal share; terminal labels (won terminus and the alt group) wrap instead of truncating/nowrap. Seam chosen: the block itself, because the synthesizer (buildDefaultTabs) only emits children, page:tabs (components) draws them as plain siblings, and RecordDetailView only passes related; none knows row counts. No new i18n key: reuses detail.noRelatedRecords and detail.new; a dedicated count phrase is a follow-up for the locale packs.", "tests": "Red-first: tests committed aba3b5ca; red leg with the 3 impl files restored to base f02e6443 (markers counted 0): 9 failed / 3 passed (the 3 passing are CONTROL legs: all-empty stack, single list, ordinary forward stage); restore proven by blob hashes equal to HEAD; green leg 12/12. plugin-detail full suite at 5cf6e03e: 306 passed, 1 failed (spec-symbol-batch7: props type in renderers/ not spelled ...RendererProps) -> module moved to src/ in 47121545. Post-merge at 8271adf9 under the lock (VERDICT command-exit 0): spec build exit 0; spec-symbol-batch7 + all record-path*, record-related-list*, recordComponentAria*, RelatedList* tests: 59/59 files, 396/396 tests; plugin-detail type-check exit 0. Consumer set at 5cf6e03e (34 files under app-shell, apps/console, components that render record:related_list or empty related lists, incl. RecordDetailView related files, not the full app-shell suite): 34/34 files, 293/293 tests. gen-sdui-manifest at 5cf6e03e: sdui.manifest.json byte-unchanged (sha256 1f6e1ccb925a); the sources record it wrote was discarded per the seat (records retired by #26367).", "gates": "At head 8271adf9: dispatch-gates --commands --repo objectstack-ai/objectstack derived 35 families; all 35 run, each exit 0 (incl. node scripts/check-sdui-manifest.mjs and its --self-test); --ran reconciliation: 35 derived, 35 run, 0 NOT-MEASURED (derived zero, exit codes recorded). CI check-runs: in_progress / not yet read (draft just opened).", "line_budget": "7 files, +680 / -11 (691 changed lines) vs origin/main merge base b33dd25b; source +93 net in 3 existing files, new module 251 lines, tests 335 lines, changeset 13", "files_changed": [ ".changeset/25895-related-empty-fold-path-terminal.md", "ui/packages/plugin-detail/src/RelatedList.tsx", "ui/packages/plugin-detail/src/RelatedListEmptyFold.tsx", "ui/packages/plugin-detail/src/renderers/record-path.tsx", "ui/packages/plugin-detail/src/renderers/record-related-list.tsx", "ui/packages/plugin-detail/src/renderers/__tests__/record-path.terminalWidth-25895.test.tsx", "ui/packages/plugin-detail/src/renderers/__tests__/record-related-list.emptyFold-25895.test.tsx" ], "deviations": [ "File surface extended within plugin-detail: RelatedList.tsx (one optional prop onEmptyChange + one effect) and the new src/RelatedListEmptyFold.tsx; neither synth/buildDefaultPageSchema.ts nor app-shell is touched.", "No useDetailTranslation fallback strings were added: ui/scripts/check-i18n-call-site-keys.mjs refuses any t() key absent from the en pack (empty ratchet baseline; an inline defaultValue is explicitly not a fix), so a new key without the locale packs would red CI. Existing keys reused instead; the dedicated phrase is a follow-up.", "sdui sources re-record dropped per the seat's mid-run update (#26367 retired them); origin/main merged as merge commit 8271adf9." ], "dogfood_battery": "n/a - no ! in the PR title and Clause-2 is no with no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 - relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST issues/26414/assignees, one dispatch fw-20261027T025959Z-c3cbf6), and this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/25895/comments via post-stamped). git push is not counted.", "open_questions": [ { "question": "Fold line copy: reuse 'No related records found' + titles, or add a count phrase (e.g. 'N more with no records: A, B')?", "options": [ "A keep the reused keys (no pack change)", "B add detail.relatedEmptyFold to all ten packs on the i18n line" ], "recommendation": "A now, B as the follow-up once the i18n line drains, because check:i18n-keys forbids a key the packs lack." } ], "out_of_scope_findings": [ "class: none filed - RelatedList shows the empty state when its read FAILS (catch only logs), so a failed list also folds as empty; pre-existing read-path behaviour, noted in the PR Acceptance notes · carrier: none (承接者:无)" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Landed · seat 2 · 2026-10-27T05:02Z
775a0006, head3fb46e57(+680/−11, seat record on #26414)origin/maingit merge-base --is-ancestorexit 0)gh-readonly-queue/main/pr-26414-*: none left (consumed)Fixes #25895on #26414Status: on the Related tab, empty lists that offer only New fold into one line after the lists with records, each keeping its New; the path bar gives terminal stages an equal share with wrapping labels. A failed related read still shows as empty and now folds too: #26415.
pm:dispatchedremoved.