@vc-shell/vc-app-skill 2.0.0-alpha.32 → 2.0.0-alpha.33

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +1 -1
  3. package/runtime/VERSION +1 -1
  4. package/runtime/agents/migration-agent.md +83 -0
  5. package/runtime/knowledge/docs/_BUILD_HASH.md +1 -1
  6. package/runtime/knowledge/docs/core/composables/useBladeForm/useBladeForm.docs.md +55 -1
  7. package/runtime/knowledge/docs/shell/auth/ChangePasswordPage/change-password-page.docs.md +102 -0
  8. package/runtime/knowledge/docs/ui/components/atoms/vc-card/vc-card.docs.md +4 -0
  9. package/runtime/knowledge/docs/ui/components/molecules/vc-accordion/vc-accordion.docs.md +4 -0
  10. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox/vc-checkbox.docs.md +5 -0
  11. package/runtime/knowledge/docs/ui/components/molecules/vc-checkbox-group/vc-checkbox-group.docs.md +5 -0
  12. package/runtime/knowledge/docs/ui/components/molecules/vc-color-input/vc-color-input.docs.md +5 -0
  13. package/runtime/knowledge/docs/ui/components/molecules/vc-date-picker/vc-date-picker.docs.md +7 -0
  14. package/runtime/knowledge/docs/ui/components/molecules/vc-editor/vc-editor.docs.md +5 -0
  15. package/runtime/knowledge/docs/ui/components/molecules/vc-field/vc-field.docs.md +5 -0
  16. package/runtime/knowledge/docs/ui/components/molecules/vc-file-upload/vc-file-upload.docs.md +5 -0
  17. package/runtime/knowledge/docs/ui/components/molecules/vc-input/vc-input.docs.md +7 -0
  18. package/runtime/knowledge/docs/ui/components/molecules/vc-input-currency/vc-input-currency.docs.md +7 -0
  19. package/runtime/knowledge/docs/ui/components/molecules/vc-input-dropdown/vc-input-dropdown.docs.md +7 -0
  20. package/runtime/knowledge/docs/ui/components/molecules/vc-multivalue/vc-multivalue.docs.md +7 -0
  21. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-button/vc-radio-button.docs.md +5 -0
  22. package/runtime/knowledge/docs/ui/components/molecules/vc-radio-group/vc-radio-group.docs.md +5 -0
  23. package/runtime/knowledge/docs/ui/components/molecules/vc-rating/vc-rating.docs.md +5 -0
  24. package/runtime/knowledge/docs/ui/components/molecules/vc-select/vc-select.docs.md +7 -0
  25. package/runtime/knowledge/docs/ui/components/molecules/vc-slider/vc-slider.docs.md +5 -0
  26. package/runtime/knowledge/docs/ui/components/molecules/vc-switch/vc-switch.docs.md +5 -0
  27. package/runtime/knowledge/docs/ui/components/molecules/vc-textarea/vc-textarea.docs.md +7 -0
  28. package/runtime/knowledge/docs/ui/components/organisms/vc-blade/vc-blade.docs.md +30 -0
  29. package/runtime/knowledge/docs/ui/components/organisms/vc-data-table/vc-data-table.docs.md +28 -0
  30. package/runtime/knowledge/migration-prompts/blade-form-migration.md +246 -0
  31. package/runtime/knowledge/migration-prompts/blade-props-migration.md +195 -0
  32. package/runtime/knowledge/migration-prompts/notifications-migration.md +218 -0
  33. package/runtime/knowledge/migration-prompts/nswag-migration.md +248 -0
  34. package/runtime/knowledge/migration-prompts/widgets-migration.md +157 -0
  35. package/runtime/vc-app.md +126 -0
  36. package/runtime/knowledge/docs/core/constants/constants.docs.md +0 -185
