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
date / datetime list filters still draw the native input: the platform picker must be reachable from FilterBuilder and plugin-view FilterUI without a cycle (half 2 of objectui#12664) #12743
Filing gate ①: a self-split from objectui#12664, which triage scoped into two halves (6216283515: "If the two halves land better in two PRs, the claimant files the second as its own card"). Filed by the domain:ui seat 2 (session_01XVp19E1MYUTFM3dnkwz8gB) when claiming objectui#12664 for half 1, the grid cell seam. ⛔ Not a claim.
What this card covers (half 2 of objectui#12664)
List filters on a date / datetime field still draw the native input, so the placeholder and digit order come from the machine's locale, not the console's. That is the defect class of objectui#12622.
Measured on objectui#12642 (dev report 6215467335):
FilterBuilder lives in @object-ui/components, which cannot import @object-ui/fields.
plugin-view's FilterUI has no @object-ui/fields dependency.
DatePickerField is not exported from the fields barrel.
The fork (triage's scope, verbatim intent)
The claim picks where the platform picker lives so that @object-ui/components and plugin-view can reach it without a cycle:
an export from @object-ui/fields, or
the face moved down a layer.
A new export is a public-surface change, so the claim declares it (Clause-②).
Done when
Every list filter row on a date / datetime field draws the platform picker, with its placeholder and digit order taken from the console locale.
Pins: a date filter row renders the picker; CONTROL: a non-date filter row is unchanged.
domain:ui · p2 (the parent's grade) · area:records.
Dedupe: this is half 2 of objectui#12664 by triage's split. The parent family is objectui#12642 / #12622.
Claim: PM loop round 3 (priority:p2; half 2 of objectui#12664, which triage split (6216283515); half 1 landed as d66d7e8, PR #12756)
Session: session_01XVp19E1MYUTFM3dnkwz8gB
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-12743-filter-date-picker
Worktree: objectui-issue-12743
Domain: domain:ui
Seat: domain:ui#2
File surface: the date / datetime value editors of the list filter rows, namely packages/components/src/custom/filter-builder.tsx and packages/components/src/renderers/complex/filter-builder.tsx, plus packages/plugin-view/src/FilterUI.tsx (measured at start: which of these the console's list filters actually render); packages/fields/src/ only for the export or seam that lets them reach the platform picker (the picker itself is packages/fields/src/widgets/date-picker/); packages/plugin-view/package.json only if a declared dependency is the chosen route; apps/console/vite.config.ts / scripts/check-eager-closure-budget.mjs carve-out rows only if the lazy chunk's membership needs a row; tests beside each; one .changeset/12743-*.md (stop on breach; explain in the report).
Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate for these paths)
Clause-②: yes (provisional: triage names a new @object-ui/fields export, or moving the face down a layer, as a public-surface change; the dev reports the measured shape, and a contract-tier review is owed before the queue)
Responsibility: objectui: list filter rows on date / datetime fields draw the native input, so the placeholder and digit order follow the machine's locale | the platform picker that forms, dialogs, grid cells and the kanban dialog already draw (objectui#12622 / #12642 / #12664) | every list filter on a date / datetime field
Thread-read: none
Serial constraints cleared: scanned every open objectui PR's file list just now. None touches the filter builders, FilterUI.tsx, packages/fields/src/index* or date-picker/. This seat's in-flight objectui#12698 (PR #12765) touches packages/auth and two header components, so it is disjoint.
Claimed at: 2026-10-16T19:18Z
{
"issue": 12743,
"status": "done",
"branch": "claude/issue-12743-filter-date-picker",
"pr": "https://github.com/objectstack-ai/objectui/pull/12782",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB (subagent: the parent seat's id)",
"premise_still_valid": true,
"dispatch_md5": "98ae9e9ad9384a9e8be22a05755c519c (prompt12743.txt, read in full before the first edit)",
"summary": "Date and datetime filter rows now draw the platform picker. In FilterBuilder (@object-ui/components; the console's ListView toolbar Filter panel renders it) this covers scalar rows and both between bounds. In plugin-view FilterUI it covers the date filter and both date-range bounds. Both resolve the field:date / field:datetime widget that @object-ui/fields already registers in ComponentRegistry, at render time, as the form renderer in components resolves field:TYPE. There is no new export, prop or dependency, components stays fields-free, and the picker stays in the lazy fields-date-picker chunk. The value shape is kept: YYYY-MM-DD for date; for datetime the picker's ISO instant is read back with core's toDateTimeInputValue onto the zoneless local YYYY-MM-DDTHH:mm that datetime-local wrote. A capture pointerdown listener blurs the editor before an outside press, so the commit-on-blur picker applies typed text. Escape discards. A1 as worded was false: neither builder resolved editors through a registry. The ruling's preferred registry seam already existed, though, so Clause-2 is corrected to no. The PR body's second line says so.",
"tests": "At HEAD 3fc88bff0 or an earlier branch commit whose files later commits did not change, each run under os-verify-lock with --maxWorkers=1 and VERDICT command-exit 0 unless noted. New pins: ListView.filterDatePicker-12743 7 passed (real ListView toolbar → FilterBuilder with registerAllFields; (a) picker face, en MM/DD/YYYY, zh YYYY/MM/DD 2026/10/01, no input[type=date]; (b) typed 10/20/2026 → 2026-10-20 on Enter, blur, and outside pointerdown+click which closes the panel; (c) datetime shows '10/01/2026, 09:15 AM' and writes 2026-10-20T14:30; (d) CONTROL text/number rows unchanged). filter-builder-date-value-seam-12743 10 passed (stand-in commit-on-blur widget; inside press does not blur; Escape discards; between bounds; CONTROL no registration keeps the native input). FilterUI.datePicker-12743 3 passed. (e) CONTROL: console vite build plus pnpm check:eager-closure exit 0, printing 'packages/fields 88 modules in ui-components and its src/widgets/date-picker subtree 2 in fields-date-picker, exactly'; eager-closure.json does not name fields-date-picker. Wider runs: all 20 components filter-builder* files plus schema-catalog filter-builder-mirror-6939: 417 passed. Components FilterBuilder/config-field-renderer consumers: 4 files / 26 passed. plugin-list Filter-panel/initialFilters tests: 13 files / 95 passed. packages/plugin-view/ whole dir: 79 files / 723 passed. Ablations through objectstack scripts/ablation-replace.mjs, each anchor x1 → x0 and each restored with blob == HEAD and git diff HEAD empty. Vitest aliases @object-ui/components to src, so no dist step. A (registeredTemporalWidget → undefined; blob 3d6f94a → 868ba46): 14 failed | 3 passed, every (a)/(b)/(c) red and the 3 CONTROLs green. B (focused.blur() → void focused): 2 failed | 15 passed, the two outside-press pins. C (FilterUI ComponentRegistry.get('date','field') → undefined; blob 12e4922 → 4811b31): 2 failed | 1 passed. NOT MEASURED: whole packages/components/ run, which hit its 1500s timeout (VERDICT command-exit 124), so the targeted sets above are declared in its place and CI runs the farm. NOT MEASURED: browser screenshot (no backend booted).",
"gates": "Exit codes captured before any pipe. Closure build components^... + plugin-view^...: 0. Closure build plugin-list^... (rebuilds components with this change): 0. type-check: components 0, plugin-view 0, plugin-list 0. eslint --no-inline-config narrowed to the 5 changed .ts/.tsx files: exit 0 and 0 errors. The population is the config's '**/*.{ts,tsx}' block; the JSON format counted 5 files. filter-builder.tsx carries 20 warnings and FilterUI.tsx 7, the same counts as their BASE blobs. The config has no project/projectService, so it is not type-aware and the diff cannot move an untouched file's verdict. check:phantom-deps 0, check:self-import 0, check:unreferenced-sources 0, check:doc-example-readers 0, check:handler-key-reads 0, check:side-effects-array 0, check:element-data-source-declaration 0, 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, check:control-bytes 0, check-hand-rolled-comment-mask.mjs 0, check-changeset-fixed.mjs 0, check-changeset-presence.mjs 0, check:new-line-citations 0, check:eager-closure 0. Control-byte self-scan of the changed files: 0 hits. check:spec-floors was not run. CI families: in_progress (PR just opened).",
"files_changed": [
"packages/components/src/custom/filter-builder.tsx",
"packages/components/src/__tests__/filter-builder-date-value-seam-12743.test.tsx",
"packages/plugin-view/src/FilterUI.tsx",
"packages/plugin-view/src/__tests__/FilterUI.datePicker-12743.test.tsx",
"packages/plugin-list/src/__tests__/ListView.filterDatePicker-12743.test.tsx",
".changeset/12743-filter-date-picker.md"
],
"line_budget": "n/a (no skills/** or governed path touched)",
"deviations": [
"packages/plugin-list/src/__tests__/ListView.filterDatePicker-12743.test.tsx is a test beside the measured host (ListView), not beside a touched file. A2 requires pins on the real filter UI the console uses, and no plugin-list source was changed.",
"The host wiring site is @object-ui/fields' existing registerAllFields() (field:date / field:datetime), so it needed no edit. components/src/renderers/complex/filter-builder.tsx needed no edit either: it renders the same FilterBuilder.",
"The first install log was written at the scratchpad root (issue-12743-install.log, prefixed) before the issue-12743/ subdirectory existed. Everything after that went into the subdirectory."
],
"mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api REST GETs (card, comments, PR read-back).",
"api_writes": "2 relay strokes via objectstack scripts/pm/fleet-write/dispatch.mjs, each a POST /repos/objectstack-ai/objectstack/dispatches: (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12782/assignees [baozhoutao]; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectui/issues/12743/comments. git push: 5 (empty-branch probe, then a429afeab, 6ef18d3bf, cdae59d78, 3fc88bff0). Labels: zero writes, since the dispatch named none and no objectui gate reads them.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: the domain:ui seat (family of objectui#12622 / #12642 / #12664 / #12743) · noted, not filed: plugin-list UserFilters.tsx draws a native input type=date pair for a date-range user-filter chip. That is the same machine-locale face. It was read from source only and not reproduced through a console view, so it has no reach line. The file is outside this claim's surface. Dedupe words: user filter chip date range native input, UserFilters date picker locale, list chip date placeholder",
"carrier: whoever next touches packages/fields/src/widgets/toDomProps.ts or DatePickerField · noted, not filed: DatePickerField composes domProps['aria-describedby'], but toDomProps never forwards aria-describedby, so that read is always undefined. As a result, a host's description (here the between-row 'is required' line) is not linked to the picker's box. It is noted in the PR's Acceptance notes."
]
}
Posted by the os-dev subagent for this card, session https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB.
PR #12782 merged through the merge queue as ed43c79, which is on main. Verified by content: all 6 of the PR's files on origin/main are blob-identical to the accepted head 3fc88bf. The squash commit's message names no model.
What landed:
The console list toolbar's Filter panel (FilterBuilder) and filter-ui draw date / datetime values, both bounds of a range included, with the platform date picker. They resolve it from the host-registered field:date / field:datetime widget in ComponentRegistry.
There is no new export, prop or dependency, and the picker stays in its lazy chunk.
The values written are unchanged, and a typed day is applied on Enter, on blur and on an outside press.
With objectui#12622 / #12642 / #12664, the forms, dialogs, grid cells, kanban dialog and list filters now share one date face.
Still open in the family:
objectui#12759: the record page's inline datetime edit drops its time.
objectui#12784: the list user-filter date-range chip.
pm:dispatched leaves with this note. The card closed completed on merge.
Activity
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 3 (
priority:p2; half 2 of objectui#12664, which triage split (6216283515); half 1 landed asd66d7e8, PR #12756)Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12743-filter-date-pickerWorktree:
objectui-issue-12743Domain:
domain:uiSeat:
domain:ui#2File surface: the date / datetime value editors of the list filter rows, namely
packages/components/src/custom/filter-builder.tsxandpackages/components/src/renderers/complex/filter-builder.tsx, pluspackages/plugin-view/src/FilterUI.tsx(measured at start: which of these the console's list filters actually render);packages/fields/src/only for the export or seam that lets them reach the platform picker (the picker itself ispackages/fields/src/widgets/date-picker/);packages/plugin-view/package.jsononly if a declared dependency is the chosen route;apps/console/vite.config.ts/scripts/check-eager-closure-budget.mjscarve-out rows only if the lazy chunk's membership needs a row; tests beside each; one.changeset/12743-*.md(stop on breach; explain in the report).Container & model:
M,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuireads no path-derived mandate for these paths)Clause-②: yes (provisional: triage names a new
@object-ui/fieldsexport, or moving the face down a layer, as a public-surface change; the dev reports the measured shape, and a contract-tier review is owed before the queue)Responsibility:
objectui: list filter rows on date / datetime fields draw the native input, so the placeholder and digit order follow the machine's locale | the platform picker that forms, dialogs, grid cells and the kanban dialog already draw (objectui#12622 / #12642 / #12664) | every list filter on a date / datetime fieldThread-read: none
Serial constraints cleared: scanned every open objectui PR's file list just now. None touches the filter builders,
FilterUI.tsx,packages/fields/src/index*ordate-picker/. This seat's in-flight objectui#12698 (PR #12765) touchespackages/authand two header components, so it is disjoint.Claimed at: 2026-10-16T19:18Z
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{ "issue": 12743, "status": "done", "branch": "claude/issue-12743-filter-date-picker", "pr": "https://github.com/objectstack-ai/objectui/pull/12782", "session": "session_01XVp19E1MYUTFM3dnkwz8gB (subagent: the parent seat's id)", "premise_still_valid": true, "dispatch_md5": "98ae9e9ad9384a9e8be22a05755c519c (prompt12743.txt, read in full before the first edit)", "summary": "Date and datetime filter rows now draw the platform picker. In FilterBuilder (@object-ui/components; the console's ListView toolbar Filter panel renders it) this covers scalar rows and both between bounds. In plugin-view FilterUI it covers the date filter and both date-range bounds. Both resolve the field:date / field:datetime widget that @object-ui/fields already registers in ComponentRegistry, at render time, as the form renderer in components resolves field:TYPE. There is no new export, prop or dependency, components stays fields-free, and the picker stays in the lazy fields-date-picker chunk. The value shape is kept: YYYY-MM-DD for date; for datetime the picker's ISO instant is read back with core's toDateTimeInputValue onto the zoneless local YYYY-MM-DDTHH:mm that datetime-local wrote. A capture pointerdown listener blurs the editor before an outside press, so the commit-on-blur picker applies typed text. Escape discards. A1 as worded was false: neither builder resolved editors through a registry. The ruling's preferred registry seam already existed, though, so Clause-2 is corrected to no. The PR body's second line says so.", "tests": "At HEAD 3fc88bff0 or an earlier branch commit whose files later commits did not change, each run under os-verify-lock with --maxWorkers=1 and VERDICT command-exit 0 unless noted. New pins: ListView.filterDatePicker-12743 7 passed (real ListView toolbar → FilterBuilder with registerAllFields; (a) picker face, en MM/DD/YYYY, zh YYYY/MM/DD 2026/10/01, no input[type=date]; (b) typed 10/20/2026 → 2026-10-20 on Enter, blur, and outside pointerdown+click which closes the panel; (c) datetime shows '10/01/2026, 09:15 AM' and writes 2026-10-20T14:30; (d) CONTROL text/number rows unchanged). filter-builder-date-value-seam-12743 10 passed (stand-in commit-on-blur widget; inside press does not blur; Escape discards; between bounds; CONTROL no registration keeps the native input). FilterUI.datePicker-12743 3 passed. (e) CONTROL: console vite build plus pnpm check:eager-closure exit 0, printing 'packages/fields 88 modules in ui-components and its src/widgets/date-picker subtree 2 in fields-date-picker, exactly'; eager-closure.json does not name fields-date-picker. Wider runs: all 20 components filter-builder* files plus schema-catalog filter-builder-mirror-6939: 417 passed. Components FilterBuilder/config-field-renderer consumers: 4 files / 26 passed. plugin-list Filter-panel/initialFilters tests: 13 files / 95 passed. packages/plugin-view/ whole dir: 79 files / 723 passed. Ablations through objectstack scripts/ablation-replace.mjs, each anchor x1 → x0 and each restored with blob == HEAD and git diff HEAD empty. Vitest aliases @object-ui/components to src, so no dist step. A (registeredTemporalWidget → undefined; blob 3d6f94a → 868ba46): 14 failed | 3 passed, every (a)/(b)/(c) red and the 3 CONTROLs green. B (focused.blur() → void focused): 2 failed | 15 passed, the two outside-press pins. C (FilterUI ComponentRegistry.get('date','field') → undefined; blob 12e4922 → 4811b31): 2 failed | 1 passed. NOT MEASURED: whole packages/components/ run, which hit its 1500s timeout (VERDICT command-exit 124), so the targeted sets above are declared in its place and CI runs the farm. NOT MEASURED: browser screenshot (no backend booted).", "gates": "Exit codes captured before any pipe. Closure build components^... + plugin-view^...: 0. Closure build plugin-list^... (rebuilds components with this change): 0. type-check: components 0, plugin-view 0, plugin-list 0. eslint --no-inline-config narrowed to the 5 changed .ts/.tsx files: exit 0 and 0 errors. The population is the config's '**/*.{ts,tsx}' block; the JSON format counted 5 files. filter-builder.tsx carries 20 warnings and FilterUI.tsx 7, the same counts as their BASE blobs. The config has no project/projectService, so it is not type-aware and the diff cannot move an untouched file's verdict. check:phantom-deps 0, check:self-import 0, check:unreferenced-sources 0, check:doc-example-readers 0, check:handler-key-reads 0, check:side-effects-array 0, check:element-data-source-declaration 0, 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, check:control-bytes 0, check-hand-rolled-comment-mask.mjs 0, check-changeset-fixed.mjs 0, check-changeset-presence.mjs 0, check:new-line-citations 0, check:eager-closure 0. Control-byte self-scan of the changed files: 0 hits. check:spec-floors was not run. CI families: in_progress (PR just opened).", "files_changed": [ "packages/components/src/custom/filter-builder.tsx", "packages/components/src/__tests__/filter-builder-date-value-seam-12743.test.tsx", "packages/plugin-view/src/FilterUI.tsx", "packages/plugin-view/src/__tests__/FilterUI.datePicker-12743.test.tsx", "packages/plugin-list/src/__tests__/ListView.filterDatePicker-12743.test.tsx", ".changeset/12743-filter-date-picker.md" ], "line_budget": "n/a (no skills/** or governed path touched)", "deviations": [ "packages/plugin-list/src/__tests__/ListView.filterDatePicker-12743.test.tsx is a test beside the measured host (ListView), not beside a touched file. A2 requires pins on the real filter UI the console uses, and no plugin-list source was changed.", "The host wiring site is @object-ui/fields' existing registerAllFields() (field:date / field:datetime), so it needed no edit. components/src/renderers/complex/filter-builder.tsx needed no edit either: it renders the same FilterBuilder.", "The first install log was written at the scratchpad root (issue-12743-install.log, prefixed) before the issue-12743/ subdirectory existed. Everything after that went into the subdirectory." ], "mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api REST GETs (card, comments, PR read-back).", "api_writes": "2 relay strokes via objectstack scripts/pm/fleet-write/dispatch.mjs, each a POST /repos/objectstack-ai/objectstack/dispatches: (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12782/assignees [baozhoutao]; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectui/issues/12743/comments. git push: 5 (empty-branch probe, then a429afeab, 6ef18d3bf, cdae59d78, 3fc88bff0). Labels: zero writes, since the dispatch named none and no objectui gate reads them.", "open_questions": [], "out_of_scope_findings": [ "carrier: the domain:ui seat (family of objectui#12622 / #12642 / #12664 / #12743) · noted, not filed: plugin-list UserFilters.tsx draws a native input type=date pair for a date-range user-filter chip. That is the same machine-locale face. It was read from source only and not reproduced through a console view, so it has no reach line. The file is outside this claim's surface. Dedupe words: user filter chip date range native input, UserFilters date picker locale, list chip date placeholder", "carrier: whoever next touches packages/fields/src/widgets/toDomProps.ts or DatePickerField · noted, not filed: DatePickerField composes domProps['aria-describedby'], but toDomProps never forwards aria-describedby, so that read is always undefined. As a result, a host's description (here the between-row 'is required' line) is not linked to the picker's box. It is noted in the PR's Acceptance notes." ] }Posted by the os-dev subagent for this card, session
https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landed ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-16T20:50ZPR #12782 merged through the merge queue as
ed43c79, which is onmain. Verified by content: all 6 of the PR's files onorigin/mainare blob-identical to the accepted head3fc88bf. The squash commit's message names no model.What landed:
FilterBuilder) andfilter-uidrawdate/datetimevalues, both bounds of a range included, with the platform date picker. They resolve it from the host-registeredfield:date/field:datetimewidget inComponentRegistry.With objectui#12622 / #12642 / #12664, the forms, dialogs, grid cells, kanban dialog and list filters now share one date face.
Still open in the family:
datetimeedit drops its time.date-rangechip.pm:dispatchedleaves with this note. The card closedcompletedon merge.Generated by Claude Code