Context
@tobiu vetoed building AgentCard (#14598) as a functional component: "functional components are vastly inferior to class-based counterparts. VBA." VBA confirms it: apps/ is 320 : 9 class-vs-functional; functional (defineComponent) is a still-maturing feature (#6992) that thinly wraps the model, while the mature class idiom (extends Component.Base, reactive x_ configs, afterSetX() → vdom + this.update(), items:[{module}] composition, state.Provider binding — see src/component/Chip.mjs, apps/agentos/view/FleetSettingsPanel.mjs) is the production Neo component.
My miss: I built the whole FM cockpit primitive layer functional — StateDot (#14700, merged), FamilyRail (#14722, merged), EventChip (#14701, merged), HealthSwatch (#14726, merging). Non-idiomatic across the board, not just AgentCard.
The Fix
Convert the FM primitive layer to class-based components, preserving each primitive's PUBLIC surface (the exported pure resolvers stateToken/familyToken/kindToken/kindLabel/stateLabel stay; the state/family/kind/count/label/live configs stay reactive) so consumers + the CSS token layer are unaffected — only the component base + internal render switch functional→class.
Sequence (foundational first): StateDot (others reuse stateToken) → FamilyRail → EventChip → HealthSwatch. Then AgentCard (#14598) is built class-based composing the converted primitives.
Acceptance Criteria
Related
Epic #14560 (FM cockpit) · #14598 (AgentCard, built class after) · operator veto 2026-07-04 · idiom refs src/component/Chip.mjs + apps/agentos/view/FleetSettingsPanel.mjs. Release classification: not release-blocking (idiom correction of merged work).
Origin Session ID: 3bc21462-8122-4b02-81e4-324ed781e1ac
Context
@tobiu vetoed building AgentCard (#14598) as a functional component: "functional components are vastly inferior to class-based counterparts. VBA." VBA confirms it: apps/ is 320 : 9 class-vs-functional; functional (
defineComponent) is a still-maturing feature (#6992) that thinly wraps the model, while the mature class idiom (extends Component.Base, reactivex_configs,afterSetX()→ vdom +this.update(),items:[{module}]composition, state.Provider binding — seesrc/component/Chip.mjs,apps/agentos/view/FleetSettingsPanel.mjs) is the production Neo component.My miss: I built the whole FM cockpit primitive layer functional — StateDot (#14700, merged), FamilyRail (#14722, merged), EventChip (#14701, merged), HealthSwatch (#14726, merging). Non-idiomatic across the board, not just AgentCard.
The Fix
Convert the FM primitive layer to class-based components, preserving each primitive's PUBLIC surface (the exported pure resolvers
stateToken/familyToken/kindToken/kindLabel/stateLabelstay; thestate/family/kind/count/label/liveconfigs stay reactive) so consumers + the CSS token layer are unaffected — only the component base + internal render switch functional→class.Sequence (foundational first): StateDot (others reuse
stateToken) → FamilyRail → EventChip → HealthSwatch. Then AgentCard (#14598) is built class-based composing the converted primitives.Acceptance Criteria
extends Neo.component.Base(or the apt base), reactivex_configs withafterSetX()render,Neo.setupClass.--fm-*binding contract unchanged; unit specs pass with the class components (same assertions).defineComponent) left inapps/agentos/view/fleet/.Related
Epic #14560 (FM cockpit) · #14598 (AgentCard, built class after) · operator veto 2026-07-04 · idiom refs
src/component/Chip.mjs+apps/agentos/view/FleetSettingsPanel.mjs. Release classification: not release-blocking (idiom correction of merged work).Origin Session ID: 3bc21462-8122-4b02-81e4-324ed781e1ac