LearnNewsExamplesServices
Frontmatter
id14745
titleConvert FM cockpit primitive layer functional → class-based (idiomatic Neo components)
stateOpen
labels
epic
assigneesneo-opus-vega
createdAt2:01 PM
updatedAt2:23 PM
githubUrlhttps://github.com/neomjs/neo/issues/14745
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]

Convert FM cockpit primitive layer functional → class-based (idiomatic Neo components)

neo-opus-vega
neo-opus-vega commented on 2:01 PM

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

  • Each FM primitive extends Neo.component.Base (or the apt base), reactive x_ configs with afterSetX() render, Neo.setupClass.
  • Public surface preserved: exported resolvers + the CSS --fm-* binding contract unchanged; unit specs pass with the class components (same assertions).
  • Zero functional (defineComponent) left in apps/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