@micha.bigler/ui-core-micha 3.14.4 → 4.0.1
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/CHANGELOG.md +29 -0
- package/README.md +7 -0
- package/dist/chat/kitSxRegistry.js +9 -0
- package/dist/components/charts/kitSxRegistry.js +6 -0
- package/dist/entries/charts.js +6 -0
- package/dist/entries/chat.js +8 -0
- package/dist/entries/markdown.js +1 -0
- package/dist/index.js +0 -14
- package/dist/pages/AccountPage.js +1 -2
- package/dist/pages/LoginPage.js +1 -2
- package/dist/pages/PasswordChangePage.js +1 -2
- package/dist/pages/PasswordInvitePage.js +1 -2
- package/dist/pages/PasswordResetRequestPage.js +1 -2
- package/dist/pages/SignUpPage.js +1 -2
- package/dist/pages/SignupConfirmPage.js +1 -2
- package/dist/theme/kitSxEntry.js +11 -0
- package/dist/theme/kitSxRegistry.js +2 -15
- package/package.json +31 -7
- package/.github/workflows/ci.yml +0 -35
- package/.github/workflows/publish.yml +0 -126
- package/DESIGN.md +0 -60
- package/WORK_ORDERS.md +0 -150
- package/dev/entries.jsx +0 -721
- package/dev/fixtures.js +0 -26
- package/dev/main.jsx +0 -75
- package/dev/mockTransport.jsx +0 -128
- package/docs/CHART-LAYOUT.md +0 -157
- package/docs/DARK-TOKENS.md +0 -140
- package/docs/TYPE-SCALE.md +0 -111
- package/docs/messaging-deviations.md +0 -118
- package/index.html +0 -12
- package/renovate.json +0 -10
- package/scripts/chart-api-census.mjs +0 -415
- package/src/auth/AuthContext.jsx +0 -158
- package/src/auth/ReauthModal.jsx +0 -82
- package/src/auth/UserMenu.jsx +0 -121
- package/src/auth/apiClient.jsx +0 -232
- package/src/auth/authApi.jsx +0 -539
- package/src/auth/authConfig.jsx +0 -34
- package/src/auth/reauth.js +0 -47
- package/src/chat/ChatComposer.jsx +0 -36
- package/src/chat/ChatList.jsx +0 -87
- package/src/chat/ChatThread.jsx +0 -128
- package/src/chat/ChatWorkspace.jsx +0 -244
- package/src/chat/MarkdownReply.jsx +0 -22
- package/src/chat/ModelPicker.jsx +0 -85
- package/src/chat/api.js +0 -18
- package/src/chat/useChatSocket.js +0 -32
- package/src/chat/wire.js +0 -7
- package/src/components/AccessCodeManager.jsx +0 -288
- package/src/components/AccessCodeSingleUseToggle.jsx +0 -92
- package/src/components/AllowedEmailDomainsManager.jsx +0 -92
- package/src/components/AuthFactorRequirementCard.jsx +0 -95
- package/src/components/BulkInviteCsvTab.jsx +0 -198
- package/src/components/EmptyState.jsx +0 -38
- package/src/components/LoginForm.jsx +0 -159
- package/src/components/MFAComponent.jsx +0 -350
- package/src/components/MfaLoginComponent.jsx +0 -252
- package/src/components/MobileBottomNav.jsx +0 -82
- package/src/components/PasskeysComponent.jsx +0 -252
- package/src/components/PasswordChangeForm.jsx +0 -87
- package/src/components/PasswordResetRequestForm.jsx +0 -43
- package/src/components/PasswordSetForm.jsx +0 -97
- package/src/components/ProfileComponent.jsx +0 -348
- package/src/components/QrSignupManager.jsx +0 -404
- package/src/components/QrSignupValidityManager.jsx +0 -106
- package/src/components/RegistrationMethodsManager.jsx +0 -150
- package/src/components/SecurityComponent.jsx +0 -141
- package/src/components/SocialLoginButtons.jsx +0 -83
- package/src/components/SoftChip.jsx +0 -93
- package/src/components/StatTile.jsx +0 -39
- package/src/components/SupportRecoveryRequestsTab.jsx +0 -482
- package/src/components/TurnstileWidget.jsx +0 -99
- package/src/components/UserInviteComponent.jsx +0 -76
- package/src/components/UserListComponent.jsx +0 -618
- package/src/components/charts/BarChart.jsx +0 -102
- package/src/components/charts/ChartFrame.jsx +0 -214
- package/src/components/charts/LineChart.jsx +0 -126
- package/src/components/charts/ScatterChart.jsx +0 -299
- package/src/components/charts/TimeSeriesChart.jsx +0 -300
- package/src/components/charts/chartDefaults.js +0 -644
- package/src/components/charts/chartLabels.js +0 -36
- package/src/components/charts/exportChart.js +0 -258
- package/src/components/charts/formatters.js +0 -39
- package/src/components/charts/palette.js +0 -33
- package/src/components/charts/yearTickInterval.js +0 -7
- package/src/i18n/authTranslations.ts +0 -2651
- package/src/i18n/chartsTranslations.ts +0 -91
- package/src/i18n/chatTranslations.ts +0 -55
- package/src/i18n/messagingTranslations.ts +0 -120
- package/src/i18n/notificationsTranslations.ts +0 -32
- package/src/i18n/onboardingTranslations.ts +0 -29
- package/src/i18n/sectionNavTranslations.ts +0 -20
- package/src/i18n/uiCoreTranslations.js +0 -29
- package/src/i18n/userMenuTranslations.ts +0 -5
- package/src/index.js +0 -158
- package/src/layout/PageLayout.jsx +0 -36
- package/src/layout/SectionNav.jsx +0 -320
- package/src/messaging/AttachmentList.jsx +0 -145
- package/src/messaging/Composer.jsx +0 -197
- package/src/messaging/ConversationLaunchers.jsx +0 -51
- package/src/messaging/ConversationList.jsx +0 -109
- package/src/messaging/DirectMessageLauncher.jsx +0 -112
- package/src/messaging/MessageBubble.jsx +0 -183
- package/src/messaging/MessagingProvider.jsx +0 -0
- package/src/messaging/MessagingScopeConfig.jsx +0 -24
- package/src/messaging/PollCard.jsx +0 -163
- package/src/messaging/ReactionBar.jsx +0 -43
- package/src/messaging/ReadTicks.jsx +0 -82
- package/src/messaging/Thread.jsx +0 -195
- package/src/messaging/api.js +0 -48
- package/src/messaging/composerImageCompression.js +0 -35
- package/src/messaging/linkifyText.jsx +0 -37
- package/src/notifications/NotificationBell.jsx +0 -84
- package/src/notifications/NotificationSettings.jsx +0 -330
- package/src/notifications/NotificationsProvider.jsx +0 -224
- package/src/notifications/PopupSurface.jsx +0 -105
- package/src/notifications/api.js +0 -55
- package/src/notifications/feedApi.js +0 -18
- package/src/notifications/realtime.jsx +0 -138
- package/src/notifications/serviceWorker/sw.js +0 -50
- package/src/onboarding/OnboardingProvider.jsx +0 -326
- package/src/onboarding/OnboardingWizard.jsx +0 -61
- package/src/onboarding/WizardDialogShell.jsx +0 -51
- package/src/onboarding/api.js +0 -13
- package/src/onboarding/stepSelection.js +0 -16
- package/src/onboarding/steps/BrowserPushStep.jsx +0 -121
- package/src/onboarding/steps/CompleteNameStep.jsx +0 -46
- package/src/onboarding/steps/CookieConsentStep.jsx +0 -133
- package/src/onboarding/steps/PwaInstallStep.jsx +0 -47
- package/src/pages/AccountPage.jsx +0 -394
- package/src/pages/LoginPage.jsx +0 -343
- package/src/pages/PasswordChangePage.jsx +0 -62
- package/src/pages/PasswordInvitePage.jsx +0 -177
- package/src/pages/PasswordResetRequestPage.jsx +0 -68
- package/src/pages/SignUpPage.jsx +0 -268
- package/src/pages/SignupConfirmPage.jsx +0 -155
- package/src/testing/checkKitIntegration.js +0 -233
- package/src/theme/createAppTheme.js +0 -423
- package/src/theme/fonts.js +0 -3
- package/src/theme/index.js +0 -21
- package/src/theme/kitSxRegistry.js +0 -285
- package/src/theme/themeCompleteness.js +0 -1045
- package/src/theme/tokens.js +0 -478
- package/src/utils/auth-errors.js +0 -76
- package/src/utils/authService.js +0 -223
- package/src/utils/resolveErrorText.js +0 -28
- package/src/utils/webauthn.js +0 -51
- package/tests/AccountPage.profileStatements.test.jsx +0 -162
- package/tests/AccountPage.test.jsx +0 -200
- package/tests/AuthContext.test.jsx +0 -129
- package/tests/BarChart.test.jsx +0 -112
- package/tests/BrowserPushStep.test.jsx +0 -110
- package/tests/ChartFrame.test.jsx +0 -336
- package/tests/ConversationList.test.jsx +0 -144
- package/tests/CookieConsentStep.test.jsx +0 -69
- package/tests/EmptyState.test.jsx +0 -62
- package/tests/LineChart.test.jsx +0 -80
- package/tests/MessagingProvider.test.jsx +0 -50
- package/tests/MobileBottomNav.test.jsx +0 -319
- package/tests/NotificationBell.test.jsx +0 -60
- package/tests/NotificationSettings.test.jsx +0 -276
- package/tests/NotificationsProvider.test.jsx +0 -240
- package/tests/OnboardingProvider.test.jsx +0 -294
- package/tests/OnboardingWizard.test.jsx +0 -143
- package/tests/PasswordChangeForm.test.jsx +0 -70
- package/tests/PasswordInvitePage.test.jsx +0 -142
- package/tests/PasswordSetForm.test.jsx +0 -70
- package/tests/PopupSurface.test.jsx +0 -142
- package/tests/ProfileComponent.refresh.test.jsx +0 -194
- package/tests/QrSignupManager.registrationContext.test.jsx +0 -106
- package/tests/QrSignupManagerInfoBox.test.jsx +0 -49
- package/tests/ScatterChart.test.jsx +0 -270
- package/tests/SectionNav.test.jsx +0 -363
- package/tests/SignUpPage.test.jsx +0 -208
- package/tests/SoftChip.test.jsx +0 -105
- package/tests/StatTile.test.jsx +0 -57
- package/tests/Thread.test.jsx +0 -151
- package/tests/TimeSeriesChart.test.jsx +0 -367
- package/tests/UserListComponent.test.jsx +0 -192
- package/tests/UserMenu.test.jsx +0 -171
- package/tests/apiClientLanguage.test.js +0 -33
- package/tests/apiClientPublicPaths.test.js +0 -178
- package/tests/authApiLogin.test.js +0 -42
- package/tests/authApiRegistration.test.js +0 -31
- package/tests/authErrorCodeRendering.test.jsx +0 -77
- package/tests/authErrors.test.js +0 -74
- package/tests/authTranslations.test.js +0 -74
- package/tests/chart-api-census.test.js +0 -366
- package/tests/chartAxisTickBand.test.jsx +0 -95
- package/tests/chartDefaults.test.js +0 -902
- package/tests/chartLabels.test.js +0 -50
- package/tests/chartsPalette.test.js +0 -99
- package/tests/chatApi.test.js +0 -48
- package/tests/chatDriverNames.test.jsx +0 -71
- package/tests/chatExports.test.js +0 -3
- package/tests/chatList.test.jsx +0 -84
- package/tests/chatPicker.test.jsx +0 -82
- package/tests/chatSocket.test.jsx +0 -26
- package/tests/chatThread.test.jsx +0 -116
- package/tests/chatTranslations.test.js +0 -47
- package/tests/chatWorkspace.test.jsx +0 -234
- package/tests/checkKitIntegration.test.jsx +0 -219
- package/tests/createAppTheme.test.js +0 -132
- package/tests/createAppThemeDark.test.js +0 -127
- package/tests/createAppThemeLightGuard.test.js +0 -40
- package/tests/createAppThemePageContrast.test.js +0 -108
- package/tests/createAppThemeTypography.test.js +0 -53
- package/tests/errorCallSiteGuard.test.js +0 -32
- package/tests/exportChart.test.js +0 -313
- package/tests/feedApi.test.js +0 -46
- package/tests/fixtures/light-theme-baseline.json +0 -2234
- package/tests/i18nAggregate.test.js +0 -120
- package/tests/i18nGermanVariant.test.js +0 -65
- package/tests/loginPageErrorResolution.test.jsx +0 -102
- package/tests/messagingApi.test.js +0 -32
- package/tests/messagingChunk6.test.jsx +0 -116
- package/tests/messagingCompactBubble.test.jsx +0 -64
- package/tests/messagingComposer.test.jsx +0 -136
- package/tests/messagingComposerChunk5.test.jsx +0 -113
- package/tests/messagingContractConformance.test.js +0 -69
- package/tests/messagingDirectMessageLauncher.test.jsx +0 -151
- package/tests/messagingExports.test.js +0 -21
- package/tests/messagingInteractions.test.jsx +0 -136
- package/tests/messagingLastMessagePreview.test.jsx +0 -93
- package/tests/messagingLinkify.test.jsx +0 -51
- package/tests/messagingMessageActions.test.jsx +0 -163
- package/tests/messagingMsg6.test.jsx +0 -105
- package/tests/messagingMsg6f.test.jsx +0 -155
- package/tests/messagingMsg6g.test.jsx +0 -166
- package/tests/messagingMsg6h.test.jsx +0 -136
- package/tests/messagingMsg6i.test.jsx +0 -129
- package/tests/messagingPollRendering.test.jsx +0 -142
- package/tests/messagingReactionMerge.test.jsx +0 -77
- package/tests/messagingReadTicksTooltip.test.jsx +0 -36
- package/tests/messagingThreadReceipts.test.jsx +0 -178
- package/tests/messagingThreadingQuoting.test.jsx +0 -87
- package/tests/messagingUnreadLifecycle.test.jsx +0 -78
- package/tests/notificationsApi.test.js +0 -41
- package/tests/notificationsExports.test.js +0 -34
- package/tests/onboardingDescriptors.test.js +0 -132
- package/tests/packageTreeShaking.test.js +0 -126
- package/tests/realtime.test.jsx +0 -219
- package/tests/resolveErrorText.test.js +0 -72
- package/tests/stepSelection.test.js +0 -53
- package/tests/themeCompleteness.test.js +0 -626
- package/tests/timeSeriesLegend.test.js +0 -99
- package/tests/userScreenTranslations.test.jsx +0 -218
- package/tsconfig.build.json +0 -18
- package/vite.config.mjs +0 -6
- package/work-orders/AUTH-1.md +0 -74
- package/work-orders/AUTH-2.md +0 -74
- package/work-orders/AUTH-4.md +0 -183
- package/work-orders/AUTH-5.md +0 -154
- package/work-orders/AUTH-7.md +0 -181
- package/work-orders/AUTH-8.md +0 -184
- package/work-orders/CHART-1.md +0 -285
- package/work-orders/CHART-2.md +0 -222
- package/work-orders/CHART-3.md +0 -163
- package/work-orders/CHART-4.md +0 -203
- package/work-orders/CHART-5.md +0 -226
- package/work-orders/CHART-6.md +0 -428
- package/work-orders/CHART-7.md +0 -175
- package/work-orders/DX-1.md +0 -169
- package/work-orders/DX-2.md +0 -188
- package/work-orders/DX-3.md +0 -195
- package/work-orders/I18N-1.md +0 -254
- package/work-orders/I18N-3.md +0 -207
- package/work-orders/MSG-3.md +0 -375
- package/work-orders/MSG-3b.md +0 -1002
- package/work-orders/MSG-3c.md +0 -378
- package/work-orders/MSG-3d.md +0 -268
- package/work-orders/MSG-3e.md +0 -164
- package/work-orders/MSG-3f.md +0 -391
- package/work-orders/MSG-6e.md +0 -308
- package/work-orders/MSG-6f.md +0 -214
- package/work-orders/MSG-6g.md +0 -244
- package/work-orders/MSG-6h.md +0 -238
- package/work-orders/MSG-6i.md +0 -271
- package/work-orders/MSG-6j.md +0 -117
- package/work-orders/NOTIF-12.md +0 -214
- package/work-orders/NOTIF-13.md +0 -142
- package/work-orders/NOTIF-14.md +0 -151
- package/work-orders/PRIM-1.md +0 -177
- package/work-orders/SHELL-1.md +0 -255
- package/work-orders/SHELL-2.md +0 -197
- package/work-orders/SHELL-3.md +0 -359
- package/work-orders/SHELL-4.md +0 -351
- package/work-orders/SHELL-5.md +0 -345
- package/work-orders/SHELL-6.md +0 -210
- package/work-orders/THEME-1.md +0 -587
- package/work-orders/THEME-10.md +0 -303
- package/work-orders/THEME-11.md +0 -208
- package/work-orders/THEME-2.md +0 -339
- package/work-orders/THEME-3.md +0 -210
- package/work-orders/THEME-4.md +0 -271
- package/work-orders/THEME-5.md +0 -341
- package/work-orders/THEME-6.md +0 -247
- package/work-orders/THEME-7.md +0 -82
- package/work-orders/THEME-8.md +0 -211
- package/work-orders/THEME-9.md +0 -194
- package/work-orders/UCM-AUTH-10.md +0 -490
- package/work-orders/UCM-AUTH-11.md +0 -185
- package/work-orders/UCM-AUTH-12.md +0 -98
- package/work-orders/UCM-AUTH-13.md +0 -47
- package/work-orders/UCM-AUTH-9.md +0 -207
- package/work-orders/UCM-CHART-10.md +0 -150
- package/work-orders/UCM-CHART-11.md +0 -132
- package/work-orders/UCM-CHART-12.md +0 -348
- package/work-orders/UCM-CHART-13.md +0 -122
- package/work-orders/UCM-CHART-14.md +0 -198
- package/work-orders/UCM-CHART-15.md +0 -187
- package/work-orders/UCM-CHART-16.md +0 -169
- package/work-orders/UCM-CHART-17.md +0 -195
- package/work-orders/UCM-CHART-18.md +0 -200
- package/work-orders/UCM-CHART-8.md +0 -147
- package/work-orders/UCM-CHART-9.md +0 -265
- package/work-orders/UCM-CHAT-1.md +0 -190
- package/work-orders/UCM-CHAT-2.md +0 -75
- package/work-orders/UCM-CI-1.md +0 -65
- package/work-orders/UCM-DEP-1.md +0 -63
- package/work-orders/UCM-I18N-4.md +0 -226
- package/work-orders/UCM-I18N-5.md +0 -211
- package/work-orders/UCM-MSG-20.md +0 -192
- package/work-orders/UCM-PRIM-2.md +0 -114
- package/work-orders/UCM-SHELL-7.md +0 -134
- package/work-orders/UCM-SHELL-8.md +0 -125
- package/work-orders/UCM-TEST-1.md +0 -304
- package/work-orders/UCM-THEME-13.md +0 -69
- package/work-orders/UCM-THEME-14.md +0 -312
- package/work-orders/UCM-THEME-15.md +0 -356
- package/work-orders/UCM-THEME-16.md +0 -80
- package/work-orders/UCM-THEME-17.md +0 -111
- package/work-orders/UCM-THEME-18.md +0 -184
- package/work-orders/assets/AUTH-4-user-list-card.html +0 -407
- package/work-orders/assets/PRIM-1-dashboard-primitives.html +0 -624
- package/work-orders/assets/SHELL-2-account-navigation.html +0 -1159
- package/work-orders/assets/THEME-1-baseline-reference-sheet.html +0 -1352
- package/work-orders/assets/UCM-CHAT-1-ai-chat.html +0 -447
- package/work-orders/assets/UCM-THEME-13-dark-prototype.html +0 -390
- package/work-orders/assets/UCM-THEME-17-type-scale.html +0 -391
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# UCM-CHAT-2 — Readable driver names in the chat model picker
|
|
2
|
-
|
|
3
|
-
Prepared: 2026-10-15. Target repository: `ui-core-micha` (`main`). Correction to `UCM-CHAT-1`, found at acceptance.
|
|
4
|
-
|
|
5
|
-
# A. Envelope — addressed to everyone
|
|
6
|
-
|
|
7
|
-
## Goal and expected outcome
|
|
8
|
-
|
|
9
|
-
The model picker of the shared chat surface groups its entries by driver. In the UCM-CHAT-1 implementation, each group heading shows the raw driver id the catalogue returns (`claude_cli`, `anthropic_api`, `openai_api`). The prototype `work-orders/assets/UCM-CHAT-1-ai-chat.html` shows readable names instead.
|
|
10
|
-
|
|
11
|
-
Expected outcome: the three drivers that `django-core-micha/DCM-CHAT-1` ships appear under readable, translated names, both in the picker and wherever else ui-core-micha shows a driver. An unknown driver id still appears as its raw id, so a driver added later (`django-core-micha/DCM-CHAT-2`) stays usable before it gets a name.
|
|
12
|
-
|
|
13
|
-
## Scope
|
|
14
|
-
|
|
15
|
-
- A mapping from the three driver ids to translated names, registered in ui-core-micha's chat translations:
|
|
16
|
-
|
|
17
|
-
| Driver id | en | de | fr | sw |
|
|
18
|
-
|---|---|---|---|---|
|
|
19
|
-
| `claude_cli` | Claude Code subscription | Claude Code (Abo) | Claude Code (abonnement) | Claude Code (usajili) |
|
|
20
|
-
| `anthropic_api` | Anthropic API | Anthropic API | API Anthropic | API ya Anthropic |
|
|
21
|
-
| `openai_api` | OpenAI API | OpenAI API | API OpenAI | API ya OpenAI |
|
|
22
|
-
|
|
23
|
-
- The picker's group heading and the group's accessible name use the translated name.
|
|
24
|
-
- Any other place in the chat surface that shows a driver uses the same name. One example is the model-change divider in the thread.
|
|
25
|
-
- Unknown driver ids fall back to the raw id.
|
|
26
|
-
|
|
27
|
-
## Copy list (released with this Envelope)
|
|
28
|
-
|
|
29
|
-
The twelve names in the table above, verbatim. No other new text.
|
|
30
|
-
|
|
31
|
-
## Non-goals
|
|
32
|
-
|
|
33
|
-
- Any change to the catalogue contract or to django-core-micha. The names live in ui-core-micha.
|
|
34
|
-
- Other picker behaviour, layout or styling.
|
|
35
|
-
- The post-landing re-review of UCM-CHAT-1's last fix batch. That is UCM-CHAT-1's own follow-up.
|
|
36
|
-
|
|
37
|
-
## Tier
|
|
38
|
-
|
|
39
|
-
Tier 3: a change inside shared-core. Small and copy-only in effect.
|
|
40
|
-
|
|
41
|
-
## Risks
|
|
42
|
-
|
|
43
|
-
- **Id mismatch:** the ids must match exactly what DCM-CHAT-1 returns (`django_core_micha/assistant/catalogue.py`, `DRIVERS`). A mismatch silently falls back to raw ids. The existing picker test fixture uses `openai`, which is not a real driver id.
|
|
44
|
-
|
|
45
|
-
## Required tests to write
|
|
46
|
-
|
|
47
|
-
- Picker: groups for `claude_cli`, `anthropic_api` and `openai_api` show their translated names as heading and accessible name. Fixtures use the real driver ids.
|
|
48
|
-
- Unknown driver: an entry with an unknown driver id is grouped under its raw id.
|
|
49
|
-
- Translations: the three new keys exist in all four languages.
|
|
50
|
-
|
|
51
|
-
# B. Implementation map — addressed to the implementer
|
|
52
|
-
|
|
53
|
-
## Context package
|
|
54
|
-
|
|
55
|
-
Tier 3 · tests: picker + translations (see Part A). Work from this package; do not explore broadly. Target working directory: `C:/Users/Micha Bigler/Documents/webapps/ui-core-micha` (never the workspace root).
|
|
56
|
-
|
|
57
|
-
- `src/chat/ModelPicker.jsx` — `groupByDriver` groups `entries` by `entry.driver`; the group is rendered at about line 38 as `<Box key={driver} role="group" aria-label={driver}>` with `<Typography variant="overline">{driver}</Typography>`. Both the accessible name and the heading must show the translated name. `t` comes from `useTranslation()` already in the file.
|
|
58
|
-
- `src/i18n/chatTranslations.ts` — one `chatTranslations` const, entries `'Chat.xxx': { de, en, fr, sw }`. Add exactly three keys, flat like the existing `Chat.effort.low`: `Chat.driver.claude_cli`, `Chat.driver.anthropic_api`, `Chat.driver.openai_api`, with the Envelope's twelve names verbatim (en/de/fr/sw columns). No other new text.
|
|
59
|
-
- A small helper keeps the lookup in one place: export `driverName(t, id)` from `src/chat/ModelPicker.jsx` (or a new `src/chat/driverName.js` if cleaner) returning `t(`Chat.driver.${id}`, { defaultValue: id })`, so an unknown id falls back to the raw id with real i18next. Use it in the picker. The thread's model-change divider (`src/chat/ChatThread.jsx`, `selectionLine`) shows only model and effort, no driver; leave it unchanged. No other place in `src/chat/**` renders a driver id (verify with a search for `driver`).
|
|
60
|
-
- Tests: `tests/chatPicker.test.jsx` mocks `react-i18next` with `t: (key) => key`; make the mock return `values.defaultValue` when the key starts with `Chat.driver.` and a `defaultValue` is given and the id is not one of the three known ids, and the key otherwise, so every other assertion keeps expecting keys. Update the fixture entries to the real ids `claude_cli`, `anthropic_api` (replace the fake `openai`), keep one extra fixture with an unknown id (for example `mystery_driver`). Assert: group role name and heading text for each known driver equal the translation KEY `Chat.driver.<id>` (the mocked t returns keys); the unknown id group is named by the raw id. Also assert with the REAL `chatTranslations` that the three keys exist with the Envelope's exact English names, and that each key is non-empty in de/en/fr/sw (add to `tests/chatTranslations.test.js`). `tests/chatWorkspace.test.jsx` uses `openai`/`claude_cli` ids in its catalogue fixture and finds the group by name `openai`: update that lookup to the new key-based name.
|
|
61
|
-
- Do not edit: `package.json`, lockfile, CHANGELOG, README, `WORK_ORDERS.md`, anything outside `src/chat/**`, `src/i18n/chatTranslations.ts`, `tests/chat*.test.*`. No catalogue contract change.
|
|
62
|
-
- Pitfall: the existing aggregate test `tests/i18nAggregate.test.js` iterates all bundle keys; every value needs all four locales as non-empty strings.
|
|
63
|
-
|
|
64
|
-
## Preamble
|
|
65
|
-
|
|
66
|
-
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies, touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT `git add`/`commit`/`push` — leave every change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review). The orchestrator re-runs the authoritative set + does the independent review after you finish — those are the gate; your own run does not count as the gate.
|
|
67
|
-
>
|
|
68
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final `RESULT: DONE|BLOCKED <reason>`.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# C. Orchestrator only — not addressed to the implementer
|
|
72
|
-
|
|
73
|
-
> **If this WO was dispatched to you as an implementer: STOP here.**
|
|
74
|
-
|
|
75
|
-
Gate #1 open until recorded in the register row. Publish as a patch release; cockpit/CP-CHAT-4 pins the release that contains it.
|
package/work-orders/UCM-CI-1.md
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# UCM-CI-1 — A dispatch-only CI workflow for ui-core-micha
|
|
2
|
-
|
|
3
|
-
Prepared: 2026-10-15. Target repository: `ui-core-micha` (`main`).
|
|
4
|
-
|
|
5
|
-
# A. Envelope — addressed to everyone
|
|
6
|
-
|
|
7
|
-
## Goal and expected outcome
|
|
8
|
-
|
|
9
|
-
ui-core-micha has one workflow, `publish.yml`, which tests and then publishes on a push to `main`. A change cannot be proven on a candidate ref without publishing, so work such as `UCM-DEP-1` has no safe CI run. This order adds `.github/workflows/ci.yml`: install, build and test on Linux, started only by hand (`workflow_dispatch`), with no publish step and no secrets.
|
|
10
|
-
|
|
11
|
-
Expected outcome: `gh workflow run ci.yml -R <owner>/ui-core-micha --ref ci-test/<ID>` runs the same install, build and test steps as `publish.yml` against that ref, and nothing else.
|
|
12
|
-
|
|
13
|
-
## Operator decision this Envelope records (2026-10-15)
|
|
14
|
-
|
|
15
|
-
The operator asked for this workflow in session, as the way to verify `UCM-DEP-1`: "Lege für ui-core-micha einen kleinen ci.yml (nur install, build, test, workflow_dispatch) als eigenes Register-Item an und nutze ihn für UCM-DEP-1."
|
|
16
|
-
|
|
17
|
-
## Scope
|
|
18
|
-
|
|
19
|
-
- One new file `.github/workflows/ci.yml`:
|
|
20
|
-
- trigger: `workflow_dispatch` only;
|
|
21
|
-
- `permissions: contents: read`;
|
|
22
|
-
- one job on `ubuntu-latest` with the steps of `publish.yml` that precede publishing, using the same action versions and the same Node and pnpm versions as `publish.yml`: checkout, setup-node, setup-pnpm, `pnpm install --frozen-lockfile`, `pnpm run build`, `pnpm run test`;
|
|
23
|
-
- no `npm publish`, no `id-token` permission, no secrets, no `registry-url`.
|
|
24
|
-
- A register row and the `CI-*` prefix in `WORK_ORDERS.md` (Orchestrator).
|
|
25
|
-
|
|
26
|
-
## Non-goals
|
|
27
|
-
|
|
28
|
-
- No change to `publish.yml`, to any test, or to the package.
|
|
29
|
-
- No push or pull-request trigger: the workflow runs only when dispatched.
|
|
30
|
-
- No matrix, cache tuning or extra jobs.
|
|
31
|
-
|
|
32
|
-
## Tier
|
|
33
|
-
|
|
34
|
-
Tier 3: CI. Small in effect.
|
|
35
|
-
|
|
36
|
-
## Risks
|
|
37
|
-
|
|
38
|
-
- A `workflow_dispatch` workflow must exist on the default branch before it can be dispatched at a ref; it lands on `main` first and is then used from `ci-test/<ID>` refs.
|
|
39
|
-
- The Node and pnpm pins duplicate those of `publish.yml`; `UCM-DEP-1` bumps both.
|
|
40
|
-
|
|
41
|
-
## Required tests to write
|
|
42
|
-
|
|
43
|
-
None: the evidence is one dispatched run of the new workflow on a `ci-test/UCM-CI-1` ref.
|
|
44
|
-
|
|
45
|
-
# B. Implementation map — addressed to the implementer
|
|
46
|
-
|
|
47
|
-
## Context package
|
|
48
|
-
|
|
49
|
-
Work from this package; do not explore broadly. Target working directory: `C:/Users/Micha Bigler/Documents/webapps/ui-core-micha`.
|
|
50
|
-
|
|
51
|
-
- Read `.github/workflows/publish.yml` once. Copy, verbatim, the `uses:` pins and versions of its checkout, setup-node (`node-version`) and pnpm/action-setup (`version`) steps. Do not copy the version-check script, the `if:` conditions, the npm update or the publish step.
|
|
52
|
-
- Create `.github/workflows/ci.yml`: `name: CI`; `on: workflow_dispatch`; top-level `permissions: contents: read`; one job `test` on `ubuntu-latest` with steps: Check out code, Set up Node, Set up pnpm, Install dependencies (`pnpm install --frozen-lockfile`), Build (`pnpm run build`), Run tests (`pnpm run test`). Same indentation and step-name style as `publish.yml`.
|
|
53
|
-
- Do not edit anything else.
|
|
54
|
-
|
|
55
|
-
## Preamble
|
|
56
|
-
|
|
57
|
-
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies, touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT `git add`/`commit`/`push` — leave every change uncommitted in the working tree for the orchestrator's independent review. This order needs no tests; run none. The orchestrator does the independent review and the dispatched run after you finish.
|
|
58
|
-
>
|
|
59
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final `RESULT: DONE|BLOCKED <reason>`.
|
|
60
|
-
|
|
61
|
-
# C. Orchestrator only — not addressed to the implementer
|
|
62
|
-
|
|
63
|
-
> **If this WO was dispatched to you as an implementer: STOP here.**
|
|
64
|
-
|
|
65
|
-
Gate #1: the operator's instruction of 2026-10-15 in the UCM-CHAT-1/2 Orchestrator session (quoted in Part A). Review lenses per Tier 3 for a workflow file (envelope, regression, duplication, tests do not apply: no tests; sec_reviewer on the permissions block). Evidence: a dispatched run on `ci-test/UCM-CI-1` after the file is on `main`.
|
package/work-orders/UCM-DEP-1.md
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# UCM-DEP-1 — All open Renovate updates in one change on main, one CI run
|
|
2
|
-
|
|
3
|
-
Prepared: 2026-10-15. Target repository: `ui-core-micha` (`main`).
|
|
4
|
-
|
|
5
|
-
# A. Envelope — addressed to everyone
|
|
6
|
-
|
|
7
|
-
## Goal and expected outcome
|
|
8
|
-
|
|
9
|
-
ui-core-micha's eight open Renovate PRs land as one change on `main`, verified by one CI run. A release follows only if a runtime dependency changed; tooling-only updates need none.
|
|
10
|
-
|
|
11
|
-
## Tier
|
|
12
|
-
|
|
13
|
-
Tier 3: dependency changes, majors included.
|
|
14
|
-
|
|
15
|
-
## Operator decisions this Envelope records (2026-10-15)
|
|
16
|
-
|
|
17
|
-
1. The bundle contains these open Renovate PRs' updates, in one change on `main`:
|
|
18
|
-
|
|
19
|
-
| PR | Update |
|
|
20
|
-
|---|---|
|
|
21
|
-
| #17 | npm non-major |
|
|
22
|
-
| #18 | github-actions |
|
|
23
|
-
| #19 | actions/checkout v7 |
|
|
24
|
-
| #20 | actions/setup-node v7 |
|
|
25
|
-
| #21 | jsdom v30 (test) |
|
|
26
|
-
| #22 | pnpm v12 |
|
|
27
|
-
| #23 | typescript v7 |
|
|
28
|
-
| #24 | vitest v5 (test) |
|
|
29
|
-
|
|
30
|
-
2. A major that needs more than small adaptations (configuration, a renamed import, a test helper) is taken out of the bundle, left as its PR, and reported with the reason. The bundle does not grow into a migration.
|
|
31
|
-
3. Verification is one CI run of the repository's own CI on the candidate (for an app: a `ci-test/<ID>` ref with the full job set). A red job is fixed within decision 2 and the run repeated; not more than that.
|
|
32
|
-
4. After the push Renovate closes the PRs whose update landed; a PR it rebases instead is an update that did not land and is reported.
|
|
33
|
-
|
|
34
|
-
## Scope
|
|
35
|
-
|
|
36
|
-
1. Dependency manifests and lockfiles, workflow `uses:` pins, image pins the updates touch.
|
|
37
|
-
2. The small adaptations decision 2 allows, with tests where behaviour is touched.
|
|
38
|
-
3. Each update's changelog read for breaking changes before it goes in; a breaking change the code meets is adapted (decision 2) or the update is taken out.
|
|
39
|
-
4. A release per the repository's own publish procedure only when the published package's runtime dependencies changed.
|
|
40
|
-
|
|
41
|
-
## Non-goals
|
|
42
|
-
|
|
43
|
-
- No new features, no refactoring beyond decision 2.
|
|
44
|
-
- No change to the Renovate configuration.
|
|
45
|
-
- No pin bump in any consuming app.
|
|
46
|
-
|
|
47
|
-
## Risks
|
|
48
|
-
|
|
49
|
-
- pnpm 12 and TypeScript 7 change the build toolchain; the published bundle must stay byte-compatible in its exports. The CI's build and the kit's own tests are the check.
|
|
50
|
-
|
|
51
|
-
## Required tests to write
|
|
52
|
-
|
|
53
|
-
None beyond the adaptations of decision 2. The evidence is the CI run of decision 3.
|
|
54
|
-
|
|
55
|
-
# B. Implementation map — addressed to the implementer
|
|
56
|
-
|
|
57
|
-
*To be filled by the Orchestrator.*
|
|
58
|
-
|
|
59
|
-
# C. Orchestrator only — not addressed to the implementer
|
|
60
|
-
|
|
61
|
-
> **If this WO was dispatched to you as an implementer: STOP here.**
|
|
62
|
-
|
|
63
|
-
Gate #1 open until recorded in the register row. Part of the PR close-out round of 2026-10-15; stagger the CI run with the other bundles of that round (one heavy run at a time on the shared runner). On 2026-10-15 the working tree carried another session's uncommitted changes to `package.json` and `pnpm-lock.yaml` (likely the dcm/ucm chat migration): the same files this bundle changes. Sequence with that session before starting; never fold its changes into this commit.
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
# UCM-I18N-4 — Let a consumer choose informal German, and translate the hard-coded English in the auth and user screens
|
|
2
|
-
|
|
3
|
-
# A. Envelope — authored by the Expertenchat
|
|
4
|
-
|
|
5
|
-
## Goal & expected outcome
|
|
6
|
-
|
|
7
|
-
- Goal: an app that addresses its users with "du" gets "du" in every ucm screen, and no ucm screen
|
|
8
|
-
shows hard-coded English in a German UI.
|
|
9
|
-
- Expected outcome:
|
|
10
|
-
- The kit's German strings exist in a formal ("Sie", today's default) and an informal ("du")
|
|
11
|
-
variant; a consumer picks one when it registers the kit's strings (the single export from
|
|
12
|
-
`I18N-1`). Apps that do nothing keep today's formal German.
|
|
13
|
-
- `UserListComponent`, the invite panel (`UserInviteComponent`, `BulkInviteCsvTab`) and their
|
|
14
|
-
messages use translation keys for every visible string, in all configured locales.
|
|
15
|
-
|
|
16
|
-
## Context — measured 2026-09-29 in jg-ferien's local browser test (ucm 3.5.0 installed there)
|
|
17
|
-
|
|
18
|
-
- jg-ferien addresses its users with "du" throughout; ucm's auth screens use "Sie" — login, signup,
|
|
19
|
-
reset request, invite and reset pages (`src/i18n/authTranslations.ts`), so the break runs through
|
|
20
|
-
one flow (`/signup` "Sie", jg's `/signup/confirm` "du"), and one page mixes both (invite page
|
|
21
|
-
heading "Sie", validation "du").
|
|
22
|
-
- Hard-coded English in German UI: `UserListComponent.jsx` — "All Users", "Search",
|
|
23
|
-
"Search users...", "Rows per page:", "Successful Login", "Are you sure you want to delete this
|
|
24
|
-
user?"; invite panel — "Invite a new user", "Bulk Invite via CSV", "Upload a CSV file containing
|
|
25
|
-
email addresses. Header "email" is supported.", "Upload CSV", "Send Invites", success "Invitation
|
|
26
|
-
sent.".
|
|
27
|
-
- **Operator decision 2026-09-29: generic fixes go to ucm, app-specific ones to the app.**
|
|
28
|
-
|
|
29
|
-
## Scope + non-goals
|
|
30
|
-
|
|
31
|
-
- In scope: the variant mechanism at registration time; the informal German variant of the auth
|
|
32
|
-
bundle; keys for the hard-coded strings above (de/en/fr at least, plus every locale the bundles
|
|
33
|
-
already carry).
|
|
34
|
-
- Explicit non-goals / do-not-touch:
|
|
35
|
-
- Default behaviour for existing consumers stays formal German — no consumer changes wording
|
|
36
|
-
without opting in.
|
|
37
|
-
- Behavioural fixes of those screens are `UCM-AUTH-9`.
|
|
38
|
-
|
|
39
|
-
## Tier · gates
|
|
40
|
-
|
|
41
|
-
- **Tier 3** — change inside shared-core, a new public option on the registration export.
|
|
42
|
-
- Reviewer: `reviewer` (all lenses) · `ui_reviewer`.
|
|
43
|
-
- **Done means released and jg-ferien's pin bumped with the option set** (separate jg step).
|
|
44
|
-
|
|
45
|
-
## Risks
|
|
46
|
-
|
|
47
|
-
- A variant that only covers some keys silently falls back to "Sie" for the rest; a test must prove
|
|
48
|
-
key parity between the two German variants.
|
|
49
|
-
- Consumers that already override ucm keys locally must keep working (override order unchanged).
|
|
50
|
-
|
|
51
|
-
## Required tests to WRITE (you write them and run YOUR OWN new ones; the orchestrator's run is the gate)
|
|
52
|
-
|
|
53
|
-
1. Registering with the informal option yields "du" strings for the auth pages; without it, today's
|
|
54
|
-
strings.
|
|
55
|
-
2. Key parity: formal and informal German cover the same key set.
|
|
56
|
-
3. `UserListComponent` and the invite panel render no hard-coded English (render in `de`, assert the
|
|
57
|
-
listed strings are absent and translated keys present).
|
|
58
|
-
4. Four-locale shape test (`I18N-3`) still passes for the new keys.
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
# B. Implementation map — filled by the Orchestrator — ADDRESSED TO THE IMPLEMENTER
|
|
63
|
-
|
|
64
|
-
## Context package — two independent parts
|
|
65
|
-
|
|
66
|
-
### 1. The variant mechanism + the informal auth bundle
|
|
67
|
-
|
|
68
|
-
- **What "registers the kit's strings" means today, concretely** (so the mechanism plugs into the
|
|
69
|
-
real thing, not a hypothetical): every consuming app's own `i18n/index.js` imports the named
|
|
70
|
-
bundle exports (`authTranslations`, `messagingTranslations`, …) or the single aggregate
|
|
71
|
-
`uiCoreTranslations` (`src/i18n/uiCoreTranslations.js`, built by `I18N-1`) and spreads them into
|
|
72
|
-
its own i18next `resources` object — see `jg-ferien/frontend/i18n/index.js` for the exact pattern
|
|
73
|
-
(not this repo; read it for reference only, do not edit it — jg's own pin-bump/adoption is a
|
|
74
|
-
separate step, out of this WO). **No app currently imports `uiCoreTranslations` itself** (checked
|
|
75
|
-
— only per-feature bundles are imported today), so changing how the aggregate is BUILT carries no
|
|
76
|
-
live migration risk.
|
|
77
|
-
- **Do not change `uiCoreTranslations`'s existing shape or behaviour** — `tests/i18nAggregate.test.js`
|
|
78
|
-
(`I18N-1`/`I18N-3`) asserts it is byte-identical to the plain merge of the 7 per-feature bundles;
|
|
79
|
-
breaking that assertion is not this WO's job. Add a NEW function alongside it instead:
|
|
80
|
-
```js
|
|
81
|
-
// src/i18n/uiCoreTranslations.js — ADD this export, keep the existing `uiCoreTranslations` export unchanged
|
|
82
|
-
export function createUiCoreTranslations({ germanVariant = 'formal' } = {}) {
|
|
83
|
-
return Object.fromEntries(
|
|
84
|
-
Object.entries(uiCoreTranslations).map(([key, value]) => {
|
|
85
|
-
const { de_informal, ...rest } = value;
|
|
86
|
-
if (germanVariant === 'informal' && de_informal) return [key, { ...rest, de: de_informal }];
|
|
87
|
-
return [key, rest];
|
|
88
|
-
}),
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
This is "the single export a consumer picks a variant with" (the Envelope's phrase) — a future jg
|
|
93
|
-
adoption step calls `createUiCoreTranslations({ germanVariant: 'informal' })` instead of spreading
|
|
94
|
-
`uiCoreTranslations` directly; every OTHER existing consumer is completely unaffected (they don't
|
|
95
|
-
call this function at all, and `uiCoreTranslations` itself is untouched) — this is what "no
|
|
96
|
-
consumer changes wording without opting in" means mechanically.
|
|
97
|
-
- **The informal German variant itself** — add a sibling `de_informal` field to the `de` value of
|
|
98
|
-
every key in `src/i18n/authTranslations.ts` where the FORMAL wording actually depends on
|
|
99
|
-
Sie/Ihr-form address. Do NOT add `de_informal` to a key whose German text has no such dependency
|
|
100
|
-
(e.g. "E-Mail-Adresse", "Passwort", "QR-Token" read identically either way) — the function above
|
|
101
|
-
already falls back to the formal `de` value when `de_informal` is absent, so omitting it there is
|
|
102
|
-
correct, not incomplete.
|
|
103
|
-
- Find every Sie-dependent key with a word-boundary scan of each entry's `de` value against
|
|
104
|
-
`\bSie\b|\bIhr\b|\bIhre\b|\bIhrem\b|\bIhren\b|\bIhrer\b|\bIhres\b` (covers "Sie", "Ihr(e/em/en/er/es)"
|
|
105
|
-
in all inflected forms) — this repo already has one page that MIXES both forms today
|
|
106
|
-
(`Auth.MFA_RECOVERY_TITLE`'s description at `authTranslations.ts` uses "du" while
|
|
107
|
-
`Auth.PAGE_INVITE_SUBTITLE` uses "Sie" — measured, not hypothetical), so a plain "does the file
|
|
108
|
-
already use du sometimes" check is not sufficient; use the regex scan.
|
|
109
|
-
- For each matched key, write a natural informal ("du"/"dein"/"dir"/imperative-du) rewording as
|
|
110
|
-
`de_informal`, keeping the same meaning, placeholders (`{{email}}` etc. must appear identically),
|
|
111
|
-
and punctuation style as the formal version. This is a real translation task — this is a
|
|
112
|
-
shared-core kit that already ships a disclosed machine-translated Swahili bundle (`I18N-3`); do
|
|
113
|
-
the same here: **disclose in your final `RESULT:` line that the informal wording was machine-
|
|
114
|
-
translated by you (the implementing model), not reviewed by a fluent German speaker**, exactly
|
|
115
|
-
as `I18N-3` did for Swahili. Do not silently imply human review.
|
|
116
|
-
- **Test file:** extend `tests/i18nAggregate.test.js` (it already imports `uiCoreTranslations` and
|
|
117
|
-
the per-bundle exports — read it first) or add a new `tests/i18nGermanVariant.test.js`, covering:
|
|
118
|
-
1. For a representative key (e.g. `Auth.PAGE_INVITE_SUBTITLE`),
|
|
119
|
-
`createUiCoreTranslations({ germanVariant: 'informal' }).['Auth.PAGE_INVITE_SUBTITLE'].de`
|
|
120
|
-
is the informal wording and does NOT match the Sie-form regex; the default call
|
|
121
|
-
(`createUiCoreTranslations()`, no argument) returns the SAME `de` value as plain
|
|
122
|
-
`uiCoreTranslations['Auth.PAGE_INVITE_SUBTITLE'].de` (today's formal string, unopted-in
|
|
123
|
-
consumers see no change).
|
|
124
|
-
2. **The real parity guard the Risk note asks for:** scan `authTranslations` for every key whose
|
|
125
|
-
`de` matches the Sie-form regex above, and assert EACH such key has a non-empty `de_informal`
|
|
126
|
-
that does NOT itself match the Sie-form regex (proves it was actually rewritten, not copied).
|
|
127
|
-
This is the test that would fail if a future key were added with formal wording only and
|
|
128
|
-
forgotten — the actual failure mode the Envelope's Risk names, not a generic "same key set"
|
|
129
|
-
check (which would be trivially true by construction here and prove nothing).
|
|
130
|
-
3. Four-locale shape test (`I18N-3`, `tests/i18nAggregate.test.js`'s existing
|
|
131
|
-
`REQUIRED_LOCALES = ['de','en','fr','sw']` check) still passes — it iterates `uiCoreTranslations`
|
|
132
|
-
itself, which is unchanged; run it to confirm, do not edit it.
|
|
133
|
-
4. Existing consumers unaffected: `uiCoreTranslations['Auth.PAGE_INVITE_SUBTITLE']` (the plain,
|
|
134
|
-
unchanged export) still equals exactly what it did before this WO — read from
|
|
135
|
-
`authTranslations.ts` directly, minus the new `de_informal` field which existing code never
|
|
136
|
-
reads.
|
|
137
|
-
|
|
138
|
-
### 2. Hard-coded English in `UserListComponent`, `UserInviteComponent`, `BulkInviteCsvTab`
|
|
139
|
-
|
|
140
|
-
- **Every string named in the Envelope's Context already uses `t(key, englishDefault)`** — the
|
|
141
|
-
translation KEYS are already referenced in the JSX, they are simply missing from every bundle, so
|
|
142
|
-
`t()` silently falls through to the English default regardless of locale. **In almost every case
|
|
143
|
-
the fix is adding the bundle entry, not touching the component.** Add these keys to
|
|
144
|
-
`src/i18n/authTranslations.ts` (all four locales it already carries: de/en/fr/sw — plain, correct
|
|
145
|
-
translations, NOT the informal-German mechanism from part 1, this is unrelated hard-coded-string
|
|
146
|
-
work):
|
|
147
|
-
- From `src/components/UserListComponent.jsx` (verified against the file, line refs current):
|
|
148
|
-
`UserList.DELETE_CONFIRM` (`:93`), `Common.OPERATION_FAILED` (`:278`), `UserList.NEW` (`:313`),
|
|
149
|
-
`UserList.SUCCESSFUL_LOGIN` (`:331`), `UserList.ROLE` (`:349`), `Common.ACTIONS` (`:398`),
|
|
150
|
-
`UserList.TITLE` (`:503`), `Common.SEARCH` (`:509`), `UserList.SEARCH_PLACEHOLDER` (`:510`),
|
|
151
|
-
`UserList.NO_USERS` (`:560`). (`Common.YES`/`Common.NO`/`Common.DELETE`/`Auth.EMAIL_LABEL`/
|
|
152
|
-
`Profile.NAME_LABEL` already exist — do not re-add them.)
|
|
153
|
-
- **One genuine code change, not just a bundle entry:** the `<TablePagination>` at `:581` has no
|
|
154
|
-
localisation props at all — MUI supplies its own English default "Rows per page:" directly, it
|
|
155
|
-
is not reachable via `t()` today. Add `labelRowsPerPage={t('UserList.ROWS_PER_PAGE', 'Rows per
|
|
156
|
-
page:')}` to that element, plus the new `UserList.ROWS_PER_PAGE` bundle entry.
|
|
157
|
-
- From `src/components/UserInviteComponent.jsx`: `Auth.INVITE_SENT_SUCCESS` (`:29`, `:104` in
|
|
158
|
-
`BulkInviteCsvTab.jsx` too — shared key), `Auth.INVITE_TITLE` (`:43`). (`Auth.EMAIL_LABEL`,
|
|
159
|
-
`Auth.INVITE_BUTTON` already exist.)
|
|
160
|
-
- From `src/components/BulkInviteCsvTab.jsx`: `Account.BULK_INVITE_NO_EMAILS` (`:82`),
|
|
161
|
-
`Account.BULK_INVITE_PARSE_FAILED` (`:87`), `Account.BULK_INVITE_DONE` (`:117`, has `{{ok}}`/
|
|
162
|
-
`{{total}}` interpolation — keep both placeholders in every locale), `Account.BULK_INVITE_TITLE`
|
|
163
|
-
(`:129`), `Account.BULK_INVITE_HINT` (`:132-135`, multi-line `t()` call — easy to miss with a
|
|
164
|
-
single-line grep, it IS in scope), `Account.BULK_INVITE_UPLOAD` (`:143`),
|
|
165
|
-
`Account.BULK_INVITE_SEND` (`:147`), `Account.BULK_INVITE_COUNT` (`:150`, `{{count}}`),
|
|
166
|
-
`Common.STATUS` (`:166`), `Common.DETAILS` (`:167`), `Account.BULK_INVITE_PROGRESS` (`:190`,
|
|
167
|
-
`{{done}}`/`{{total}}`), `Account.BULK_INVITE_SUCCESS_COUNT` (`:192`, `{{count}}`).
|
|
168
|
-
(`Auth.EMAIL_LABEL`, `Common.SUCCESS`, `Common.ERROR` already exist.)
|
|
169
|
-
- **`UCM-AUTH-9` already landed** (earlier in this release's sequence) and touched this SAME
|
|
170
|
-
file: it added `UserList.ROLE_UPDATE_SUCCESS` (already present, all four locales — do not
|
|
171
|
-
re-add it) and, after its own review, reused the pre-existing `Auth.SELF_SIGNUP_DISABLED` key
|
|
172
|
-
for the closed-signup message rather than adding a new `Auth.SIGNUP_CLOSED` key (that key does
|
|
173
|
-
NOT exist — do not look for it or add it).
|
|
174
|
-
- Test file: extend `tests/UserListComponent`/`UserInviteComponent`/`BulkInviteCsvTab` tests if they
|
|
175
|
-
exist (grep `tests/`), or add focused new ones:
|
|
176
|
-
1. Render each of the three components with `i18n.language = 'de'` (or however this repo's test
|
|
177
|
-
harness sets locale — check an existing test that asserts translated text, e.g.
|
|
178
|
-
`tests/authTranslations.test.js`, for the pattern) and assert NONE of the literal English
|
|
179
|
-
default strings listed above are present, and the translated (German) text IS present.
|
|
180
|
-
2. Four-locale shape test (`i18nAggregate.test.js`) still passes for every new key.
|
|
181
|
-
|
|
182
|
-
## Do-not-touch / invariants
|
|
183
|
-
|
|
184
|
-
- Default behaviour for existing consumers stays formal German — `uiCoreTranslations` itself must
|
|
185
|
-
not change; only the new `createUiCoreTranslations` function is variant-aware.
|
|
186
|
-
- Behavioural fixes of the auth screens are `UCM-AUTH-9`'s scope, not this one — this WO only adds
|
|
187
|
-
strings/keys and the variant mechanism, it does not change component logic (aside from the one
|
|
188
|
-
named `labelRowsPerPage` prop addition, which is not a behaviour change).
|
|
189
|
-
- No secrets, no dependency changes — everything here is data (translation bundles) plus one small
|
|
190
|
-
pure function.
|
|
191
|
-
|
|
192
|
-
## Target repo working directory (absolute)
|
|
193
|
-
|
|
194
|
-
`C:\Users\biglmi\Documents\webapps\ui-core-micha` (branch `main`)
|
|
195
|
-
|
|
196
|
-
## Preamble — a REQUIRED block IN this file, not something appended at invocation
|
|
197
|
-
|
|
198
|
-
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there
|
|
199
|
-
> is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the
|
|
200
|
-
> app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI
|
|
201
|
-
> unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register
|
|
202
|
-
> row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source
|
|
203
|
-
> and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies,
|
|
204
|
-
> touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state
|
|
205
|
-
> blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT
|
|
206
|
-
> `git add`/`commit`/`push` — leave every
|
|
207
|
-
> change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests
|
|
208
|
-
> the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute
|
|
209
|
-
> and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review).
|
|
210
|
-
> The orchestrator re-runs the authoritative set + does the independent review after you finish —
|
|
211
|
-
> those are the gate; your own run does not count as the gate.
|
|
212
|
-
>
|
|
213
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
|
|
214
|
-
> `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
|
|
215
|
-
> completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
|
|
216
|
-
> `RESULT: DONE|BLOCKED <reason>`.
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
# C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
|
|
221
|
-
|
|
222
|
-
> **If you are the implementer reading this work order as your own specification: STOP at this line.
|
|
223
|
-
> Everything below describes what the Orchestrator does AFTER you finish. You do none of it — no
|
|
224
|
-
> reviewers, no verification run, no register edit, no commit.**
|
|
225
|
-
|
|
226
|
-
*(to be filled by the Orchestrator: execution directive; `reviewer` (all lenses) + `ui_reviewer`; release; jg-ferien pin bump with the informal option; register rows here and in jg (`JG-UX-10`).)*
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# UCM-I18N-5 — User-list pagination range text is hard-coded English
|
|
2
|
-
|
|
3
|
-
# A. Envelope — authored by the Expertenchat
|
|
4
|
-
|
|
5
|
-
## Goal & expected outcome
|
|
6
|
-
|
|
7
|
-
- Goal: the user list's pagination reads in the user's language.
|
|
8
|
-
- Expected outcome: `UserListComponent`'s `TablePagination` renders its "1–4 of 4" text through a
|
|
9
|
-
translation key (de/en/fr and every locale the bundles carry), the way `labelRowsPerPage`
|
|
10
|
-
already does.
|
|
11
|
-
|
|
12
|
-
## Context — measured 2026-10-01 in jg-ferien's local browser (ucm 3.7.0 installed there)
|
|
13
|
-
|
|
14
|
-
- `/account?tab=users` in German: "Zeilen pro Seite: 25 ▾ · **1–4 of 4**". `UserListComponent.jsx`
|
|
15
|
-
(~l.589-600) sets `labelRowsPerPage={t('UserList.ROWS_PER_PAGE', …)}` but no
|
|
16
|
-
`labelDisplayedRows`, so MUI's English default renders. It is the only `TablePagination` in ucm.
|
|
17
|
-
- Follows `UCM-I18N-4` (hard-coded English in the user list).
|
|
18
|
-
|
|
19
|
-
## Scope + non-goals
|
|
20
|
-
|
|
21
|
-
- In scope: `labelDisplayedRows` via a key with count interpolation; tests; release.
|
|
22
|
-
- Explicit non-goals / do-not-touch: no other change to the user list.
|
|
23
|
-
|
|
24
|
-
## Tier · gates
|
|
25
|
-
|
|
26
|
-
- **Tier 3** — change inside shared-core (small).
|
|
27
|
-
- Done means released AND jg-ferien's pin bumped.
|
|
28
|
-
|
|
29
|
-
## Risks
|
|
30
|
-
|
|
31
|
-
- The "more than" form (`count === -1`) must have a wording too, or it renders "of -1".
|
|
32
|
-
|
|
33
|
-
## Required tests to WRITE (you write them and run YOUR OWN new ones; the orchestrator's run is the gate)
|
|
34
|
-
|
|
35
|
-
1. In `de`, the pagination shows the German range text; in `en` the English one.
|
|
36
|
-
2. Key-parity: every locale bundle has the new key.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
# B. Implementation map — filled by the Orchestrator — ADDRESSED TO THE IMPLEMENTER
|
|
41
|
-
|
|
42
|
-
## Context package
|
|
43
|
-
|
|
44
|
-
### The call site
|
|
45
|
-
|
|
46
|
-
`src/components/UserListComponent.jsx:589-601`:
|
|
47
|
-
```jsx
|
|
48
|
-
<TablePagination
|
|
49
|
-
component="div"
|
|
50
|
-
count={sortedUsers.length}
|
|
51
|
-
page={page}
|
|
52
|
-
onPageChange={(_, newPage) => setPage(newPage)}
|
|
53
|
-
rowsPerPage={pageSize}
|
|
54
|
-
onRowsPerPageChange={(event) => {
|
|
55
|
-
setPageSize(Number(event.target.value));
|
|
56
|
-
setPage(0);
|
|
57
|
-
}}
|
|
58
|
-
labelRowsPerPage={t('UserList.ROWS_PER_PAGE', 'Rows per page:')}
|
|
59
|
-
rowsPerPageOptions={[10, 25, 50, 100]}
|
|
60
|
-
/>
|
|
61
|
-
```
|
|
62
|
-
`t`/`i18n` come from `useTranslation()` (`react-i18next`), already in scope at l.53.
|
|
63
|
-
|
|
64
|
-
### MUI's `labelDisplayedRows` contract
|
|
65
|
-
|
|
66
|
-
MUI's own default (`node_modules/@mui/material/TablePagination/TablePagination.js:119-124`,
|
|
67
|
-
for reference only — do not import it):
|
|
68
|
-
```js
|
|
69
|
-
function defaultLabelDisplayedRows({ from, to, count }) {
|
|
70
|
-
return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
The prop signature is `({ from, to, count, page }) => ReactNode`. `count` is `-1` when the total
|
|
74
|
-
is unknown/unbounded — this component always passes a real `sortedUsers.length`, but the prop
|
|
75
|
-
contract still has to handle `-1` defensively (the Risk note): MUI itself would call the function
|
|
76
|
-
with `-1` only if `count={-1}` were passed, which this component doesn't do — handle it anyway
|
|
77
|
-
since the function must satisfy the full contract, not just this component's current call site.
|
|
78
|
-
|
|
79
|
-
### The translation bundle has FOUR locales, not three
|
|
80
|
-
|
|
81
|
-
`src/i18n/authTranslations.ts` (flat `export const authTranslations = { "Key.NAME": { de, fr, en,
|
|
82
|
-
sw }, ... }`) carries `de`/`fr`/`en`/`sw` for every existing key, confirmed by grepping all locale
|
|
83
|
-
codes in the file — **sw (Swahili) is real and already translated throughout, not a stub**. "every
|
|
84
|
-
locale the bundles carry" in the Envelope means these four, not jg-ferien's usual three. Add the
|
|
85
|
-
new key(s) in the same shape, next to `UserList.ROWS_PER_PAGE` (~l.2050-2055) for locality.
|
|
86
|
-
|
|
87
|
-
Proposed keys (interpolated, i18next `{{var}}` syntax — do not reserialize the whole file through
|
|
88
|
-
`JSON.parse`/`JSON.stringify`, this is a `.ts` module, not JSON; a plain text insert keeps every
|
|
89
|
-
other entry byte-identical):
|
|
90
|
-
```ts
|
|
91
|
-
"UserList.DISPLAYED_ROWS": {
|
|
92
|
-
"de": "{{from}}–{{to}} von {{count}}",
|
|
93
|
-
"fr": "{{from}}–{{to}} sur {{count}}",
|
|
94
|
-
"en": "{{from}}–{{to}} of {{count}}",
|
|
95
|
-
"sw": "{{from}}–{{to}} ya {{count}}"
|
|
96
|
-
},
|
|
97
|
-
"UserList.DISPLAYED_ROWS_MORE_THAN": {
|
|
98
|
-
"de": "{{from}}–{{to}} von mehr als {{to}}",
|
|
99
|
-
"fr": "{{from}}–{{to}} sur plus de {{to}}",
|
|
100
|
-
"en": "{{from}}–{{to}} of more than {{to}}",
|
|
101
|
-
"sw": "{{from}}–{{to}} ya zaidi ya {{to}}"
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
The `sw` wording reuses "ya" for "of"/possessive, already used this way elsewhere in the same file
|
|
105
|
-
(e.g. l.57 `"ruhusa ya kutuma mialiko"`, l.114 `"barua pepe ya kuweka upya"`) and "zaidi ya" ("more
|
|
106
|
-
than") as a plain compositional phrase — a reasonable best-effort construction, NOT a
|
|
107
|
-
native-speaker-verified translation; say so plainly in your own report rather than presenting it as
|
|
108
|
-
settled, same as you would for any other claim you can't independently verify.
|
|
109
|
-
|
|
110
|
-
Call site becomes:
|
|
111
|
-
```jsx
|
|
112
|
-
labelDisplayedRows={({ from, to, count }) =>
|
|
113
|
-
count === -1
|
|
114
|
-
? t('UserList.DISPLAYED_ROWS_MORE_THAN', '{{from}}–{{to}} of more than {{to}}', { from, to })
|
|
115
|
-
: t('UserList.DISPLAYED_ROWS', '{{from}}–{{to}} of {{count}}', { from, to, count })
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Existing test harness to extend, not duplicate
|
|
120
|
-
|
|
121
|
-
`tests/userScreenTranslations.test.jsx` already renders `UserListComponent` through a REAL
|
|
122
|
-
`i18next` instance pinned to German (`withGermanI18n`, ~l.22-30, built from
|
|
123
|
-
`authTranslations.*.de`) and asserts rendered German strings plus `expectNoEnglishDefaults()`
|
|
124
|
-
(~l.34-39, checks `document.body.textContent` against an `ENGLISH_DEFAULTS` list, ~l.33-46). The
|
|
125
|
-
test `'renders UserListComponent in German, including pagination and action feedback'` (~l.97-125)
|
|
126
|
-
already fetches exactly 1 user, so the pagination currently renders English "1–1 of 1" — add that
|
|
127
|
-
literal string (or your chosen German text) to the existing `for (const german of [...])` loop
|
|
128
|
-
(~l.115) to assert the real rendered pagination text, and add the English range phrasing (e.g.
|
|
129
|
-
`'of 1'` or similar, whatever actually changes) to `ENGLISH_DEFAULTS` so `expectNoEnglishDefaults()`
|
|
130
|
-
(already called at line 124) starts actually catching a regression here — today it does NOT, since
|
|
131
|
-
no "of N" string is in that list, which is why this bug shipped unnoticed.
|
|
132
|
-
|
|
133
|
-
Required test 1 (German vs English) is naturally satisfied by extending this file: German via the
|
|
134
|
-
existing `withGermanI18n` harness, English via a parallel small i18next instance (or reuse the
|
|
135
|
-
`en` resources the same way `germanResources` is built from `.de`) rendering the same component and
|
|
136
|
-
asserting the English range text.
|
|
137
|
-
|
|
138
|
-
Required test 2 (key-parity across all four locales) — check whether a generic "every key has
|
|
139
|
-
every locale" structural test already exists in this repo (grep `authTranslations` test files for
|
|
140
|
-
something like `Object.values(...).every(...)` or a locale-set check) before writing a new one;
|
|
141
|
-
extend it if so, add a small standalone one for just these two new keys if not.
|
|
142
|
-
|
|
143
|
-
## Target repo working directory (absolute)
|
|
144
|
-
|
|
145
|
-
`C:\Users\biglmi\Documents\webapps\ui-core-micha` (branch `main`)
|
|
146
|
-
|
|
147
|
-
## Preamble — a REQUIRED block IN this file, not something appended at invocation
|
|
148
|
-
|
|
149
|
-
> The text above is the COMPLETE spec — the committed WO file's content, not a plan to refine; there
|
|
150
|
-
> is no separate plan file. Read the nearest `AGENTS.md`, the relevant `.codex/skills/<role>/SKILL.md`, and the
|
|
151
|
-
> app `MEMORY.md` ONLY for conventions. Stay in scope; do not touch auth/permissions/deps/schema/CI
|
|
152
|
-
> unless the spec says so; do not update `MEMORY.md`. **Do NOT edit `WORK_ORDERS.md` — the register
|
|
153
|
-
> row and the review verdicts are the orchestrator's alone.** **Your tools are for editing source
|
|
154
|
-
> and test files and for running the tests you wrote — nothing else.** Do NOT install dependencies,
|
|
155
|
-
> touch a lockfile, run a package manager, or tidy up stray files; if something in the repo state
|
|
156
|
-
> blocks you, stop and report it as `RESULT: BLOCKED <reason>` instead of fixing it. Do NOT
|
|
157
|
-
> `git add`/`commit`/`push` — leave every
|
|
158
|
-
> change uncommitted in the working tree for the orchestrator's independent review. WRITE the tests
|
|
159
|
-
> the `Required tests` section calls for AND **RUN the tests you just wrote** to confirm they execute
|
|
160
|
-
> and pass — that is the ONLY test run you do (NOT the app's affected/full suite, NOT any review).
|
|
161
|
-
> The orchestrator re-runs the authoritative set + does the independent review after you finish —
|
|
162
|
-
> those are the gate; your own run does not count as the gate.
|
|
163
|
-
>
|
|
164
|
-
> Narrate continuously: a `PLAN: <step1> | <step2> | …` line up front, then a single-line
|
|
165
|
-
> `PROGRESS: [<n>/<total>] <present-tense action>` before every relevant action (and `… done` on
|
|
166
|
-
> completion), spaced so no gap exceeds ~2 min, stdout unbuffered, plus exactly one final
|
|
167
|
-
> `RESULT: DONE|BLOCKED <reason>`.
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
# C. Orchestrator only — NOT ADDRESSED TO THE IMPLEMENTER
|
|
172
|
-
|
|
173
|
-
> **If you are the implementer reading this work order as your own specification: STOP at this line.
|
|
174
|
-
> Everything below describes what the Orchestrator does AFTER you finish. You do none of it — no
|
|
175
|
-
> reviewers, no verification run, no register edit, no commit.**
|
|
176
|
-
|
|
177
|
-
**Execution directive:** dispatch via `codex exec --skip-git-repo-check
|
|
178
|
-
--dangerously-bypass-approvals-and-sandbox -m gpt-5.6-luna - < work-orders/UCM-I18N-5.md` (today,
|
|
179
|
-
2026-10-02, already recorded `available` in `webapps/.claude/codex-status.md`), cwd =
|
|
180
|
-
`C:\Users\biglmi\Documents\webapps\ui-core-micha`. Monitor for `RESULT: DONE|BLOCKED`.
|
|
181
|
-
|
|
182
|
-
**Review routing:** Tier 3 (shared-core) — full `reviewer` lens set (`envelope`, `regression`,
|
|
183
|
-
`duplication`, `tests`, codex/gpt-5.6-luna, one concurrent batch, diff inline) PLUS `ui_reviewer`
|
|
184
|
-
(frontend-adjacent: a rendered component's i18n text). `duplication` should specifically check
|
|
185
|
-
whether any OTHER app already patched around this same MUI default locally (a local workaround that
|
|
186
|
-
this shared-core fix should make redundant, worth naming even if out of this WO's scope to remove).
|
|
187
|
-
|
|
188
|
-
**Tests:** the Orchestrator re-runs `tests/userScreenTranslations.test.jsx` (and any new/renamed
|
|
189
|
-
key-parity test file) as the gate — not ucm's full suite (Tier 3 but a small, local-only change;
|
|
190
|
-
no cross-app ripple to justify a full run per `AGENTS.md` → Test scope).
|
|
191
|
-
|
|
192
|
-
**Release:** patch bump (3.11.0 → 3.11.1) — this extends `UCM-I18N-4`'s existing i18n-gap category
|
|
193
|
-
in the same component, not a new capability area, per the project convention (version bump reflects
|
|
194
|
-
scope, not mere newness). Update `package.json` + `CHANGELOG.md`, then the repo's normal publish
|
|
195
|
-
path (check `.github/workflows/` or `package.json` scripts for how a previous release like
|
|
196
|
-
`UCM-THEME-14`/3.11.0 or `UCM-AUTH-11`/3.9.1 actually published, don't assume `npm publish` by
|
|
197
|
-
hand — follow the established mechanism).
|
|
198
|
-
|
|
199
|
-
**jg-ferien pin bump:** after the release is live, bump `ui-core-micha`'s pin in
|
|
200
|
-
`jg-ferien/frontend/package.json`, install, run jg-ferien's own affected tests (anything touching
|
|
201
|
-
`UserListComponent` consumption, if jg-ferien renders it at all — check first; if jg-ferien doesn't
|
|
202
|
-
use `UserListComponent`, the pin bump itself plus jg-ferien's existing suite staying green is the
|
|
203
|
-
evidence), commit + push to jg-ferien's `develop`.
|
|
204
|
-
|
|
205
|
-
**Register:** `done` only once BOTH halves land — the release AND the jg-ferien pin bump (the WO's
|
|
206
|
-
own Tier line: "Done means released AND jg-ferien's pin bumped"). Row here (ui-core-micha's
|
|
207
|
-
`WORK_ORDERS.md`) AND a row in jg-ferien's own `WORK_ORDERS.md` noting the pin bump, per the
|
|
208
|
-
Envelope's own closing instruction.
|
|
209
|
-
|
|
210
|
-
**Commit:** ui-core-micha lands on `main` (no `develop` branch here, confirmed in `AGENTS.md`'s
|
|
211
|
-
branch table). jg-ferien's pin bump lands on `develop` as usual.
|