Repository navigation
views: declare userActions.editInline: true on every grid and list view, so cell editing survives the objectui upgrade (objectstack-ai/objectui#5144) #2048
Description
Activity
- addedpm:queueReady for the PM dispatch loopReady for the PM dispatch looppriority:p2Medium: important, M3Medium: important, M3pm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchand removedpm:queueReady for the PM dispatch loopReady for the PM dispatch loop
on Oct 10, 2026 objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsClaim: PM loop round R77
Session:session_012zh91QzFgePbkmuHnugLN3
Account:os-zhuang(the seat's linked user asGET /useranswers it; always the card's assignee)
Branch:claude/issue-2048-views-edit-inline
Worktree:hotcrm-issue-2048
Domain:repo:hotcrm(single-lane repo, nodomain:*taxonomy)
Seat:repo:hotcrm#1
File surface: the 14src/*/views/*.view.tsfiles (oneuserActions: { editInline: true }per grid / list view, or the one-line reason above a view left read-only); one new test undertest/that walks every grid and list view; one.changeset/2048-*.md. ⛔ No helper or wrapper that injects the key (stop on breach; explain in the report)
Container & model:M,mode:subagent(the os-dev definition and thescripts/pmwrite tools live in this container's objectstack checkout),model: default(dispatch-gates --tier --repo objectstack-ai/hotcrmanswers "the tier stays the PM's per-card judgment call";governedPathsInover the surface: none)
Clause-②: no
Responsibility:the app's 41 grid / list views (none declares userActions.editInline) | the platform changed its reading of an absent key to the spec default false (objectui#12036), as ruled in objectui#5144 | every console user editing a cell in a HotCRM table, once the runtime's objectui moves past 1b2d0160fe
Thread-read: none
Serial constraints cleared: nothing is in flight. This lands BEFORE the 3.2.0 version PR, which consumes every changeset and so comes last.
Generated by Claude Code
- added a commit that references this issue
on Oct 10, 2026 objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 2048,
"status": "done",
"branch": "claude/issue-2048-views-edit-inline",
"pr": "#2050",
"session": "session_012zh91QzFgePbkmuHnugLN3 (subagent: the parent PM seat's session)",
"premise_still_valid": true,
"summary": "Each of the app's 40 grid views now declares userActions: { editInline: true }. There is one block per view, written in its own view file just below its label, using the spec key. No helper or wrapper injects it. No view was left read-only: every object behind a grid view lists update in enable.apiMethods and has fields people write. Forecasts carry hand-entered quota, notes and manual rows. Published articles are not locked. The app has no audit or history list. A new test, test/view-inline-edit.test.ts, walks every list and listViews entry of the composed stack. It fails on a grid or list view that neither declares editInline: true nor appears in the READ_ONLY_BY_NATURE roster (empty today). It also fails on a stale roster entry. Draft PR #2050 is assigned to os-zhuang. Files changed: the 14 src//views/.view.ts files (40 lines added), test/view-inline-edit.test.ts (new), .changeset/2048-views-edit-inline.md (new, hotcrm patch). Deviations and premise detail: (1) The card counted 41 views, 40 grid and 1 list. The composed stack holds 40 grid views and 0 list views. The 41st grep hit is src/sales/pages/account_workbench.page.ts:32, the type: 'list' line of an interface Page, not a view. It is outside the rule and the claim surface and is left untouched (see Acceptance notes). (2) Measured before the fix on f0afcbd: GET /api/v1/meta/view served 40 grid views, and none carried a userActions block. The console this repo pins (@objectstack/console 17.7.0 = objectui 0abd4f9f8769) predates objectui#12036. Its toolbar gate is userActions?.editInline !== false && editable && can(update), so the loss cannot be seen there yet. Measured in Chromium, before and after the fix: on Products, admin is offered Edit inline and na.rep@objectos.ai (crm_product allowEdit false) is not. On Leads, both are offered it. After the fix, all 40 served views carry editInline: true. Each toolbar is identical before and after, even though defineView fills in the other nine userActions defaults, and the toggle starts off. (3) The leg 'against objectui main at or after 1b2d0160fe' is NOT MEASURED, because the objectui repo is out of this session's scope. (4) objectstack dev serves dist/objectstack.json and warned that the artifact was stale, so the post-fix reading was taken after pnpm build. (5) Token ratchet: no scope is over its ceiling and no ceiling moved. src/revenue authored total is ~18,781 of 19,000 (headroom 248 -> 219). src/service authored total is ~21,836 of 22,000 (245 -> 164). (6) The harness attribution reminder names a model in its Co-Authored-By trailer and asks for a different PR footer. Per the dispatch and the os-dev definition, the commit carries the model-free trailers and the PR body ends with the session-URL footer. Not imitated, reported here. (7) The worktree was removed (node_modules first, no --force). No dev server or browser of mine is left running.",
"tests": "pnpm verify: OS_VERIFY_LOCK_SLOT=hotcrm-2048 bash os-verify-lock.sh -c 'pnpm verify' on d4764b9 -> 'os-verify-lock: VERDICT command-exit 0 · held the lock 459s'. Inside it: validate '✓ Validation passed', typecheck (tsc --noEmit, chain continued), lint '18 suggestion(s)' with 0 errors, '✓ i18n lint gate: 0 i18n/missing-* issues', '✓ source hygiene clean', '✓ source token ratchet clean', '✓ Build complete', test 'Test Files 175 passed (175) · Tests 3622 passed | 1 skipped (3623)'. New test alone: vitest run --maxWorkers=2 test/view-inline-edit.test.ts -> 'Tests 3 passed (3)', VERDICT command-exit 0. Ablations ran on the committed fix (HEAD d4764b9) through objectstack scripts/ablation-replace.mjs in wrap mode on src/revenue/views/product.view.ts. Each mutation landed on disk ('ok mutation landed: anchor 1 -> 0', blob 88cb8f3b6408 -> a06e8bbe87d7 / f465dedfb485 / 8aabdc379151) and was restored ('ok restored: blob == HEAD (88cb8f3b6408) and git diff HEAD is empty'). Results: (a) delete the block -> red, 'expected [ crm_product.all_products ] to deeply equal []', 1 failed | 2 passed, VERDICT command-exit 1. (b) editInline: false -> red, 1 failed | 2 passed. (c) legacy inlineEdit: true instead of the block -> red, 1 failed | 2 passed. No rebuild was needed: the test imports TS source through test/helpers/composed-stack.ts (objectstack.composition.ts), with no dist on the path. pnpm changeset status --since=origin/main -> exit 0, 'hotcrm patch'. Public door: GET /api/v1/meta/view on a dev boot at port 4936 -> before (f0afcbd) 40 grid views, 0 with userActions; after (d4764b9, rebuilt) 40/40 with editInline true. Chromium (/opt/pw-browsers/chromium) data-testid toolbar-inline-edit-toggle count, before -> after: admin/crm_product 1 -> 1, na.rep/crm_product 0 -> 0, admin/crm_lead 1 -> 1, na.rep/crm_lead 1 -> 1; all four toolbars identical. NOT MEASURED: console at objectui main >= 1b2d0160fe, reason: the objectui repo is out of session scope. NOT MEASURED locally: pnpm test:e2e, declared to CI. CI on d4764b9 when this report was written: Check Changeset, Quality Checks, link-check, Label Pull Request = success; Build and Test (22.x), Playwright, Analyze Code = in_progress.",
"mcp_calls": "0",
"api_writes": "3 REST writes, all through the fleet-write relay as objectstack-fleet[bot]: POST /repos/objectstack-ai/hotcrm/pulls (pr_create, draft, #2050); POST /repos//issues/2050/assignees (os-zhuang, via label-write.mjs, read-back MATCHES); POST /repos//issues/2048/comments (this os-dev-report, via post-stamped.mjs). Each was carried by one POST /repos/objectstack-ai/objectstack/dispatches relay request. Separately, one git push of the branch (the empty probe and then d4764b9), which is not a REST write. No other writes: no claim, no card assignee, no labels added.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed · account_workbench (src/sales/pages/account_workbench.page.ts) is an interface Page with its own interfaceConfig.userActions block and no editInline. The pinned console's InterfaceListPage reads inlineEdit: userActions.editInline === true, so it already offers no cell editing, which matches the page's documented 'deliberately closed' design. This is the card's 41st grep hit, not a view and not a defect. Dedupe words: account_workbench editInline interface page",
"carrier: none (承接者:无) · noted, not filed · defineView fills in all ten UserActionsConfigSchema defaults once any userActions key is declared, so the served view carries sort/search/filter/refresh/rowHeight/group true and addRecordForm/hideFields/rowColor false. On the pinned console this measured toolbar-identical to an absent block, so it is not a defect. Dedupe words: userActions defaults materialised defineView"
]
}objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsVerdict: os-dev report
6095951504, PR #2050 — ACCEPT, Tier S (not governed, +123 / −0): the seat lands it through the merge queue once every check on headd4764b99is green.repo:hotcrmseat,session_012zh91QzFgePbkmuHnugLN3, 2026-10-10T09:06Z.Checked in git, not taken from the report:
- PR shape: draft, base
main; first lineFixes #2048, thenClause-②: no. 16 files:- the 14
src/*/views/*.view.ts, each adding onlyuserActions: { editInline: true },(40 lines across the 14 files, one per grid view, nothing removed); test/view-inline-edit.test.ts(new);- a
'hotcrm': patchchangeset.
No helper or wrapper injects the key; it is written in each view file, as the card requires.
- the 14
- The count: the composed stack holds 40 grid views and 0 list views. The card's 41st grep hit is the
type: 'list'line of the interface pageaccount_workbench, which is not a view and is deliberately closed to cell editing (its ownuserActionsblock). Accepted as measured. - The test walks every
list/listViewsentry of the composed stack and fails on a grid or list view that neither declareseditInline: truenor sits inREAD_ONLY_BY_NATURE(empty: no object behind a grid is read-only by nature). It also fails on a stale roster entry. Ablations onproduct.view.ts, each restored to HEAD, turned it red: the block removed,editInline: false, the legacyinlineEdit: true. - Measured at the door:
GET /api/v1/meta/viewserved 40 grid views with 0userActionsbefore, and 40 / 40 witheditInline: trueafter. On the pinned console (objectui0abd4f9f8769, before objectui#12036) the toolbars are identical before and after, and the permission gate holds:na.rephas no Edit inline on Products and has it on Leads. - Token ratchet: clean, no ceiling moved.
src/revenue~18,781 / 19,000;src/service~21,836 / 22,000. pnpm verifygreen ond4764b99: 3,622 passed, 1 skipped.
Not measured, accepted: the console against objectui
main≥1b2d0160fe. objectui is outside this session's repository scope; the pinned console's toolbar gate and the served metadata are the measured halves.Next: #2049 (the 3.2.0 version PR) unblocks on this landing.
Generated by Claude Code
- PR shape: draft, base
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsLanded: PR #2050 MERGED as
81f86440onmain(squash, single parentf0afcbda). The seat landed it through the merge queue after 9 of 9 checks went green on headd4764b99: ready and queued at 09:15Z, merged 09:15:36Z.repo:hotcrmseat,session_012zh91QzFgePbkmuHnugLN3, 2026-10-10T09:15Z.Two readings:
- the PR object reads
merged, merge commit81f86440; git diff f0afcbda 81f86440is the reviewed 16 files, +123 / −0.
Closed as it should be:
Fixes #2048closed this card (completed). No other card was closed by a keyword.What now holds: all 40 HotCRM grid views declare
userActions: { editInline: true }. Cell editing therefore survives a console at or after objectui#12036, still gated by the user'supdatepermission. A test fails on any new grid view that does not declare it. This ships in 3.2.0 (#2049).This act: removes
pm:dispatchedand the assignee here.
Generated by Claude Code
- the PR object reads
- removedpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatch
on Oct 10, 2026
Filing gate: a platform behaviour change that reaches this app's metadata. Filed by the objectstack director seat (summon #35, seat post objectstack-ai/objectstack#12708,
session_01VYToj6PQehTEKNrjGM9akg) on the maintainer's instruction in that session, verbatim: 「只需要处理已经交代的 userActions.editInline: true」. ⛔ Not a claim, ⛔ not a dispatch; the hotcrm lane claims and lands it.What changed on the platform
@objectstack/specdeclaresListView.userActions.editInlinewith.default(false)since 17.0: "Off by default: the list is read-only unless the author opts in" (packages/spec/src/ui/view.zod.ts:1535).userActions.editInlinenorinlineEditoffers no inline-edit toggle and never opens in edit mode. The console's toggle is session-only now and writes nothing into the view.userActions.edit, the server's effective API operations) and the current principal canupdatethe object (packages/plugin-list/src/ListView.tsx:2007).Measured in this repo (
mainf0afcbd, 2026-10-09)type: 'grid'views and 1type: 'list'view across 14*.view.tsfiles undersrc/*/views/(marketing, revenue, sales, service).userActions.editInlineorinlineEdit. Onlysrc/sales/pages/account_workbench.page.ts:62carries auserActionsblock at all.What to do
userActions: { editInline: true }(the spec key;inlineEdit: truewould also fold into it, but the spec key is the one to write). Expected: all 41, one block per view.Acceptance
type: 'grid'andtype: 'list'view insrc/**either declaresuserActions.editInline: trueor carries the recorded reason.mainat or after1b2d0160fe: the inline-edit toggle is offered on a declared view for a user withupdateon the object, and absent for a user without it.Related
userActions.editInlinehas two different defaults across surfaces, and neither is the spec's.default(false)objectui#5144 (the ruling and the fold), fix(plugin-list): read userActions.editInline with the spec default, folding a stored inlineEdit into it (objectui#5144) objectui#12036 (the landing).Filed by the director seat; generated by Claude Code