@gears-frontx/react 0.2.0-alpha.0 → 0.2.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms.txt CHANGED
@@ -6,9 +6,9 @@ Part of the FrontX React Layer (L3) - depends on @gears-frontx/framework. Peer d
6
6
 
7
7
  ## Core API
8
8
 
9
- - [Gears FrontXProvider](https://frontx.dev/docs/react/provider): Root context provider
10
- - [MFE Components](https://frontx.dev/docs/react/mfe): ExtensionDomainSlot, MfeProvider, RefContainerProvider
11
- - `Gears FrontXProvider` resolves the shared `QueryClient` from `queryCache()` / `queryCacheShared()` through the app instance; mounted MFEs reuse the host cache by building their local app with `queryCacheShared()`, which joins the same shared `QueryClient` without mutating L1 contracts
9
+ - [FrontXProvider](https://frontx.dev/docs/react/provider): Root context provider
10
+ - [MFE Components](https://frontx.dev/docs/react/mfe): ExtensionDomainSlot, MfeProvider
11
+ - `FrontXProvider` resolves the shared `QueryClient` from `queryCache()` / `queryCacheShared()` through the app instance; mounted MFEs reuse the host cache by building their local app with `queryCacheShared()`, which joins the same shared `QueryClient` without mutating L1 contracts
12
12
 
13
13
  ## Hooks
14
14
 
@@ -26,23 +26,27 @@ Part of the FrontX React Layer (L3) - depends on @gears-frontx/framework. Peer d
26
26
  | Hook | Purpose |
27
27
  |------|---------|
28
28
  | `useMfeBridge()` | Access MFE bridge (child MFEs) |
29
- | `useSharedProperty()` | Subscribe to shared property changes |
29
+ | `useSharedProperty()` | Subscribe to shared property changes, via `MfeContext` or an explicit `bridge` option |
30
30
  | `useHostAction()` | Invoke actions on host application |
31
31
  | `useDomainExtensions()` | Subscribe to extensions in a domain |
32
32
 
33
33
  ## Quick Start
34
34
 
35
35
  ```tsx
36
- import { Gears FrontXProvider, useTranslation, useFrontX } from '@gears-frontx/react';
36
+ import { createFrontX, FrontXProvider, presets, useTranslation, useFrontX } from '@gears-frontx/react';
37
+
38
+ // One app per runtime, built once at module level (the full preset here;
39
+ // `presets.full({ microfrontends: config })` also adds microfrontends)
40
+ const app = createFrontX().useAll(presets.full()).build();
37
41
 
38
42
  // Wrap app with provider
39
43
  function App() {
40
44
  return (
41
- <Gears FrontXProvider>
45
+ <FrontXProvider app={app}>
42
46
  <Layout>
43
47
  <MainScreen />
44
48
  </Layout>
45
- </Gears FrontXProvider>
49
+ </FrontXProvider>
46
50
  );
47
51
  }
48
52
 
@@ -81,15 +85,17 @@ function LayoutScreen() {
81
85
  ### Using MFE Bridge
82
86
 
83
87
  ```tsx
84
- import { useMfeBridge, useSharedProperty, Gears FrontX_ACTION_LOAD_EXT, Gears FrontX_SHARED_PROPERTY_THEME } from '@gears-frontx/react';
88
+ import { useMfeBridge, useSharedProperty, FRONTX_ACTION_LOAD_EXT, FRONTX_SHARED_PROPERTY_THEME } from '@gears-frontx/react';
85
89
 
86
90
  function MyExtension() {
87
91
  const bridge = useMfeBridge();
88
- const theme = useSharedProperty(Gears FrontX_SHARED_PROPERTY_THEME);
92
+ const theme = useSharedProperty(FRONTX_SHARED_PROPERTY_THEME);
89
93
 
90
- const handleAction = async () => {
91
- await bridge.executeActionsChain({
92
- action: { type: Gears FrontX_ACTION_LOAD_EXT, target: 'screen', payload: { extensionId: 'other' } }
94
+ // executeActionsChain is acceptance-only: it returns void, never throws,
95
+ // and never yields anything to await for the chain's own execution.
96
+ const handleAction = () => {
97
+ bridge.executeActionsChain({
98
+ action: { type: FRONTX_ACTION_LOAD_EXT, target: 'screen', payload: { subject: 'other' } }
93
99
  });
94
100
  };
95
101
 
@@ -97,6 +103,26 @@ function MyExtension() {
97
103
  }
98
104
  ```
99
105
 
106
+ ### Shared Properties Without MfeProvider
107
+
108
+ `useSharedProperty(propertyTypeId, options)` takes an explicit `bridge` for components that never mount `MfeProvider`, plus a `fallback` returned until the host publishes the property (only `undefined` is substituted; a published `null` is a value). With `fallback` set the result type is `T`. There is no consumer-side validation option: the host validates published values against the property's schema before delivery, so `T` is the caller's declaration of that schema.
109
+
110
+ ```tsx
111
+ import { useSharedProperty } from '@gears-frontx/react';
112
+ import type { ChildMfeBridge } from '@gears-frontx/framework';
113
+
114
+ function StandaloneComponent({ bridge }: { bridge: ChildMfeBridge }) {
115
+ const label = useSharedProperty<string>(LABEL_PROPERTY_ID, {
116
+ bridge,
117
+ fallback: 'Untitled',
118
+ });
119
+
120
+ return <span>{label}</span>;
121
+ }
122
+ ```
123
+
124
+ Omitting `bridge` falls back to `MfeContext`; the hook still throws when neither is available. Changing `bridge` or `propertyTypeId` moves the subscription and the value follows on the same render.
125
+
100
126
  ### Subscribing to Domain Extensions
101
127
 
102
128
  ```tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gears-frontx/react",
3
- "version": "0.2.0-alpha.0",
3
+ "version": "0.2.0-alpha.15",
4
4
  "description": "React bindings and hooks for FrontX framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,37 +26,39 @@
26
26
  "files": [
27
27
  "dist",
28
28
  "CLAUDE.md",
29
- "llms.txt",
30
- "commands"
29
+ "llms.txt"
31
30
  ],
32
31
  "scripts": {
33
32
  "build": "tsup",
34
- "type-check": "tsc --noEmit",
33
+ "type-check": "tsc --noEmit && npm run type-check:test",
35
34
  "type-check:test": "tsc -p tsconfig.test.json",
36
35
  "test": "npm run test:unit",
37
36
  "test:unit": "vitest --run --passWithNoTests=false",
38
37
  "test:unit:watch": "vitest --watch"
39
38
  },
40
39
  "devDependencies": {
41
- "@reduxjs/toolkit": "^2.5.0",
42
- "@tanstack/react-query": "^5.90.0",
40
+ "@reduxjs/toolkit": "2.12.0",
41
+ "@tanstack/react-query": "5.101.4",
43
42
  "@testing-library/react": "16.3.2",
44
- "@types/react": "^19.0.8",
45
- "@types/react-redux": "^7.1.33",
43
+ "@types/node": "^24.0.0",
44
+ "@types/react": "19.2.18",
45
+ "@types/react-redux": "7.1.34",
46
46
  "@vitejs/plugin-react": "4.3.4",
47
47
  "@vitest/coverage-v8": "4.1.4",
48
48
  "jsdom": "26.1.0",
49
- "react": "^19.2.4",
50
- "react-redux": "^9.1.0",
51
- "tsup": "^8.0.0",
52
- "typescript": "^5.4.2",
49
+ "react": "19.2.4",
50
+ "react-dom": "19.2.4",
51
+ "react-redux": "9.3.0",
52
+ "tsup": "8.5.1",
53
+ "typescript": "5.9.3",
53
54
  "vitest": "4.1.4"
54
55
  },
55
56
  "peerDependencies": {
56
57
  "@gears-frontx/framework": "*",
57
- "@tanstack/react-query": ">=5.0.0",
58
- "react": "^19.2.4",
59
- "react-redux": ">=8.0.0"
58
+ "@tanstack/react-query": "5.101.4",
59
+ "react": "19.2.4",
60
+ "react-dom": "19.2.4",
61
+ "react-redux": "9.3.0"
60
62
  },
61
63
  "peerDependenciesMeta": {
62
64
  "@gears-frontx/framework": {
@@ -65,6 +67,9 @@
65
67
  "react": {
66
68
  "optional": false
67
69
  },
70
+ "react-dom": {
71
+ "optional": false
72
+ },
68
73
  "react-redux": {
69
74
  "optional": false
70
75
  },
@@ -1,58 +0,0 @@
1
- <!-- @standalone -->
2
- # frontx:duplicate-screenset - Duplicate Screenset
3
-
4
- ## AI WORKFLOW (REQUIRED)
5
- 1) Read .ai/targets/SCREENSETS.md before starting.
6
- 2) Gather requirements from user.
7
- 3) Follow steps below.
8
-
9
- REQUIRED: Copy folder and update ids.ts only (2 steps, 96% reduction).
10
- REQUIRED: Pass arch:check with zero errors.
11
- REQUIRED: Test via Chrome DevTools MCP (never skip).
12
-
13
- ## GATHER REQUIREMENTS
14
- Ask user for:
15
- - SOURCE screenset name (existing screenset to copy).
16
- - TARGET screenset name (camelCase, single word preferred).
17
- - TARGET category: Drafts | Mockups | Production.
18
-
19
- ## STEP 1: Copy Screenset via CLI
20
- ```bash
21
- frontx screenset copy SOURCE TARGET --category={category}
22
- ```
23
- The CLI automatically:
24
- - Copies all files (screens, slices, actions, events, effects, API, icons, i18n).
25
- - Updates ids.ts with TARGET_SCREENSET_ID and all SCREEN_IDs.
26
- - Everything auto-updates via template literals:
27
- - Event enums: ${TARGET_SCREENSET_ID}/${DOMAIN_ID}/eventName.
28
- - Icon IDs: ${TARGET_SCREENSET_ID}:iconName.
29
- - API domain: ${TARGET_SCREENSET_ID}:serviceName.
30
- - Redux state key.
31
- - Screenset auto-discovered (no manual registration).
32
-
33
- ## STEP 2: Validate
34
- ```bash
35
- npm run type-check
36
- npm run arch:check
37
- npm run lint
38
- grep -rn "OLD_SCREENSET_ID" src/screensets/TARGET/ # Must return 0 matches
39
- ```
40
-
41
- ## STEP 3: Test via Chrome DevTools MCP
42
- STOP: If MCP connection is broken, fix it first. NEVER skip testing.
43
- - npm run dev.
44
- - Verify TARGET in screenset selector.
45
- - Click TARGET screenset in dev panel.
46
- - Verify URL changes to target screenset.
47
- - Check 0 console errors.
48
- - Test all primary features.
49
- - Verify auto-discovery worked (screenset appears without manual registration).
50
-
51
- ## CHECKLIST
52
- - [ ] Gather requirements (source, target name, category).
53
- - [ ] Run `frontx screenset copy SOURCE TARGET --category={category}`.
54
- - [ ] Run type-check (MUST pass).
55
- - [ ] Run arch:check (MUST pass).
56
- - [ ] Run lint (MUST pass).
57
- - [ ] Verify zero occurrences of old screenset ID.
58
- - [ ] Test via Chrome DevTools MCP (NEVER skip).
@@ -1,57 +0,0 @@
1
- <!-- @standalone -->
2
- # frontx:new-component - Add New UI Component
3
-
4
- ## AI WORKFLOW (REQUIRED)
5
- 1) Read `.ai/project/GUIDELINES.md` and `.ai/project/targets/UNIT_TESTING.md` when they exist **before** any unit-test, validation, or testing steps in this command (project-owned overrides take precedence over defaults here).
6
- 2) Check for existing equivalent in project (e.g. components/ui/) and configured UI library first.
7
- 3) Gather requirements from user.
8
- 4) Implement.
9
-
10
- ## CHECK EXISTING COMPONENTS FIRST
11
- - REQUIRED: Read `frontx.config.json` to find the `uikit` value.
12
- - If uikit is a third-party package (not `shadcn` or `none`): read its exports from `node_modules/<package>/` to check for existing components.
13
- - REQUIRED: Before creating a new component, scan the project AND the configured UI library for existing equivalents.
14
- - REQUIRED: Reuse existing components if equivalent exists.
15
-
16
- ## GATHER REQUIREMENTS
17
- Ask user for:
18
- - Component name (e.g., "DataTable", "ColorPicker").
19
- - Component description and props.
20
-
21
- ## IF SCREENSET COMPONENT
22
-
23
- ### STEP 0: Determine Subfolder
24
- - components/ui/: Base UI primitives (shadcn components or custom).
25
- - screens/{screen}/components/: Screen-specific components.
26
- - components/: Shared composites used across screens.
27
-
28
- ### STEP 1: Implementation
29
-
30
- #### 1.1 Create Component
31
- File: src/components/ui/{ComponentName}.tsx (base primitives)
32
- or: src/screens/{screen}/components/{ComponentName}.tsx (screen-specific)
33
- or: src/components/{ComponentName}.tsx (shared composites)
34
- - Must be reusable within the MFE.
35
- - NO Redux or state management.
36
- - Accept value/onChange pattern for state.
37
-
38
- #### 1.2 Export
39
- Export from local index if needed.
40
-
41
- #### 1.3 Validation
42
- <!-- @cpt-begin:cpt-frontx-flow-unit-test-generation-and-agent-verification-agent-verify:p1:inst-agent-implement-and-test -->
43
- If creating a shared composite in `src/components/`, add or update a component test for its stable behavior.
44
- Run `npm run test:unit`, `npm run type-check`, `npm run arch:check`, and `npm run dev` (or the equivalent commands for this project's configured package manager) and apply any stricter triggers or conventions from `.ai/project/targets/UNIT_TESTING.md`. Apply constraints from workflow step 1.
45
- <!-- @cpt-end:cpt-frontx-flow-unit-test-generation-and-agent-verification-agent-verify:p1:inst-agent-implement-and-test -->
46
- Test component in UI.
47
-
48
- ## TESTING
49
- - REQUIRED: Load `.ai/project/GUIDELINES.md` and `.ai/project/targets/UNIT_TESTING.md` when they exist **before** interpreting unit-test requirements elsewhere in this command.
50
- - REQUIRED: Follow `.ai/project/targets/UNIT_TESTING.md` for `__test-utils__/` placement and durable, non-placeholder assertions when adding or updating tests.
51
-
52
- ## RULES
53
- - REQUIRED: Check existing project UI components first; create new only if missing.
54
- - FORBIDDEN: Redux, business logic, side effects in components.
55
- - FORBIDDEN: Inline styles outside components/ui/.
56
- - REQUIRED: Accept value/onChange pattern for state.
57
- - REQUIRED: New shared composite components in `src/components/` include a colocated or nearby unit test when the behavior is stable.
@@ -1,153 +0,0 @@
1
- <!-- @standalone -->
2
- # frontx:new-mfe - Create New Microfrontend Package
3
-
4
- ## PREREQUISITES (CRITICAL - STOP IF FAILED)
5
-
6
- 1. MFE must be associated with a screenset
7
- 2. Screenset must exist (run `frontx-new-screenset` first if needed)
8
- 3. Vite and Module Federation must be configured
9
-
10
- ## QUICK START
11
-
12
- For a screenset named `{screensetName}` with a new MFE:
13
-
14
- ```bash
15
- # 1. Create the MFE package in src/mfe_packages/{screensetName}-mfe/
16
- cp -r packages/cli/template-sources/mfe-package/ src/mfe_packages/{screensetName}-mfe/
17
-
18
- # 2. Update variables in package.json and vite.config.ts:
19
- # - Replace {{mfeName}} with your screenset name (camelCase)
20
- # - Replace {{port}} with available port (3001, 3010, 3020, etc)
21
- # - IMPORTANT: set preview script to "vite preview --port {{port}}"
22
-
23
- # 3. Install dependencies
24
- cd src/mfe_packages/{screensetName}-mfe
25
- npm install
26
-
27
- # 4. Create src/lifecycle.tsx that extends ThemeAwareReactLifecycle
28
-
29
- # 5. Regenerate MFE manifests so bootstrap.ts picks up the new package
30
- npm run generate:mfe-manifests
31
- ```
32
-
33
- ## CONFIGURATION REQUIREMENTS
34
-
35
- ✅ **Correct preview script** (required for port auto-discovery):
36
- ```json
37
- "preview": "vite preview --port {{port}}"
38
- ```
39
-
40
- ✅ **Correct dev script** (for hot reload):
41
- ```json
42
- "dev": "vite --port {{port}}"
43
- ```
44
-
45
- ❌ **WRONG** (don't use this for dev):
46
- ```json
47
- "dev": "vite build && vite preview --port {{port}}"
48
- ```
49
-
50
- ## PORT ALLOCATION
51
-
52
- Reserve ports for MFE packages:
53
- - **3001**: demo-mfe
54
- - **3010+**: (next available: 3010, 3020, 3030, ...)
55
- - **5173**: Main app
56
-
57
- ## LIFECYCLE TEMPLATE
58
-
59
- Create `src/lifecycle.tsx`:
60
-
61
- ```typescript
62
- import React from 'react';
63
- import type { ChildMfeBridge } from '@gears-frontx/react';
64
- import { ThemeAwareReactLifecycle } from '@gears-frontx/react';
65
- import { mfeApp } from './init';
66
- import { YourScreen } from './screens/YourScreen';
67
-
68
- class Lifecycle extends ThemeAwareReactLifecycle {
69
- constructor() {
70
- super(mfeApp);
71
- }
72
-
73
- protected renderContent(bridge: ChildMfeBridge): React.ReactNode {
74
- return <YourScreen bridge={bridge} />;
75
- }
76
- }
77
-
78
- export default new Lifecycle();
79
- ```
80
-
81
- ## dev:all INTEGRATION (AUTOMATIC)
82
-
83
- After creating the MFE and running `npm run generate:mfe-manifests`, the `dev:all`
84
- script auto-discovers your new package — no manual configuration needed.
85
-
86
- `dev-all.ts` scans `src/mfe_packages/*/package.json` and reads the port from the
87
- `preview` (or `dev`) script using `--port NNNN`. The new MFE will automatically
88
- appear in the next `npm run dev:all` run.
89
-
90
- ## VALIDATION
91
-
92
- After creation:
93
-
94
- ```bash
95
- # Regenerate manifests (required after adding new MFE)
96
- npm run generate:mfe-manifests
97
-
98
- # Validate TypeScript
99
- npm run type-check
100
-
101
- # Check architecture compliance
102
- npm run arch:check
103
-
104
- # Run the dev server (picks up new MFE automatically)
105
- npm run dev:all
106
-
107
- # Verify MFE loads at http://localhost:5173
108
- # Open Studio Overlay (Ctrl+`) and check screenset
109
- ```
110
-
111
- ## TROUBLESHOOTING
112
-
113
- ### Issue: MFE not appearing in screenset selector
114
- - Run `npm run generate:mfe-manifests` to regenerate manifests
115
- - Check mfe.json manifest is properly exported
116
- - Verify extensions are registered in manifest
117
- - Check browser console for errors
118
-
119
- ### Issue: dev:all not picking up MFE port
120
- - Verify `preview` script has `--port NNNN` (e.g., `"vite preview --port 3010"`)
121
- - Check port is not in use (`lsof -i :3010`)
122
- - Restart dev server
123
-
124
- ### Issue: Hot reload not working
125
- - Verify dev script uses `vite --port` (not `vite build && vite preview`)
126
- - Check port is not in use
127
- - Restart dev server
128
-
129
- ### Issue: Redux/useSelector errors
130
- - MFE must use mock data (no Redux Provider in isolation)
131
- - Use `useState` for local state management
132
- - Do not import Redux hooks (@gears-frontx/react)
133
-
134
- ## BEST PRACTICES
135
-
136
- ✅ **DO:**
137
- - Set `preview` script with `--port NNNN` for port auto-discovery
138
- - Use mock data with useState for UI-only MFEs
139
- - Keep MFE logic isolated and simple
140
- - Use local components (e.g. components/ui/)
141
- - Run `npm run generate:mfe-manifests` after creating the MFE
142
-
143
- ❌ **DON'T:**
144
- - Import Redux hooks directly
145
- - Use vite build && vite preview in dev mode
146
- - Create complex state management in MFE
147
- - Hardcode ports without updating package.json preview script
148
-
149
- ---
150
-
151
- See also:
152
- - `/packages/cli/template-sources/mfe-package/` for templates
153
- - `frontx-new-screenset.md` for screenset creation
@@ -1,45 +0,0 @@
1
- <!-- @standalone -->
2
- # frontx:new-screen - Add New Screen
3
-
4
- ## AI WORKFLOW (REQUIRED)
5
- 1) Read .ai/targets/SCREENSETS.md and .ai/targets/EVENTS.md before starting.
6
- 2) Read `.ai/project/GUIDELINES.md` and `.ai/project/targets/UNIT_TESTING.md` when they exist **before** planning unit tests, validation, or any test-related tasks in this command (project-owned overrides take precedence over defaults here).
7
- 3) Gather requirements from user (including UI sections).
8
- 4) Implement.
9
-
10
- ## GATHER REQUIREMENTS
11
- Ask user for:
12
- - Screenset path (e.g., src/screensets/chat).
13
- - Screen name (camelCase).
14
- - UI sections (e.g., "header, form, data table").
15
- - Add to menu? (Y/N)
16
-
17
- ## STEP 1: Implementation
18
- 1) Add screen ID to ids.ts.
19
- 2) Create components BEFORE screen file per Component Plan.
20
- 3) Create screen following data flow rules from .ai/targets/EVENTS.md:
21
- - Use actions to trigger state changes
22
- - FORBIDDEN: Direct slice dispatch from screen
23
- 4) Add i18n with useScreenTranslations(). Export default.
24
- 5) Add or update a screen test that covers stable render or behavior for the new screen and place any test-only helpers in a sibling `__test-utils__/` folder.
25
- 6) Add to menu if requested.
26
- 7) Validate: run `test:unit`, `type-check`, and `arch:check` via this project's package manager per `.ai/project/targets/UNIT_TESTING.md` (which defines the exact commands). Apply constraints from workflow step 2.
27
- 8) Test via Chrome DevTools MCP (REQUIRED):
28
- - Navigate to new screen
29
- - Verify screen renders without console errors
30
- - Test UI interactions and data flow
31
- - Verify translations load correctly
32
- - STOP if MCP connection fails
33
-
34
- ## TESTING
35
- - REQUIRED: Load `.ai/project/GUIDELINES.md` and `.ai/project/targets/UNIT_TESTING.md` when they exist **before** interpreting unit-test requirements elsewhere in this command.
36
- - REQUIRED: Use neutral fixtures, translation mocks, and stable keys, roles, or IDs instead of placeholder-derived copy when adding or updating generated screen tests.
37
-
38
- ## COMPONENT PLAN
39
- - REQUIRED: Use local components (e.g. `components/ui/`) — no shared UI kit package.
40
- - components/ui/: base UI primitives (shadcn components or custom)
41
- - screens/{screen}/components/: screen-specific components
42
-
43
- ## DATA FLOW
44
- - Uses existing screenset events/slices per EVENTS.md
45
- - Screen dispatches actions, never direct slice updates
@@ -1,57 +0,0 @@
1
- <!-- @standalone -->
2
- # frontx:new-screenset - Create New Screenset
3
-
4
- ## PREREQUISITES (CRITICAL - STOP IF FAILED)
5
- Run `frontx --version`.
6
- STOP: If fails, tell user to install.
7
- FORBIDDEN: Creating screenset manually or by copying peers.
8
-
9
- ## AI WORKFLOW (REQUIRED)
10
- 1) Check prerequisites above.
11
- 2) Read .ai/targets/SCREENSETS.md and .ai/targets/EVENTS.md before starting.
12
- 3) Read `.ai/project/GUIDELINES.md` and `.ai/project/targets/UNIT_TESTING.md` when they exist **before** planning unit tests, validation, or any test-related tasks in this command (project-owned overrides take precedence over defaults here).
13
- 4) Gather requirements from user (including UI sections).
14
- 5) Implement.
15
-
16
- ## GATHER REQUIREMENTS
17
- Ask user for:
18
- - Screenset name (camelCase).
19
- - Category: Drafts | Mockups | Production.
20
- - Initial screens.
21
- - UI sections per screen (e.g., "stats cards, charts, activity feed").
22
-
23
- ## STEP 1: Implementation
24
- 1) Create screenset via `frontx screenset create` (REQUIRED).
25
- 2) Create components BEFORE screen file per Component Plan.
26
- 3) Implement data flow per .ai/targets/EVENTS.md:
27
- - Actions emit events via eventBus.emit()
28
- - Effects subscribe and update slices
29
- - FORBIDDEN: Direct slice dispatch from components
30
- 4) Add API service with mocks and endpoint descriptors:
31
- - Read endpoints: `readonly prop = this.protocol(RestEndpointProtocol).query<T>('/path')`
32
- - Write endpoints: `readonly prop = this.protocol(RestEndpointProtocol).mutation<T, V>('PUT', '/path')`
33
- - NO queryOptions, NO manual query key factories outside the service
34
- - Screens use `useApiQuery(service.prop)` and `useApiMutation({ endpoint: service.prop })`
35
- 5) Add or update starter unit tests for stable generated behavior.
36
- 6) Validate: run `test:unit`, `type-check`, `arch:check`, and `lint` via this project's package manager per `.ai/project/targets/UNIT_TESTING.md` (which defines the exact commands). Apply constraints from workflow step 3.
37
- 7) Test via Chrome DevTools MCP (REQUIRED):
38
- - Navigate to new screenset
39
- - Verify screen renders without console errors
40
- - Test user interactions trigger correct events
41
- - Verify state updates via Redux DevTools
42
- - STOP if MCP connection fails
43
-
44
- ## COMPONENT PLAN
45
- - REQUIRED: Use local components (e.g. `components/ui/`) — no shared UI kit package.
46
- - components/ui/: base UI primitives (shadcn components or custom)
47
- - components/: multi-screen shared components
48
- - screens/{screen}/components/: screen-specific components
49
-
50
- ## DATA FLOW
51
- - Events: {domain events per EVENTS.md}
52
- - State: slices/, events/, effects/, actions/
53
- - API: api/{Name}ApiService.ts with mocks and endpoint descriptors
54
-
55
- ## TESTING
56
- - REQUIRED: Load `.ai/project/GUIDELINES.md` and `.ai/project/targets/UNIT_TESTING.md` when they exist **before** interpreting unit-test requirements elsewhere in this command.
57
- - REQUIRED: Preserve the generated API-contract test and `HomeScreen` smoke test unless the new behavior replaces that baseline intentionally.