# Phase 2 Summary ## Scope Executed the state and replicants phase only. This phase focused on isolating state logic, normalizing Pinia stores, encapsulating browser-side replicant access, and moving side effects behind services without changing UX, visual design, overlay CSS, or public NodeCG contracts. ## Completed - Added pure state/domain modules: - `src/shared/domain/scoreboard` - `src/shared/domain/commentary` - `src/shared/domain/graphics` - `src/shared/domain/players/state.ts` - `src/shared/domain/packs/characters.ts` - Moved normalization and pure state transitions out of dashboard stores. - Replaced direct dashboard replicant imports with `src/dashboard/services/replicant-state-service.ts`. - Added `useGraphicsSettingsStore` and moved dashboard graphics skin writes through the store. - Reworked scoreboard, players and commentary stores to use shared domain normalizers and service-based replicant sync. - Replaced the pack registry singleton composable with a normalized `usePacksStore`. - Moved pack replicant listeners and NodeCG pack messages into `src/dashboard/services/pack-service.ts`. - Removed Vue reactivity and mutable pack registration from `src/shared/fighting-characters.ts`. - Modeled installed pack manifests as explicit store state instead of hidden module state. - Centralized registry auto-refresh timer in the packs store. - Routed integration NodeCG messages through `src/dashboard/services/integration-message-service.ts`. - Added `src/graphics/shared/services/replicated-state.ts` so graphics read replicants through a service layer. - Removed the redundant `src/dashboard/stores/store-sync.ts`. ## Preserved - Public replicant names were unchanged. - Public message names were unchanged. - Existing dashboard UX was preserved. - Overlay markup, CSS, positioning and animation logic were not intentionally changed. - The existing `usePackRegistry` import path remains as a compatibility wrapper over the packs store. - The legacy `src/shared/fighting-characters.ts` path remains as a compatibility export, but no longer owns mutable runtime state. ## Realtime Flow After This Phase ```text schemas -> nodecg/browser -> dashboard services / graphics services -> Pinia stores or overlay computed state -> components ``` Pack runtime flow: ```text pack replicants -> pack service -> packs store -> pack registry compatibility composable -> game / character UI ``` ## Verification - `pnpm.cmd exec vue-tsc -p tsconfig.browser.json --noEmit`: passed. - `pnpm.cmd exec tsc -b tsconfig.extension.json --pretty false`: passed. - `pnpm.cmd exec eslint`: passed with 0 errors and existing Vue formatting warnings. - `pnpm.cmd run build`: passed. - Searched dashboard, graphics and shared for direct NodeCG/message/replicant imports: - remaining browser NodeCG access is contained in services and `nodecg/browser`. - direct component/view replicant imports were removed. - Searched for `any` in touched runtime areas: - no new TypeScript `any` usage was added. ## Notes and Limits - This phase did not split large views like `Players.vue` or `Settings.vue`. - This phase did not refactor overlay internals beyond replacing direct replicant imports with a read service. - This phase did not rewrite extension-side `pack-manager.ts`. - This phase did not rename public messages to the future canonical names; compatibility was preserved. - Existing Vue lint warnings remain formatting-only and were not addressed because they are outside this phase. ## Remaining For Later Phases - Controlled rewrite of `pack-manager.ts`. - Full split of `useIntegration` into provider clients, OAuth client, temporary players and import modules. - Divide `Players.vue` and `Settings.vue`. - Extract overlay view models and visual helpers after visual baseline. - Add tests for pure normalizers and pack state derivations.