@hai3/react 0.2.0-alpha.0

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/CLAUDE.md ADDED
@@ -0,0 +1,227 @@
1
+ # @hai3/react
2
+
3
+ React bindings and hooks for HAI3 applications. Provides the React integration layer.
4
+
5
+ ## React Layer
6
+
7
+ This package is part of the **React Layer (L3)** - it depends only on @hai3/framework (not directly on SDK packages) and provides React-specific components and hooks.
8
+
9
+ ## Core Concepts
10
+
11
+ ### HAI3Provider
12
+
13
+ Wrap your app with HAI3Provider to enable all hooks:
14
+
15
+ ```tsx
16
+ import { HAI3Provider } from '@hai3/react';
17
+
18
+ function App() {
19
+ return (
20
+ <HAI3Provider>
21
+ <YourApp />
22
+ </HAI3Provider>
23
+ );
24
+ }
25
+
26
+ // With configuration
27
+ <HAI3Provider config={{ devMode: true }}>
28
+ <YourApp />
29
+ </HAI3Provider>
30
+
31
+ // With pre-built app
32
+ const app = createHAI3().use(screensets()).build();
33
+ <HAI3Provider app={app}>
34
+ <YourApp />
35
+ </HAI3Provider>
36
+ ```
37
+
38
+ ### Available Hooks
39
+
40
+ #### useHAI3
41
+
42
+ Access the HAI3 app instance:
43
+
44
+ ```tsx
45
+ import { useHAI3 } from '@hai3/react';
46
+
47
+ function MyComponent() {
48
+ const app = useHAI3();
49
+ const screensets = app.screensetRegistry.getAll();
50
+ }
51
+ ```
52
+
53
+ #### useAppDispatch / useAppSelector
54
+
55
+ Type-safe Redux hooks:
56
+
57
+ ```tsx
58
+ import { useAppDispatch, useAppSelector } from '@hai3/react';
59
+ import { selectActiveScreen } from '@hai3/react';
60
+
61
+ function MyComponent() {
62
+ const dispatch = useAppDispatch();
63
+ const activeScreen = useAppSelector(selectActiveScreen);
64
+ }
65
+ ```
66
+
67
+ #### useTranslation
68
+
69
+ Access translation utilities:
70
+
71
+ ```tsx
72
+ import { useTranslation } from '@hai3/react';
73
+
74
+ function MyComponent() {
75
+ const { t, language, setLanguage, isRTL } = useTranslation();
76
+
77
+ return (
78
+ <div dir={isRTL ? 'rtl' : 'ltr'}>
79
+ <h1>{t('common:title')}</h1>
80
+ <p>{t('common:welcome', { name: 'John' })}</p>
81
+ </div>
82
+ );
83
+ }
84
+ ```
85
+
86
+ #### useScreenTranslations
87
+
88
+ Load screen-level translations:
89
+
90
+ ```tsx
91
+ import { useScreenTranslations } from '@hai3/react';
92
+
93
+ const translations = {
94
+ en: () => import('./i18n/en.json'),
95
+ es: () => import('./i18n/es.json'),
96
+ };
97
+
98
+ function HomeScreen() {
99
+ const { isLoaded, error } = useScreenTranslations('demo', 'home', translations);
100
+
101
+ if (!isLoaded) return <Loading />;
102
+ if (error) return <Error error={error} />;
103
+
104
+ return <div>...</div>;
105
+ }
106
+ ```
107
+
108
+ #### useNavigation
109
+
110
+ Navigate between screens:
111
+
112
+ ```tsx
113
+ import { useNavigation } from '@hai3/react';
114
+
115
+ function MyComponent() {
116
+ const { navigateToScreen, navigateToScreenset, currentScreen } = useNavigation();
117
+
118
+ return (
119
+ <button onClick={() => navigateToScreen('demo', 'home')}>
120
+ Go to Home
121
+ </button>
122
+ );
123
+ }
124
+ ```
125
+
126
+ #### useTheme
127
+
128
+ Access theme utilities:
129
+
130
+ ```tsx
131
+ import { useTheme } from '@hai3/react';
132
+
133
+ function ThemeToggle() {
134
+ const { currentTheme, themes, setTheme } = useTheme();
135
+
136
+ return (
137
+ <select value={currentTheme} onChange={(e) => setTheme(e.target.value)}>
138
+ {themes.map((theme) => (
139
+ <option key={theme.id} value={theme.id}>{theme.name}</option>
140
+ ))}
141
+ </select>
142
+ );
143
+ }
144
+ ```
145
+
146
+ ### Components
147
+
148
+ #### TextLoader
149
+
150
+ Prevents flash of untranslated content:
151
+
152
+ ```tsx
153
+ import { TextLoader } from '@hai3/react';
154
+
155
+ function Screen() {
156
+ return (
157
+ <TextLoader fallback={<Loading />}>
158
+ <h1>{t('screen.demo.home:title')}</h1>
159
+ </TextLoader>
160
+ );
161
+ }
162
+ ```
163
+
164
+ #### AppRouter
165
+
166
+ Renders screens with lazy loading:
167
+
168
+ ```tsx
169
+ import { AppRouter } from '@hai3/react';
170
+
171
+ function App() {
172
+ return (
173
+ <HAI3Provider>
174
+ <Layout>
175
+ <AppRouter
176
+ fallback={<Loading />}
177
+ errorFallback={(error) => <Error error={error} />}
178
+ />
179
+ </Layout>
180
+ </HAI3Provider>
181
+ );
182
+ }
183
+ ```
184
+
185
+ ## Key Rules
186
+
187
+ 1. **Wrap with HAI3Provider** - Required for all hooks to work
188
+ 2. **Use hooks for state access** - Don't import selectors directly from @hai3/layout
189
+ 3. **Lazy load translations** - Use `useScreenTranslations` for screen-level i18n
190
+ 4. **Use TextLoader** - Wrap translated content to prevent FOUC
191
+ 5. **NO Layout components here** - Layout is in @hai3/uikit or user code
192
+
193
+ ## Re-exports
194
+
195
+ For convenience, this package re-exports everything from @hai3/framework:
196
+
197
+ - All SDK primitives (eventBus, createStore, etc.)
198
+ - All plugins (screensets, themes, layout, etc.)
199
+ - All registries and factory functions
200
+ - All selectors from @hai3/layout
201
+ - All types
202
+
203
+ This allows users to import everything from `@hai3/react` without needing `@hai3/framework` directly.
204
+
205
+ ## Exports
206
+
207
+ ### Components
208
+ - `HAI3Provider` - Main context provider
209
+ - `AppRouter` - Screen router
210
+ - `TextLoader` - Translation loading wrapper
211
+
212
+ ### Hooks
213
+ - `useHAI3` - Access app instance
214
+ - `useAppDispatch` - Typed dispatch
215
+ - `useAppSelector` - Typed selector
216
+ - `useTranslation` - Translation utilities
217
+ - `useScreenTranslations` - Screen translation loading
218
+ - `useNavigation` - Navigation utilities
219
+ - `useTheme` - Theme utilities
220
+
221
+ ### Context
222
+ - `HAI3Context` - React context (for advanced use)
223
+
224
+ ### Types
225
+ - `HAI3ProviderProps`, `AppRouterProps`, `TextLoaderProps`
226
+ - `UseTranslationReturn`, `UseNavigationReturn`, `UseThemeReturn`
227
+ - All types from @hai3/framework
@@ -0,0 +1,58 @@
1
+ <!-- @standalone -->
2
+ # hai3: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
+ hai3 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 `hai3 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).
@@ -0,0 +1,76 @@
1
+ <!-- @standalone -->
2
+ # hai3:new-component - Add New UI Component
3
+
4
+ ## AI WORKFLOW (REQUIRED)
5
+ 1) Check if @hai3/uikit has equivalent component first.
6
+ 2) Gather requirements from user.
7
+ 3) Determine type: screenset composite (default) | screenset base (rare).
8
+ 4) Create OpenSpec proposal for approval.
9
+ 5) After approval, apply implementation.
10
+
11
+ ## CHECK GLOBAL UIKIT FIRST
12
+ - REQUIRED: Before creating screenset component, verify @hai3/uikit lacks equivalent.
13
+ - REQUIRED: Import from @hai3/uikit if component exists there.
14
+
15
+ ## GATHER REQUIREMENTS
16
+ Ask user for:
17
+ - Component name (e.g., "DataTable", "ColorPicker").
18
+ - Component type: screenset composite (default) | screenset base (rare).
19
+ - Component description and props.
20
+ - If screenset base: justification why composite is insufficient.
21
+
22
+ ## IF SCREENSET COMPONENT
23
+
24
+ ### STEP 0: Determine Subfolder
25
+ - uikit/composite/: Screenset-specific composites (theme tokens only).
26
+ - uikit/base/: Rare primitives needing inline styles (needs strong justification).
27
+
28
+ ### STEP 1: Create OpenSpec Proposal
29
+ Create openspec/changes/add-{screenset}-{component}/ with:
30
+
31
+ #### proposal.md
32
+ - Summary: Add new screenset-specific component to {screenset}.
33
+ - Details: Screenset, component name, placement (base/composite), description, props.
34
+ - Justification (if base/): Why global uikit insufficient, why composite insufficient.
35
+ - Implementation: HAI3 patterns (no Redux, no business logic).
36
+
37
+ #### tasks.md
38
+ - Create component file in uikit/{base|composite}/.
39
+ - Implement props interface.
40
+ - Add theme token styling (or inline for base/).
41
+ - Export from local index if needed.
42
+ - Validate: npm run arch:check.
43
+ - Test in UI.
44
+
45
+ ### STEP 2: Wait for Approval
46
+ Tell user: "Review proposal at openspec/changes/add-{screenset}-{component}/."
47
+ Tell user: "Run /openspec:apply add-{screenset}-{component} to implement."
48
+
49
+ ### STEP 3: Apply Implementation (after approval)
50
+ When user runs /openspec:apply:
51
+
52
+ #### 3.1 Create Component
53
+ File: src/screensets/{screenset}/uikit/{base|composite}/{ComponentName}.tsx
54
+ - composite/: Use theme tokens only (no inline styles).
55
+ - base/: May use inline styles (rare, needs justification).
56
+ - Must be reusable within the screenset.
57
+ - NO @hai3/uicore imports (except types).
58
+ - NO Redux or state management.
59
+ - Accept value/onChange pattern for state.
60
+
61
+ #### 3.2 Export
62
+ Export from local index if needed.
63
+
64
+ #### 3.3 Validation
65
+ Run: npm run arch:check && npm run dev
66
+ Test component in UI.
67
+
68
+ #### 3.4 Mark Tasks Complete
69
+ Update tasks.md to mark all completed tasks.
70
+
71
+ ## RULES
72
+ - REQUIRED: Check @hai3/uikit first; screenset uikit only if missing.
73
+ - REQUIRED: Screenset base components need strong justification.
74
+ - FORBIDDEN: Redux, business logic, side effects in components.
75
+ - FORBIDDEN: Inline styles outside uikit/base/.
76
+ - REQUIRED: Accept value/onChange pattern for state.
@@ -0,0 +1,81 @@
1
+ <!-- @standalone -->
2
+ # hai3:new-screen - Add New Screen
3
+
4
+ ## PREREQUISITES (CRITICAL - STOP IF FAILED)
5
+ FORBIDDEN: Proceeding without proposal.
6
+ FORBIDDEN: Creating screen manually without OpenSpec workflow.
7
+
8
+ ## AI WORKFLOW (REQUIRED)
9
+ 1) Read .ai/targets/SCREENSETS.md and .ai/targets/EVENTS.md before starting.
10
+ 2) Gather requirements from user (including UI sections).
11
+ 3) Create OpenSpec proposal via `.claude/commands/openspec-proposal.md` (REQUIRED).
12
+ 4) After approval, implement via `.claude/commands/openspec-apply.md` (REQUIRED).
13
+
14
+ ## GATHER REQUIREMENTS
15
+ Ask user for:
16
+ - Screenset path (e.g., src/screensets/chat).
17
+ - Screen name (camelCase).
18
+ - UI sections (e.g., "header, form, data table").
19
+ - Add to menu? (Y/N)
20
+
21
+ ## STEP 1: Create OpenSpec Proposal (REQUIRED)
22
+ Execute openspec:proposal command (see `.claude/commands/openspec-proposal.md`).
23
+ Proposal name: `add-{screenset}-{screen}`
24
+
25
+ ### proposal.md content
26
+ ```
27
+ # Proposal: Add {ScreenName} Screen
28
+
29
+ ## Summary
30
+ Add new screen "{screenName}" to {screenset} screenset.
31
+
32
+ ## Details
33
+ - Screenset: {screenset}
34
+ - Screen name: {screenName}
35
+ - Add to menu: {Y/N}
36
+
37
+ ## Component Plan
38
+ - REQUIRED: Use @hai3/uikit components first; local uikit only if missing.
39
+ - uikit/base/: rare primitives (inline styles allowed, needs justification)
40
+ - uikit/composite/: screenset composites (theme tokens only)
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
46
+ ```
47
+
48
+ ### tasks.md minimum required tasks
49
+ NOTE: Proposal may include additional tasks, but MUST include these:
50
+ ```
51
+ - [ ] Add screen ID to ids.ts
52
+ - [ ] Create components per Component Plan (BEFORE screen file)
53
+ - [ ] Create screen (orchestrates components, follows EVENTS.md data flow)
54
+ - [ ] Add i18n files for all languages
55
+ - [ ] Add to menu (if requested)
56
+ - [ ] Validate: `npm run type-check && npm run lint`
57
+ - [ ] Test via Chrome DevTools MCP
58
+ ```
59
+
60
+ ## STEP 2: Wait for Approval
61
+ Tell user: "Review proposal at `openspec/changes/add-{screenset}-{screen}/`."
62
+ Tell user: "Execute openspec:apply command to implement."
63
+
64
+ ## STEP 3: Implementation (via openspec:apply)
65
+ BEFORE executing openspec:apply, verify tasks.md contains all minimum required tasks above.
66
+ Execute openspec:apply command (see `.claude/commands/openspec-apply.md`).
67
+ Follow tasks.md strictly:
68
+ 1) Add screen ID to ids.ts.
69
+ 2) Create components BEFORE screen file per Component Plan.
70
+ 3) Create screen following data flow rules from .ai/targets/EVENTS.md:
71
+ - Use actions to trigger state changes
72
+ - FORBIDDEN: Direct slice dispatch from screen
73
+ 4) Add i18n with useScreenTranslations(). Export default.
74
+ 5) Add to menu if requested.
75
+ 6) Validate: `npm run type-check && npm run lint`.
76
+ 7) Test via Chrome DevTools MCP (REQUIRED):
77
+ - Navigate to new screen
78
+ - Verify screen renders without console errors
79
+ - Test UI interactions and data flow
80
+ - Verify translations load correctly
81
+ - STOP if MCP connection fails
@@ -0,0 +1,85 @@
1
+ <!-- @standalone -->
2
+ # hai3:new-screenset - Create New Screenset
3
+
4
+ ## PREREQUISITES (CRITICAL - STOP IF FAILED)
5
+ Run `hai3 --version`.
6
+ STOP: If fails, tell user to install.
7
+ FORBIDDEN: Proceeding without CLI tools.
8
+ FORBIDDEN: Creating screenset manually or by copying peers.
9
+
10
+ ## AI WORKFLOW (REQUIRED)
11
+ 1) Check prerequisites above.
12
+ 2) Read .ai/targets/SCREENSETS.md and .ai/targets/EVENTS.md before starting.
13
+ 3) Gather requirements from user (including UI sections).
14
+ 4) Create OpenSpec proposal via `.claude/commands/openspec-proposal.md` (REQUIRED).
15
+ 5) After approval, implement via `.claude/commands/openspec-apply.md` (REQUIRED).
16
+
17
+ ## GATHER REQUIREMENTS
18
+ Ask user for:
19
+ - Screenset name (camelCase).
20
+ - Category: Drafts | Mockups | Production.
21
+ - Initial screens.
22
+ - UI sections per screen (e.g., "stats cards, charts, activity feed").
23
+
24
+ ## STEP 1: Create OpenSpec Proposal (REQUIRED)
25
+ Execute openspec:proposal command (see `.claude/commands/openspec-proposal.md`).
26
+ Proposal name: `add-{screenset-name}`
27
+
28
+ ### proposal.md content
29
+ ```
30
+ # Proposal: Add {ScreensetName} Screenset
31
+
32
+ ## Summary
33
+ Add new {category} screenset "{screensetName}" with {screens} screen(s).
34
+
35
+ ## Details
36
+ - Name: {screensetName}
37
+ - Category: {category}
38
+ - Initial screens: {screens}
39
+
40
+ ## Component Plan
41
+ - REQUIRED: Use @hai3/uikit components first; local uikit only if missing.
42
+ - uikit/base/: rare primitives (inline styles allowed, needs justification)
43
+ - uikit/composite/: screenset composites (theme tokens only)
44
+ - components/: multi-screen components
45
+ - screens/{screen}/components/: screen-specific components
46
+
47
+ ## Data Flow
48
+ - Events: {domain events per EVENTS.md}
49
+ - State: slices/, events/, effects/, actions/
50
+ - API: api/{Name}ApiService.ts with mocks
51
+ ```
52
+
53
+ ### tasks.md minimum required tasks
54
+ NOTE: Proposal may include additional tasks, but MUST include these:
55
+ ```
56
+ - [ ] Create screenset: `hai3 screenset create {name} --category={category}`
57
+ - [ ] Create components per Component Plan (BEFORE screen file)
58
+ - [ ] Implement data flow per EVENTS.md (actions emit events, effects update slices)
59
+ - [ ] Add API service with mocks
60
+ - [ ] Validate: `npm run type-check && npm run arch:check && npm run lint`
61
+ - [ ] Test via Chrome DevTools MCP
62
+ ```
63
+
64
+ ## STEP 2: Wait for Approval
65
+ Tell user: "Review proposal at `openspec/changes/add-{screenset-name}/`."
66
+ Tell user: "Execute openspec:apply command to implement."
67
+
68
+ ## STEP 3: Implementation (via openspec:apply)
69
+ BEFORE executing openspec:apply, verify tasks.md contains all minimum required tasks above.
70
+ Execute openspec:apply command (see `.claude/commands/openspec-apply.md`).
71
+ Follow tasks.md strictly:
72
+ 1) Create screenset via `hai3 screenset create` (REQUIRED).
73
+ 2) Create components BEFORE screen file per Component Plan.
74
+ 3) Implement data flow per .ai/targets/EVENTS.md:
75
+ - Actions emit events via eventBus.emit()
76
+ - Effects subscribe and update slices
77
+ - FORBIDDEN: Direct slice dispatch from components
78
+ 4) Add API service with mocks.
79
+ 5) Validate: `npm run type-check && npm run arch:check && npm run lint`.
80
+ 6) Test via Chrome DevTools MCP (REQUIRED):
81
+ - Navigate to new screenset
82
+ - Verify screen renders without console errors
83
+ - Test user interactions trigger correct events
84
+ - Verify state updates via Redux DevTools
85
+ - STOP if MCP connection fails