@@ -0,0 +1,246 @@
1
+ ---
2
+ name: blade-form-migration
3
+ description: AI transformation rules for useForm + onBeforeClose → useBladeForm.
4
+ ---
5
+
6
+ # Blade Form Migration: useForm → useBladeForm
7
+
8
+ Replace manual wiring of `useForm()` (vee-validate) + `useModificationTracker()` + `useBeforeUnload()` + `onBeforeClose()` with the unified `useBladeForm()` composable.
9
+
10
+ ## RULE 1: Replace useForm + onBeforeClose with useBladeForm
11
+
12
+ **BEFORE:**
13
+
14
+ ```typescript
15
+ import { useForm } from "vee-validate";
16
+ import { useBeforeUnload, useModificationTracker, useBlade, usePopup } from "@vc-shell/framework";
17
+
18
+ const { item, loading, load, save } = useMyDetails();
19
+ const { onBeforeClose } = useBlade();
20
+ const { showConfirmation } = usePopup();
21
+
22
+ const { errorBag, setFieldError, meta: formMeta } = useForm({
23
+ initialValues: item,
24
+ });
25
+
26
+ const { currentValue, resetModificationState, isModified } = useModificationTracker(item);
27
+
28
+ useBeforeUnload(computed(() => isModified.value));
29
+
30
+ onBeforeClose(async () => {
31
+ if (isModified.value) {
32
+ return showConfirmation(t("MY_MODULE.ALERTS.CLOSE_CONFIRMATION"));
33
+ }
34
+ return true;
35
+ });
36
+
37
+ const canSave = computed(
38
+ () => isModified.value && formMeta.value.valid && !loading.value,
39
+ );
40
+
41
+ async function handleSave() {
42
+ await save(item.value);
43
+ resetModificationState();
44
+ }
45
+
46
+ async function handleCancel() {
47
+ item.value = JSON.parse(JSON.stringify(currentValue.value));
48
+ resetModificationState();
49
+ }
50
+ ```
51
+
52
+ **AFTER:**
53
+
54
+ ```typescript
55
+ import { useBladeForm } from "@vc-shell/framework";
56
+
57
+ const { item, loading, load, save } = useMyDetails();
58
+
59
+ const { canSave, isModified, setBaseline, revert, setFieldError, errorBag } = useBladeForm({
60
+ data: item,
61
+ closeConfirmMessage: () => t("MY_MODULE.ALERTS.CLOSE_CONFIRMATION"),
62
+ });
63
+
64
+ watch(item, () => {
65
+ if (item.value) setBaseline();
66
+ }, { once: true });
67
+
68
+ async function handleSave() {
69
+ await save(item.value);
70
+ setBaseline();
71
+ }
72
+ ```
73
+
74
+ ## RULE 2: Remove onBeforeClose Entirely
75
+
76
+ `useBladeForm` handles the unsaved-changes guard automatically via `autoBeforeClose` (defaults to `true`).
77
+
78
+ **BEFORE:**
79
+
80
+ ```typescript
81
+ const { onBeforeClose } = useBlade();
82
+
83
+ onBeforeClose(async () => {
84
+ if (formMeta.value.dirty) {
85
+ return confirm("You have unsaved changes. Discard?");
86
+ }
87
+ return true;
88
+ });
89
+ ```
90
+
91
+ **AFTER:**
92
+
93
+ ```typescript
94
+ // Remove entirely. useBladeForm handles this.
95
+ // If you need a custom message, pass closeConfirmMessage option:
96
+ const form = useBladeForm({
97
+ data: item,
98
+ closeConfirmMessage: () => t("MY_MODULE.ALERTS.CLOSE_CONFIRMATION"),
99
+ });
100
+ ```
101
+
102
+ ## RULE 3: Update Toolbar Disabled Logic
103
+
104
+ **BEFORE:**
105
+
106
+ ```typescript
107
+ const canSave = computed(
108
+ () => !meta.value.valid || !isModified.value,
109
+ );
110
+
111
+ // or in toolbar items:
112
+ {
113
+ id: "save",
114
+ disabled: computed(() => !formMeta.value.valid || !isModified.value),
115
+ }
116
+ ```
117
+
118
+ **AFTER:**
119
+
120
+ ```typescript
121
+ // canSave is returned directly from useBladeForm:
122
+ const { canSave } = useBladeForm({ data: item });
123
+
124
+ // In toolbar items:
125
+ {
126
+ id: "save",
127
+ disabled: computed(() => !canSave.value),
128
+ }
129
+ ```
130
+
131
+ For additional disabled conditions (e.g., async validation in progress), use `canSaveOverride`:
132
+
133
+ ```typescript
134
+ const { canSave } = useBladeForm({
135
+ data: item,
136
+ canSaveOverride: computed(() => !isSkuValidating.value && !loading.value),
137
+ });
138
+ ```
139
+
140
+ ## RULE 4: Keep Field from vee-validate
141
+
142
+ Only remove `useForm` from vee-validate imports. Keep `Field`, `ErrorMessage`, and other template-level components — they still work with `useBladeForm` which uses vee-validate internally.
143
+
144
+ **BEFORE:**
145
+
146
+ ```typescript
147
+ import { useForm, Field, ErrorMessage } from "vee-validate";
148
+ ```
149
+
150
+ **AFTER:**
151
+
152
+ ```typescript
153
+ import { Field, ErrorMessage } from "vee-validate";
154
+ ```
155
+
156
+ ## RULE 5: Remove useBeforeUnload / useModificationTracker
157
+
158
+ `useBladeForm` handles both browser unload guards and modification tracking internally.
159
+
160
+ **BEFORE:**
161
+
162
+ ```typescript
163
+ import { useBeforeUnload, useModificationTracker } from "@vc-shell/framework";
164
+
165
+ const { currentValue, resetModificationState, isModified } = useModificationTracker(item);
166
+ useBeforeUnload(computed(() => isModified.value));
167
+ ```
168
+
169
+ **AFTER:**
170
+
171
+ ```typescript
172
+ // Remove entirely. useBladeForm provides:
173
+ // - isModified (deep comparison against baseline)
174
+ // - setBaseline() (replaces resetModificationState)
175
+ // - revert() (replaces manual JSON.parse(JSON.stringify(currentValue.value)))
176
+ // - Browser unload guard (automatic)
177
+ ```
178
+
179
+ Also remove `useModificationTracker` from data composables if present:
180
+
181
+ **BEFORE (data composable):**
182
+
183
+ ```typescript
184
+ export function useMyDetails() {
185
+ const item = ref<MyItem>();
186
+ const { currentValue, resetModificationState, isModified } = useModificationTracker(item);
187
+
188
+ async function load(id: string) {
189
+ item.value = await api.get(id);
190
+ resetModificationState();
191
+ }
192
+
193
+ return { item, currentValue, resetModificationState, isModified, load, save };
194
+ }
195
+ ```
196
+
197
+ **AFTER (data composable):**
198
+
199
+ ```typescript
200
+ export function useMyDetails() {
201
+ const item = ref<MyItem>();
202
+
203
+ async function load(id: string) {
204
+ item.value = await api.get(id);
205
+ }
206
+
207
+ return { item, load, save };
208
+ }
209
+ ```
210
+
211
+ ## Template Changes
212
+
213
+ Remove `:modified` prop from `<VcBlade>` — it is auto-detected via provide/inject.
214
+
215
+ **BEFORE:**
216
+
217
+ ```vue
218
+ <template>
219
+ <VcBlade :modified="isModified" :closable="true">
220
+ <!-- content -->
221
+ </VcBlade>
222
+ </template>
223
+ ```
224
+
225
+ **AFTER:**
226
+
227
+ ```vue
228
+ <template>
229
+ <VcBlade :closable="true">
230
+ <!-- content — no :modified prop needed -->
231
+ </VcBlade>
232
+ </template>
233
+ ```
234
+
235
+ ## Verification
236
+
237
+ After migration:
238
+
239
+ 1. Run `npx tsc --noEmit` to verify no TypeScript errors
240
+ 2. Confirm the blade shows a modified indicator when data changes
241
+ 3. Confirm closing a modified blade shows the confirmation dialog
242
+ 4. Confirm the save button is disabled when form is clean or invalid
243
+ 5. Confirm `setBaseline()` is called after initial load and after save
244
+ 6. Confirm cancel/revert restores data to the last baseline
245
+ 7. Confirm `useModificationTracker` is removed from data composables
246
+ 8. Confirm no stale imports of `useForm`, `useBeforeUnload`, `useModificationTracker`, or `onBeforeClose`
@@ -0,0 +1,195 @@
1
+ ---
2
+ name: blade-props-migration
3
+ description: AI transformation rules for reusable blade components skipped by CLI migrator.
4
+ ---
5
+
6
+ # Blade Props Migration: Boilerplate Removal
7
+
8
+ Remove blade prop/emit boilerplate from blade pages. VcBlade is now context-aware — it reads `expanded` and `closable` from the BladeDescriptor automatically via provide/inject. Use `useBlade()` for `param`, `options`, `closeSelf`, and `callParent`.
9
+
10
+ ## RULE 1: Remove Blade Prop Forwarding from Template
11
+
12
+ Remove `:expanded`, `:closable`, `@close`, `@expand`, `@collapse` from the `<VcBlade>` tag.
13
+
14
+ **BEFORE:**
15
+
16
+ ```vue
17
+ <template>
18
+ <VcBlade
19
+ :title="bladeTitle"
20
+ :expanded="expanded"
21
+ :closable="closable"
22
+ :toolbar-items="bladeToolbar"
23
+ @close="$emit('close:blade')"
24
+ @expand="$emit('expand:blade')"
25
+ @collapse="$emit('collapse:blade')"
26
+ >
27
+ <VcDataTable ... />
28
+ </VcBlade>
29
+ </template>
30
+ ```
31
+
32
+ **AFTER:**
33
+
34
+ ```vue
35
+ <template>
36
+ <VcBlade
37
+ :title="bladeTitle"
38
+ :toolbar-items="bladeToolbar"
39
+ >
40
+ <VcDataTable ... />
41
+ </VcBlade>
42
+ </template>
43
+ ```
44
+
45
+ ## RULE 2: Remove Props and Emits Interfaces
46
+
47
+ Remove `expanded`, `closable`, `param`, `options` from Props interface. Remove blade events from Emits. Use `useBlade()` to access `param` and `options`.
48
+
49
+ **BEFORE:**
50
+
51
+ ```typescript
52
+ export interface Props {
53
+ expanded?: boolean;
54
+ closable?: boolean;
55
+ param?: string;
56
+ options?: { sellerProduct?: SellerProduct };
57
+ }
58
+
59
+ export interface Emits {
60
+ (event: "parent:call", args: IParentCallArgs): void;
61
+ (event: "close:blade"): void;
62
+ (event: "collapse:blade"): void;
63
+ (event: "expand:blade"): void;
64
+ }
65
+
66
+ const props = withDefaults(defineProps<Props>(), {
67
+ expanded: true,
68
+ closable: true,
69
+ });
70
+ const emit = defineEmits<Emits>();
71
+ ```
72
+
73
+ **AFTER:**
74
+
75
+ ```typescript
76
+ import { useBlade } from "@vc-shell/framework";
77
+
78
+ const { param, options, openBlade, closeSelf, callParent } =
79
+ useBlade<{ sellerProduct?: SellerProduct }>();
80
+ ```
81
+
82
+ If the Props interface has other non-blade props, keep only those:
83
+
84
+ ```typescript
85
+ // Keep non-blade props
86
+ export interface Props {
87
+ config?: DetailConfig;
88
+ }
89
+
90
+ const props = defineProps<Props>();
91
+
92
+ // Blade concerns via composable
93
+ const { param, options, closeSelf, callParent } = useBlade<{ orderId: string }>();
94
+ ```
95
+
96
+ ## RULE 3: Replace emit("parent:call") with callParent()
97
+
98
+ **BEFORE:**
99
+
100
+ ```typescript
101
+ const emit = defineEmits<Emits>();
102
+
103
+ const reload = async () => {
104
+ await loadOffers({ ... });
105
+ emit("parent:call", { method: "reload" });
106
+ };
107
+
108
+ function onItemSelect(item: Product) {
109
+ emit("parent:call", { method: "onItemClick", args: { data: item } });
110
+ }
111
+ ```
112
+
113
+ **AFTER:**
114
+
115
+ ```typescript
116
+ const { callParent } = useBlade();
117
+
118
+ const reload = async () => {
119
+ await loadOffers({ ... });
120
+ callParent("reload");
121
+ };
122
+
123
+ function onItemSelect(item: Product) {
124
+ callParent("onItemClick", { data: item });
125
+ }
126
+ ```
127
+
128
+ ## RULE 4: Replace emit("close:blade") with closeSelf()
129
+
130
+ **BEFORE:**
131
+
132
+ ```typescript
133
+ const emit = defineEmits<Emits>();
134
+
135
+ function handleClose() {
136
+ emit("close:blade");
137
+ }
138
+
139
+ // or in template:
140
+ // @click="$emit('close:blade')"
141
+ ```
142
+
143
+ **AFTER:**
144
+
145
+ ```typescript
146
+ const { closeSelf } = useBlade();
147
+
148
+ function handleClose() {
149
+ closeSelf();
150
+ }
151
+
152
+ // or in template:
153
+ // @click="closeSelf()"
154
+ ```
155
+
156
+ ## Wrapper Components
157
+
158
+ If a wrapper component forwards blade props to a base component, remove the forwarding. The base component should call `useBlade()` directly.
159
+
160
+ **BEFORE:**
161
+
162
+ ```vue
163
+ <template>
164
+ <ProductDetailsBase
165
+ :expanded="expanded"
166
+ :closable="closable"
167
+ :param="param"
168
+ :options="options"
169
+ @parent:call="$emit('parent:call', $event)"
170
+ @close:blade="$emit('close:blade')"
171
+ @expand:blade="$emit('expand:blade')"
172
+ @collapse:blade="$emit('collapse:blade')"
173
+ />
174
+ </template>
175
+ ```
176
+
177
+ **AFTER:**
178
+
179
+ ```vue
180
+ <template>
181
+ <ProductDetailsBase />
182
+ </template>
183
+ ```
184
+
185
+ ## Verification
186
+
187
+ After migration:
188
+
189
+ 1. Run `npx tsc --noEmit` to verify no TypeScript errors
190
+ 2. Confirm blades open and close correctly
191
+ 3. Confirm `param.value` is accessible in script (use `param` without `.value` in templates)
192
+ 4. Confirm `options.value` provides typed options from parent
193
+ 5. Confirm `callParent()` triggers the parent's exposed method
194
+ 6. Confirm no remaining `emit("close:blade")` or `emit("parent:call", ...)` calls
195
+ 7. Confirm no remaining `:expanded`, `:closable`, `@close`, `@expand`, `@collapse` on `<VcBlade>`
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: notifications-migration
3
+ description: AI transformation rules for notification template migration to new defineAppModule config.
4
+ ---
5
+
6
+ # Notifications Migration: useNotifications → useBladeNotifications
7
+
8
+ Migrate from `createAppModule(pages, locales, notificationTemplates)` to `defineAppModule({ notifications })`, and from `useNotifications()` to `useBladeNotifications()`.
9
+
10
+ ## RULE 1: Move Notification Directory
11
+
12
+ Move `components/notifications/` to `notifications/` at the module root. Remove the barrel `index.ts` that re-exports all templates.
13
+
14
+ **BEFORE:**
15
+
16
+ ```
17
+ my-module/
18
+ components/
19
+ notifications/
20
+ index.ts ← barrel: export { default as MyEvent } from "./MyEvent.vue"
21
+ MyEvent.vue
22
+ pages/
23
+ index.ts
24
+ ```
25
+
26
+ **AFTER:**
27
+
28
+ ```
29
+ my-module/
30
+ notifications/
31
+ MyEvent.vue ← no barrel index.ts needed
32
+ pages/
33
+ index.ts
34
+ ```
35
+
36
+ ## RULE 2: Update Notification Template
37
+
38
+ Remove `defineProps`, remove `defineOptions({ inheritAttrs: false })`, and use `useNotificationContext()` composable instead of props.
39
+
40
+ **BEFORE:**
41
+
42
+ ```vue
43
+ <template>
44
+ <NotificationTemplate
45
+ :color="color"
46
+ :title="notification.title"
47
+ :icon="icon"
48
+ :notification="notification"
49
+ @click="onClick"
50
+ >
51
+ <VcHint>{{ notification.description }}</VcHint>
52
+ </NotificationTemplate>
53
+ </template>
54
+
55
+ <script lang="ts" setup>
56
+ import { PushNotification, NotificationTemplate } from "@vc-shell/framework";
57
+
58
+ export interface Props {
59
+ notification: PushNotification;
60
+ }
61
+
62
+ defineProps<Props>();
63
+ defineOptions({ inheritAttrs: false });
64
+
65
+ const color = computed(() => "var(--primary-500)");
66
+ const icon = "lucide-bell";
67
+
68
+ function onClick() {
69
+ // handle click
70
+ }
71
+ </script>
72
+ ```
73
+
74
+ **AFTER:**
75
+
76
+ ```vue
77
+ <template>
78
+ <NotificationTemplate
79
+ :color="color"
80
+ :title="notification.title"
81
+ :icon="icon"
82
+ :notification="notification"
83
+ @click="onClick"
84
+ >
85
+ <VcHint>{{ notification.description }}</VcHint>
86
+ </NotificationTemplate>
87
+ </template>
88
+
89
+ <script lang="ts" setup>
90
+ import { PushNotification, useBlade, NotificationTemplate, useNotificationContext } from "@vc-shell/framework";
91
+ import { computed } from "vue";
92
+
93
+ interface IMyNotification extends PushNotification {
94
+ customField?: string;
95
+ }
96
+
97
+ const notificationRef = useNotificationContext<IMyNotification>();
98
+ const notification = computed(() => notificationRef.value);
99
+
100
+ const color = computed(() => "var(--primary-500)");
101
+ const icon = "lucide-bell";
102
+
103
+ function onClick() {
104
+ // handle click
105
+ }
106
+ </script>
107
+ ```
108
+
109
+ ## RULE 3: Update Module index.ts
110
+
111
+ Replace `createAppModule(pages, locales, notificationTemplates)` with `defineAppModule({ notifications })`. Import each notification template individually instead of using a barrel `import *`.
112
+
113
+ **BEFORE:**
114
+
115
+ ```typescript
116
+ import * as pages from "./pages";
117
+ import * as locales from "./locales";
118
+ import * as notificationTemplates from "./components/notifications";
119
+
120
+ export default createAppModule(pages, locales, notificationTemplates);
121
+ ```
122
+
123
+ **AFTER:**
124
+
125
+ ```typescript
126
+ import * as pages from "./pages";
127
+ import * as locales from "./locales";
128
+ import MyCreatedEvent from "./notifications/MyCreatedEvent.vue";
129
+ import MyDeletedEvent from "./notifications/MyDeletedEvent.vue";
130
+ import { defineAppModule } from "@vc-shell/framework";
131
+
132
+ export default defineAppModule({
133
+ blades: pages,
134
+ locales,
135
+ notifications: {
136
+ MyCreatedDomainEvent: {
137
+ template: MyCreatedEvent,
138
+ toast: { mode: "auto" },
139
+ },
140
+ MyDeletedDomainEvent: {
141
+ template: MyDeletedEvent,
142
+ toast: { mode: "auto", severity: "warning" },
143
+ },
144
+ },
145
+ });
146
+ ```
147
+
148
+ Toast options:
149
+ - `mode`: `"auto"` (show and auto-dismiss), `"progress"` (show with progress bar), `"silent"` (no toast)
150
+ - `severity`: `"info"` (default), `"warning"`, `"error"`, `"critical"`
151
+
152
+ ## RULE 4: Replace useNotifications in Blades
153
+
154
+ Replace `useNotifications()` with `useBladeNotifications()`. Remove `setNotificationHandler`, `moduleNotifications` watch, and `notifyType` from `defineOptions`.
155
+
156
+ **BEFORE:**
157
+
158
+ ```typescript
159
+ defineOptions({
160
+ name: "MyBlade",
161
+ notifyType: "MyDomainEvent",
162
+ });
163
+
164
+ const { markAsRead, setNotificationHandler, moduleNotifications } = useNotifications("MyDomainEvent");
165
+
166
+ setNotificationHandler((message) => {
167
+ if (message.title) {
168
+ notification.success(message.title, {
169
+ onClose() {
170
+ markAsRead(message);
171
+ },
172
+ });
173
+ }
174
+ });
175
+
176
+ // or watch pattern:
177
+ watch(moduleNotifications, (newVal) => {
178
+ // manual toast management
179
+ }, { deep: true });
180
+ ```
181
+
182
+ **AFTER:**
183
+
184
+ ```typescript
185
+ defineOptions({
186
+ name: "MyBlade",
187
+ // notifyType removed
188
+ });
189
+
190
+ const { messages } = useBladeNotifications({
191
+ types: ["MyDomainEvent"],
192
+ onMessage: () => reloadData(),
193
+ });
194
+ ```
195
+
196
+ For progress notifications:
197
+
198
+ ```typescript
199
+ // Module config: notifications: { MyProgressEvent: { toast: { mode: "progress" } } }
200
+ useBladeNotifications({
201
+ types: ["MyProgressEvent"],
202
+ filter: (msg) => msg.entityId === param.value,
203
+ onMessage: (msg) => refreshData(msg),
204
+ });
205
+ ```
206
+
207
+ ## Verification
208
+
209
+ After migration:
210
+
211
+ 1. Run `npx tsc --noEmit` to verify no TypeScript errors
212
+ 2. Confirm notification templates render correctly in the notification panel
213
+ 3. Confirm toast notifications appear for configured event types
214
+ 4. Confirm `useBladeNotifications` triggers `onMessage` callback when events arrive
215
+ 5. Confirm `notifyType` is removed from all `defineOptions` calls
216
+ 6. Confirm `components/notifications/` directory is removed and `notifications/` exists at module root
217
+ 7. Confirm no remaining imports of `useNotifications`, `setNotificationHandler`, or `moduleNotifications`
218
+ 8. Confirm no remaining `defineProps` or `defineOptions({ inheritAttrs: false })` in notification templates