@imfusion/web-ui 0.5.1-dev.21.g2accd17d → 0.5.1-dev.23.g913f03e6

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.
@@ -3786,4 +3786,4 @@ function Mo({ className: e, ...t }) {
3786
3786
  }
3787
3787
  Mo.displayName = "Tabs.Panel";
3788
3788
  //#endregion
3789
- export { Hn as $, M as $n, Vt as $t, Kr as A, Ue as An, xn as At, Tr as B, J as Bn, pn as Bt, ha as C, st as Cn, Tn as Ct, gi as D, Je as Dn, kn as Dt, hi as E, $e as En, wn as Et, Fr as F, X as Fn, vn as Ft, mr as G, F as Gn, en as Gt, Sr as H, V as Hn, fn as Ht, Nr as I, ke as In, yn as It, fr as J, T as Jn, Jt, pr as K, N as Kn, $t as Kt, Mr as L, Ee as Ln, hn as Lt, zr as M, Pe as Mn, Cn as Mt, Ir as N, Ae as Nn, bn as Nt, mi as O, Ke as On, Dn as Ot, Pr as P, je as Pn, _n as Pt, Kn as Q, k as Qn, Kt as Qt, kr as R, be as Rn, mn as Rt, _a as S, ct as Sn, jn as St, ra as T, rt as Tn, En as Tt, br as U, B as Un, sn as Ut, Cr as V, U as Vn, ln as Vt, hr as W, L as Wn, tn as Wt, Gn as X, ee as Xn, qt as Xt, gr as Y, f as Yn, Zt as Yt, Un as Z, u as Zn, Gt as Zt, Ta as _, _t as _n, In as _t, Do as a, jt as an, D as ar, Yn as at, fa as b, ft as bn, Fn as bt, to as c, Pt as cn, g as cr, ur as ct, Xa as d, Ot as dn, E as dr, Bn as dt, zt as en, A as er, Jn as et, Ua as f, gt as fn, zn as ft, ka as g, vt as gn, Ln as gt, Oa as h, yt as hn, Rn as ht, jo as i, Dt as in, h as ir, er as it, Wr as j, Z as jn, Sn as jt, ai as k, qe as kn, An as kt, $a as l, xt as ln, v as lr, qn as lt, Na as m, Ft as mn, Vn as mt, Oo as n, At as nn, w as nr, $n as nt, ko as o, Et as on, p as or, sr as ot, Ra as p, bt as pn, dr as pt, vr as q, O as qn, Qt as qt, Mo as r, St as rn, m as rr, Xn as rt, bo as s, Tt as sn, _ as sr, cr as st, Ao as t, Lt as tn, d as tr, Qn as tt, Za as u, Ct as un, y as ur, Zn as ut, ma as v, It as vn, Nn as vt, pa as w, it as wn, On as wt, da as x, ut as xn, Mn as xt, ga as y, pt as yn, Pn as yt, Or as z, _e as zn, dn as zt };
3789
+ export { Hn as $, ee as $n, Vt as $t, Kr as A, Je as An, xn as At, Tr as B, Ee as Bn, pn as Bt, ha as C, ct as Cn, Tn as Ct, gi as D, rt as Dn, kn as Dt, hi as E, it as En, wn as Et, Fr as F, Pe as Fn, vn as Ft, mr as G, V as Gn, en as Gt, Sr as H, _e as Hn, fn as Ht, Nr as I, Ae as In, yn as It, fr as J, F as Jn, Jt, pr as K, B as Kn, $t as Kt, Mr as L, je as Ln, hn as Lt, zr as M, qe as Mn, Cn as Mt, Ir as N, Ue as Nn, bn as Nt, mi as O, Xe as On, Dn as Ot, Pr as P, Z as Pn, _n as Pt, Kn as Q, f as Qn, Kt as Qt, kr as R, X as Rn, mn as Rt, _a as S, ut as Sn, jn as St, ra as T, st as Tn, En as Tt, br as U, J as Un, sn as Ut, Cr as V, be as Vn, ln as Vt, hr as W, U as Wn, tn as Wt, Gn as X, O as Xn, qt as Xt, gr as Y, N as Yn, Zt as Yt, Un as Z, T as Zn, Gt as Zt, Ta as _, _t as _n, In as _t, Do as a, jt as an, w as ar, Yn as at, fa as b, dt as bn, Fn as bt, to as c, Pt as cn, D as cr, ur as ct, Xa as d, Ot as dn, g as dr, Bn as dt, zt as en, u as er, Jn as et, Ua as f, gt as fn, v as fr, zn as ft, ka as g, vt as gn, Ln as gt, Oa as h, yt as hn, Rn as ht, jo as i, Dt as in, d as ir, er as it, Wr as j, Ke as jn, Sn as jt, ai as k, $e as kn, An as kt, $a as l, xt as ln, p as lr, qn as lt, Na as m, Ft as mn, E as mr, Vn as mt, Oo as n, At as nn, M as nr, $n as nt, ko as o, Et as on, m as or, sr as ot, Ra as p, bt as pn, y as pr, dr as pt, vr as q, L as qn, Qt as qt, Mo as r, St as rn, A as rr, Xn as rt, bo as s, Tt as sn, h as sr, cr as st, Ao as t, Lt as tn, k as tr, Qn as tt, Za as u, Ct as un, _ as ur, Zn as ut, ma as v, It as vn, Nn as vt, pa as w, ot as wn, On as wt, da as x, ft as xn, Mn as xt, ga as y, pt as yn, Pn as yt, Or as z, ke as zn, dn as zt };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imfusion/web-ui",
3
- "version": "0.5.1-dev.21.g2accd17d",
3
+ "version": "0.5.1-dev.23.g913f03e6",
4
4
  "description": "The official Web UI component library for ImFusion web apps",
5
5
  "author": "ImFusion GmbH",
6
6
  "license": "UNLICENSED",
@@ -1194,6 +1194,333 @@
1194
1194
  }
1195
1195
  ]
1196
1196
  },
1197
+ "field": {
1198
+ "root": {
1199
+ "name": "Field.Root",
1200
+ "description": "Field.Root — groups a label, control, validation state, and supporting copy.",
1201
+ "props": [
1202
+ {
1203
+ "name": "actionsRef",
1204
+ "required": false,
1205
+ "type": "RefObject<FieldRootActions | null>",
1206
+ "defaultValue": null,
1207
+ "description": ""
1208
+ },
1209
+ {
1210
+ "name": "className",
1211
+ "required": false,
1212
+ "type": "string | ((state: FieldRootState) => string)",
1213
+ "defaultValue": null,
1214
+ "description": ""
1215
+ },
1216
+ {
1217
+ "name": "dirty",
1218
+ "required": false,
1219
+ "type": "boolean",
1220
+ "defaultValue": null,
1221
+ "description": ""
1222
+ },
1223
+ {
1224
+ "name": "disabled",
1225
+ "required": false,
1226
+ "type": "boolean",
1227
+ "defaultValue": "false",
1228
+ "description": ""
1229
+ },
1230
+ {
1231
+ "name": "invalid",
1232
+ "required": false,
1233
+ "type": "boolean",
1234
+ "defaultValue": null,
1235
+ "description": ""
1236
+ },
1237
+ {
1238
+ "name": "name",
1239
+ "required": false,
1240
+ "type": "string",
1241
+ "defaultValue": null,
1242
+ "description": ""
1243
+ },
1244
+ {
1245
+ "name": "render",
1246
+ "required": false,
1247
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldRootState>",
1248
+ "defaultValue": null,
1249
+ "description": ""
1250
+ },
1251
+ {
1252
+ "name": "style",
1253
+ "required": false,
1254
+ "type": "| CSSProperties\n| ((state: FieldRootState) => CSSProperties)",
1255
+ "defaultValue": null,
1256
+ "description": ""
1257
+ },
1258
+ {
1259
+ "name": "touched",
1260
+ "required": false,
1261
+ "type": "boolean",
1262
+ "defaultValue": null,
1263
+ "description": ""
1264
+ },
1265
+ {
1266
+ "name": "validate",
1267
+ "required": false,
1268
+ "type": "(\n value: unknown,\n formValues: Record<string, any>\n) =>\n | string\n | string[]\n | Promise<string | string[] | null>\n | null",
1269
+ "defaultValue": null,
1270
+ "description": ""
1271
+ },
1272
+ {
1273
+ "name": "validationDebounceTime",
1274
+ "required": false,
1275
+ "type": "number",
1276
+ "defaultValue": "0",
1277
+ "description": ""
1278
+ },
1279
+ {
1280
+ "name": "validationMode",
1281
+ "required": false,
1282
+ "type": "FormValidationMode",
1283
+ "defaultValue": "onSubmit",
1284
+ "description": ""
1285
+ }
1286
+ ]
1287
+ },
1288
+ "subComponents": [
1289
+ {
1290
+ "name": "Field.Control",
1291
+ "description": "Field.Control — a native input control with Field labeling and validation.",
1292
+ "props": [
1293
+ {
1294
+ "name": "className",
1295
+ "required": false,
1296
+ "type": "string | ((state: FieldControlState) => string)",
1297
+ "defaultValue": null,
1298
+ "description": ""
1299
+ },
1300
+ {
1301
+ "name": "defaultValue",
1302
+ "required": false,
1303
+ "type": "string | number | readonly string[]",
1304
+ "defaultValue": null,
1305
+ "description": ""
1306
+ },
1307
+ {
1308
+ "name": "onValueChange",
1309
+ "required": false,
1310
+ "type": "(\n value: string,\n eventDetails: {\n reason: \"none\";\n event: Event;\n cancel: () => void;\n allowPropagation: () => void;\n isCanceled: boolean;\n isPropagationAllowed: boolean;\n trigger: Element;\n }\n) => void",
1311
+ "defaultValue": null,
1312
+ "description": ""
1313
+ },
1314
+ {
1315
+ "name": "render",
1316
+ "required": false,
1317
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldControlState>",
1318
+ "defaultValue": null,
1319
+ "description": ""
1320
+ },
1321
+ {
1322
+ "name": "style",
1323
+ "required": false,
1324
+ "type": "| CSSProperties\n| ((state: FieldControlState) => CSSProperties)",
1325
+ "defaultValue": null,
1326
+ "description": ""
1327
+ }
1328
+ ]
1329
+ },
1330
+ {
1331
+ "name": "Field.Description",
1332
+ "description": "Field.Description — supporting information for a field.",
1333
+ "props": [
1334
+ {
1335
+ "name": "className",
1336
+ "required": false,
1337
+ "type": "| string\n| ((state: FieldDescriptionState) => string)",
1338
+ "defaultValue": null,
1339
+ "description": ""
1340
+ },
1341
+ {
1342
+ "name": "render",
1343
+ "required": false,
1344
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldDescriptionState>",
1345
+ "defaultValue": null,
1346
+ "description": ""
1347
+ },
1348
+ {
1349
+ "name": "style",
1350
+ "required": false,
1351
+ "type": "| CSSProperties\n| ((state: FieldDescriptionState) => CSSProperties)",
1352
+ "defaultValue": null,
1353
+ "description": ""
1354
+ }
1355
+ ]
1356
+ },
1357
+ {
1358
+ "name": "Field.Error",
1359
+ "description": "Field.Error — an inline validation message shown when its match condition fails.",
1360
+ "props": [
1361
+ {
1362
+ "name": "className",
1363
+ "required": false,
1364
+ "type": "string | ((state: FieldErrorState) => string)",
1365
+ "defaultValue": null,
1366
+ "description": ""
1367
+ },
1368
+ {
1369
+ "name": "match",
1370
+ "required": false,
1371
+ "type": "boolean | keyof ValidityState",
1372
+ "defaultValue": null,
1373
+ "description": ""
1374
+ },
1375
+ {
1376
+ "name": "render",
1377
+ "required": false,
1378
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldErrorState>",
1379
+ "defaultValue": null,
1380
+ "description": ""
1381
+ },
1382
+ {
1383
+ "name": "style",
1384
+ "required": false,
1385
+ "type": "| CSSProperties\n| ((state: FieldErrorState) => CSSProperties)",
1386
+ "defaultValue": null,
1387
+ "description": ""
1388
+ }
1389
+ ]
1390
+ },
1391
+ {
1392
+ "name": "Field.Item",
1393
+ "description": "Field.Item — groups one checkable option with its label and description.",
1394
+ "props": [
1395
+ {
1396
+ "name": "className",
1397
+ "required": false,
1398
+ "type": "string | ((state: FieldItemState) => string)",
1399
+ "defaultValue": null,
1400
+ "description": ""
1401
+ },
1402
+ {
1403
+ "name": "disabled",
1404
+ "required": false,
1405
+ "type": "boolean",
1406
+ "defaultValue": "false",
1407
+ "description": ""
1408
+ },
1409
+ {
1410
+ "name": "render",
1411
+ "required": false,
1412
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldItemState>",
1413
+ "defaultValue": null,
1414
+ "description": ""
1415
+ },
1416
+ {
1417
+ "name": "style",
1418
+ "required": false,
1419
+ "type": "| CSSProperties\n| ((state: FieldItemState) => CSSProperties)",
1420
+ "defaultValue": null,
1421
+ "description": ""
1422
+ }
1423
+ ]
1424
+ },
1425
+ {
1426
+ "name": "Field.Label",
1427
+ "description": "Field.Label — an accessible label automatically associated with the control.",
1428
+ "props": [
1429
+ {
1430
+ "name": "className",
1431
+ "required": false,
1432
+ "type": "string | ((state: FieldLabelState) => string)",
1433
+ "defaultValue": null,
1434
+ "description": ""
1435
+ },
1436
+ {
1437
+ "name": "nativeLabel",
1438
+ "required": false,
1439
+ "type": "boolean",
1440
+ "defaultValue": "true",
1441
+ "description": ""
1442
+ },
1443
+ {
1444
+ "name": "render",
1445
+ "required": false,
1446
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldLabelState>",
1447
+ "defaultValue": null,
1448
+ "description": ""
1449
+ },
1450
+ {
1451
+ "name": "style",
1452
+ "required": false,
1453
+ "type": "| CSSProperties\n| ((state: FieldLabelState) => CSSProperties)",
1454
+ "defaultValue": null,
1455
+ "description": ""
1456
+ }
1457
+ ]
1458
+ },
1459
+ {
1460
+ "name": "Field.Validity",
1461
+ "description": "Field.Validity — renderless access to the field validity data for custom messages.\nIts function child owns the rendered element and therefore its identity and styling.",
1462
+ "props": []
1463
+ }
1464
+ ]
1465
+ },
1466
+ "fieldset": {
1467
+ "root": {
1468
+ "name": "Fieldset.Root",
1469
+ "description": "Fieldset.Root — semantic grouping for related form controls and a shared legend.",
1470
+ "props": [
1471
+ {
1472
+ "name": "className",
1473
+ "required": false,
1474
+ "type": "string | ((state: FieldsetRootState) => string)",
1475
+ "defaultValue": null,
1476
+ "description": ""
1477
+ },
1478
+ {
1479
+ "name": "render",
1480
+ "required": false,
1481
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldsetRootState>",
1482
+ "defaultValue": null,
1483
+ "description": ""
1484
+ },
1485
+ {
1486
+ "name": "style",
1487
+ "required": false,
1488
+ "type": "| CSSProperties\n| ((state: FieldsetRootState) => CSSProperties)",
1489
+ "defaultValue": null,
1490
+ "description": ""
1491
+ }
1492
+ ]
1493
+ },
1494
+ "subComponents": [
1495
+ {
1496
+ "name": "Fieldset.Legend",
1497
+ "description": "Fieldset.Legend — the accessible label for its related controls.",
1498
+ "props": [
1499
+ {
1500
+ "name": "className",
1501
+ "required": false,
1502
+ "type": "string | ((state: FieldsetLegendState) => string)",
1503
+ "defaultValue": null,
1504
+ "description": ""
1505
+ },
1506
+ {
1507
+ "name": "render",
1508
+ "required": false,
1509
+ "type": "| ReactElement<\n unknown,\n string | JSXElementConstructor<any>\n >\n| ComponentRenderFn<HTMLProps, FieldsetLegendState>",
1510
+ "defaultValue": null,
1511
+ "description": ""
1512
+ },
1513
+ {
1514
+ "name": "style",
1515
+ "required": false,
1516
+ "type": "| CSSProperties\n| ((state: FieldsetLegendState) => CSSProperties)",
1517
+ "defaultValue": null,
1518
+ "description": ""
1519
+ }
1520
+ ]
1521
+ }
1522
+ ]
1523
+ },
1197
1524
  "input": {
1198
1525
  "root": {
1199
1526
  "name": "Input",
@@ -73,6 +73,18 @@ Off-canvas panel that slides in from a screen edge. Use for mobile navigation, s
73
73
  - props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .drawer (jq: jq '.drawer' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
74
74
  - further reading (usage/anatomy, not props): https://base-ui.com/react/components/drawer.md
75
75
 
76
+ ## Field
77
+ - category: Inputs, status: stable
78
+ Accessible field composition for a label, form control, supporting description, and inline validation message. Use it to associate a control such as Input, Checkbox, or Select with field state including valid, invalid, dirty, touched, filled, and focused.
79
+ - props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .field (jq: jq '.field' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
80
+ - further reading (usage/anatomy, not props): https://base-ui.com/react/components/field.md
81
+
82
+ ## Fieldset
83
+ - category: Inputs, status: stable
84
+ Semantic grouping for related form controls with a shared legend. Also called a form group; use it to communicate a common topic and propagate disabled state without introducing a decorative container.
85
+ - props: node_modules/@imfusion/web-ui/src/docgen/doc.gen.json -> .fieldset (jq: jq '.fieldset' node_modules/@imfusion/web-ui/src/docgen/doc.gen.json)
86
+ - further reading (usage/anatomy, not props): https://base-ui.com/react/components/fieldset.md
87
+
76
88
  ## ImageDisplayOptions
77
89
  - category: Inputs, status: experimental
78
90
  A panel or toolbar of controls bound to an image dataset's display options.
@@ -2,14 +2,16 @@
2
2
  name: imf-web-ui-update
3
3
  description:
4
4
  "Update @imfusion/web-ui in a consumer repository: refresh the package and vendored skills, audit and optionally install
5
- lifecycle hooks, handle conflicts, verify the result, and obtain explicit approval before committing."
5
+ lifecycle hooks, verify the base update, then audit and optionally migrate affected or custom consumer components in a
6
+ separate approved commit."
6
7
  argument-hint: "[--dry-run] [optional version or reason]"
7
8
  ---
8
9
 
9
10
  # imf-web-ui-update
10
11
 
11
- Update a repository that consumes `@imfusion/web-ui`. Preserve existing project choices and user work. Never commit without a
12
- fresh explicit approval.
12
+ Update a repository that consumes `@imfusion/web-ui`. Preserve existing project choices and user work. The workflow has two
13
+ commits: the dependency/tooling update first, then an optional consumer migration. Never commit without a fresh explicit
14
+ approval.
13
15
 
14
16
  ## Rules
15
17
 
@@ -23,6 +25,12 @@ fresh explicit approval.
23
25
  - A dirty file that the workflow needs to modify is a conflict. Stop and report it. This includes package files, installed
24
26
  skill directories, the `AGENTS.md` installer fence, hook files, and hook settings.
25
27
  - Do not hand-edit installer-owned skills, the `AGENTS.md` fenced block, or installer-owned hook files.
28
+ - Keep the base update and consumer migration in separate commits. Do not begin the migration audit until the base update
29
+ commit is complete.
30
+ - Treat the installed package version before the update as the comparison baseline. There is no assumed changelog.
31
+ - A migration candidate is a custom consumer implementation whose behavior overlaps with a current web-ui component, or an
32
+ existing web-ui usage affected by changed types or documented API. Do not infer a replacement from a name alone; inspect
33
+ the implementation and the current component documentation/types.
26
34
 
27
35
  ## Preflight
28
36
 
@@ -32,7 +40,7 @@ fresh explicit approval.
32
40
  4. Inspect `.agents/skills/`, `.claude/skills/`, the `AGENTS.md` fence, `.claude/settings.json`, and `.agents/hooks/`.
33
41
  5. Check for another package-manager process. Stop on any conflict or ambiguous target.
34
42
 
35
- ## Update
43
+ ## Base update
36
44
 
37
45
  In a non-dry run, update the dependency with the detected manager:
38
46
 
@@ -71,7 +79,7 @@ Audit these responsibilities separately: session start, prompt submit, and post-
71
79
 
72
80
  A declined hook offer is valid. Report `hooks: skipped by user` and continue.
73
81
 
74
- ## Conflict and verification
82
+ ## Verification
75
83
 
76
84
  After each mutating command, compare `git status --short` with the preflight snapshot.
77
85
 
@@ -83,12 +91,18 @@ Classify paths as:
83
91
 
84
92
  On conflict, stop. Never use `git restore`, `git reset`, `git clean`, or broad staging to hide it.
85
93
 
86
- Run only scripts documented by the frontend's `package.json`. Verify the dependency/lockfile, current skill markers, the
87
- `AGENTS.md` fence, hook coverage, and the final path list. In dry-run mode, say that mutation-dependent checks were skipped.
94
+ Run the frontend package's documented full verification after the base update. Read its `package.json` scripts and choose
95
+ commands that cover typechecking, linting, tests, and building. Prefer one documented aggregate `verify`/`check` script when
96
+ it covers those responsibilities; otherwise run the documented non-watch scripts for the responsibilities that exist. Do not
97
+ invent script names or run watch/dev scripts. A type or build failure is a base-update conflict to resolve before the base
98
+ commit, not a migration finding to defer.
88
99
 
89
- ## Report and approval
100
+ Verify the dependency/lockfile, current skill markers, the `AGENTS.md` fence, hook coverage, and the final path list. In
101
+ dry-run mode, say that mutation-dependent checks were skipped.
90
102
 
91
- Before any commit, show this concise report:
103
+ ## Base update report and approval
104
+
105
+ Before the base commit, show this concise report:
92
106
 
93
107
  ```text
94
108
  @imfusion/web-ui update report
@@ -107,13 +121,45 @@ answer. If denied, leave the changes uncommitted.
107
121
 
108
122
  Dry-run mode: state **“Dry run complete; no changes or commit were made.”** Do not mutate or ask for commit approval.
109
123
 
124
+ ## Consumer migration audit
125
+
126
+ Begin this phase only after the approved base update has been committed. Record the old and new package versions from the
127
+ pre-update and current manifests/lockfile. Use the current package's exported types, generated documentation, and component
128
+ examples as the source of truth. Use the old version's package metadata or repository history when available to identify what
129
+ changed; do not pretend a changelog exists.
130
+
131
+ Run the same documented full verification again after the base commit. Separate findings into:
132
+
133
+ - **Compatibility fixes:** existing web-ui imports, props, or usage patterns that no longer typecheck, build, lint, or pass
134
+ tests.
135
+ - **Changed component usages:** existing components whose current API, behavior, or documented contract changed between the
136
+ two versions and may need a consumer update, even when the typecheck passes.
137
+ - **Replacement candidates:** custom consumer components, wrappers, or field implementations that overlap with a component
138
+ now exported by `@imfusion/web-ui`. Inspect their code, styles, and call sites before suggesting a replacement. Include the
139
+ current custom implementation, the proposed web-ui component, the relevant API/type evidence, and any behavior or styling
140
+ that still needs to be preserved.
141
+
142
+ Report these findings separately from the base update. Ask whether to apply the proposed migration. If the user declines,
143
+ leave the consumer code unchanged. If accepted, make only the approved migration changes, run the documented full
144
+ verification again, and show a second report with the migration paths, held-back paths, conflicts, and verification result.
145
+
146
+ If no findings exist, report that the installed update has no detected compatibility fixes, changed usages, or replacement
147
+ candidates. Do not create an empty migration commit.
148
+
149
+ ## Migration approval
150
+
151
+ Ask exactly, **“Approve these consumer migration changes and commit them separately?”** Do not commit without an affirmative
152
+ answer. The migration approval is not implied by approval of the base update.
153
+
110
154
  ## Commit
111
155
 
112
- After approval:
156
+ For the base update, after approval:
113
157
 
114
158
  1. Recheck status and exclude held-back paths.
115
- 2. Stage update-owned paths selectively. Never use `git add .` or `git add -A`.
159
+ 2. Stage base update-owned paths selectively. Never use `git add .` or `git add -A`.
116
160
  3. Run the repository's commit workflow if it has one, including its required verification and documentation audit. Otherwise
117
161
  run documented verification and follow the repository's commit convention.
118
- 4. Commit with a concise imperative message and confirm the commit and final status. Never bypass hooks or amend an unrelated
119
- commit after a hook failure.
162
+ 4. Commit with a concise imperative message and confirm the commit and final status.
163
+
164
+ For an approved migration, repeat the same selective staging and documented commit workflow with a separate imperative
165
+ message. Never bypass hooks or amend an unrelated commit after a hook failure.