@manohub/kit 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRACT.md CHANGED
@@ -86,8 +86,18 @@ theme 提供令牌(值),icon 提供图形。**本包不发布任何样式*
86
86
  - **顺序不可换**:先值(令牌)后面(组件面)。反过来的话组件面里的 `var(--ui-*)` 全是空值。
87
87
  - 用非兜底主题时把 ① 换成对应入口(如 `@manohub/theme/farris.css`),
88
88
  并在入口给 `createSubApp({ theme: 'farris' })`(写到容器的 `data-theme` 上)。
89
- - **本包不提供 `reset.css`,也不提供富文本预设**:应用侧需要时自己写(仍受 §3 的样式纪律约束)。
90
- 富文本排版目前没有合规归属,见 §10 的已知缺口。
89
+ - **`reset`(元素级基线)自 0.7.0 起已内置在 ② 里**,不需要第三行:`@manohub/ui/styles.css` 的**首条** import
90
+ 就是它(盒模型、按钮外观、列表序号、链接下划线、标题字阶一并归零)。作用域锚 `[data-manohub-ui]`
91
+ 且特异性为 0,**应用侧写任何元素选择器都能盖过它**。(0.6.x 没有它,那两版的应用侧自补过一份 —— 见 §12.2。)
92
+ - **入口基线(`html` / `body` / `#app` 的高度链)归消费方,且是合法的**:本包的 reset **有意不写**这三个
93
+ 选择器 —— micro-app 的 `scopecss` 不作用域化它们,包内写进去会泄漏到宿主全局。但「页面撑满」这条链
94
+ **必须有人给**(`Page` 的 `height: 100%` 依赖它),所以它由**应用的入口基线**承担:写在 ③ 里,
95
+ 或写在入口 HTML 的 `<style>` 里。典型形态是「`html` / `body` / `#app` 三个 `height: 100%` + `margin: 0`」。
96
+ 这是 L1-6「不得用裸元素选择器」的**唯一例外**(`html` / `body` / `#app` 三个名字),
97
+ 用到的属性全在 L1-4 白名单内。**别把这条链写进组件 / 页面样式** —— 它只属于入口。
98
+ - **富文本(markdown)要自行复权**:reset 归零了 `ul` / `ol` 的序号与 `a` 的下划线,
99
+ 而富文本排版没有合规归属(见 §10 的已知缺口)—— 消费方须为自己的富文本容器类补回
100
+ `list-style` / 链接样式 / 段落边距。
91
101
 
92
102
  ### 1.3 入口
93
103
 
@@ -166,14 +176,13 @@ configureHost(hostEl)
166
176
  | --- | --- | --- |
167
177
  | **L1-1 应用侧不持有值** | 应用侧的 `--*` 自定义属性**一处都不该有**。只有两种合法写法:① **重设已存在的令牌**(局部换肤)② 不写 | 值的唯一来源是 theme。局部换肤是合法且推荐的(见下) |
168
178
  | **L1-2 引用必须存在** | 每个 `var(--xxx)` 的 `--xxx` 必须能在 theme 六片或 `<件>.tokens.css` 里**搜到**。**新增令牌名一律违规** | 写错名字不会报错,只会静默回退成默认值 |
169
- | **L1-3 禁 `:root` / `html` / `body`** | 选择器里**不得出现** `:root` / `html` / `body` | `scopecss` 不作用域化 `:root`,会泄漏到宿主 |
170
- | **L1-4 尺寸取令牌** | 尺寸取 `--ui-space-*` / `--ui-radius-*` / `--ui-control-height-*` / `--ui-row-height` / `--ui-grid-column-min`;**几何是设计基准、不跟根字号**,故禁 `rem`;内距给 **px 数字**(与 `Padding` 同口径) | 设计基准不随宿主根字号分叉 |
171
- | **L1-5 只写布局属性** | `<style>` 与 `style={{ }}` 里的属性名必须在**下面的白名单**内 | theme 是视觉的唯一来源 |
172
- | **L1-6 类名形状** | 类名一律 `<本仓命名空间>-<kebab-case>`。落点 A:CSS 选择器**首段**;落点 B:`class=` 的**每个 token** | 两个应用装进同一页面时不能撞名 |
173
- | **L1-7 不碰库的类** | 选择器里**不得出现 `.mh-`**;不得用 `!important`;不得用裸元素选择器与 `*` | `.mh-*` 与档位类归 ui;覆写升版即静默失效 |
174
- | **L1-8 不引 Tailwind** | 全仓不得出现 `tailwindcss` / `@tailwindcss/` / `@theme` | theme 只认自己的 `@import './…css'` |
179
+ | **L1-3 尺寸取令牌** | 尺寸取 `--ui-space-*` / `--ui-radius-*` / `--ui-control-height-*` / `--ui-row-height` / `--ui-grid-column-min`;**几何是设计基准、不跟根字号**,故禁 `rem`;内距给 **px 数字**(与 `Padding` 同口径) | 设计基准不随宿主根字号分叉 |
180
+ | **L1-4 只写布局属性** | `<style>` 与 `style={{ }}` 里的属性名必须在**下面的白名单**内 | theme 是视觉的唯一来源 |
181
+ | **L1-5 类名形状** | 类名一律 `<本仓命名空间>-<kebab-case>`。落点 A:CSS 选择器**首段**;落点 B:`class=` 的**每个 token** | 两个应用装进同一页面时不能撞名 |
182
+ | **L1-6 不碰库的类** | 选择器里**不得出现 `.mh-`**;不得用 `!important`;不得用裸元素选择器与 `*`。**唯一例外:入口基线**(`html` / `body` / `#app` 三个选择器及其高度链,见 §1.2)| `.mh-*` 与档位类归 ui;覆写升版即静默失效 |
183
+ | **L1-7 不引 Tailwind** | 全仓不得出现 `tailwindcss` / `@tailwindcss/` / `@theme` | theme 只认自己的 `@import './…css'` |
175
184
 
176
- ### L1-5 的属性白名单(闭集,逐字照用)
185
+ ### L1-4 的属性白名单(闭集,逐字照用)
177
186
 
178
187
  ```
179
188
  盒模型与定位:display / position / inset / top / right / bottom / left / z-index / box-sizing /
@@ -378,7 +387,7 @@ configureHost(hostEl)
378
387
  | --- | --- | --- |
379
388
  | **L3-1 件白名单** | 只用导出表里的件;复合成员**只走点号**;**先查 `.d.ts` 再写** | README 与文档会漂移(`Page.Toolbar` / `Input.Group` / `Input.Chip` 都曾出现在文档里,实际不存在) |
380
389
  | **L3-2 外观只走语义 prop** | 改外观**只能**用件自己的 prop(语义词表共 **26 个维度**,逐个列在 §0 指的那份 `.d.ts` 里)或**换件**;**不得写 CSS 改外观** | 「不写 CSS 也能改外观」是这套库的全部答案 |
381
- | **L3-3 import 源白名单** | 只允许:框架(`vue` / `vue-router` / `pinia` / `@tanstack/vue-query` / `vue-i18n`)· `@manohub/ui`(子路径只认 `styles.css`)· `@manohub/icon`(或 `/glyphs`)· `@manohub/theme`(只认 `default.css` / `farris.css`)· `@manohub/kit/entry`。**其余一律违规** | 黑名单每天漏一个,白名单零维护 |
390
+ | **L3-3 外观来源白名单** | **外观**只能来自这几处:`@manohub/ui`(子路径只认 `styles.css`)· `@manohub/icon`(或 `/glyphs`)· `@manohub/theme`(只认 `default.css` / `farris.css`)· `@manohub/kit/entry`(编排,零外观)。**不得从别处取外观**:不引第三方组件库 / CSS 框架 / 图标库,不直连底层组件库,不自绘(含手写 `<svg>` 与文字符号)。**不在本条款管辖内的**(它们不产生外观):① 框架与运行时(`vue` / `vue-router` / `pinia` / `@tanstack/vue-query` / `vue-i18n` / 微前端运行时);② 本仓**业务域自有包**(`@manohub/*` 里不在上列者,如 `@manohub/api-client`);③ **不产生外观的行为库**(拖拽 / 虚拟滚动 / 图表计算一类,只给行为与数据结构)。判据是「**它是不是外观来源**」,不是「它是不是依赖」 | 白名单管的是外观的**来源**。写成「import 清单」会把业务包与行为库一起圈进来 ⇒ 每个已迁移应用都命中一条「不可登记」的违规,而那条违规与「不引第三方组件库」的立法本意毫无关系 |
382
391
  | **L3-4 交互不走原生控件** | 按钮 / 输入 / 下拉 / 文本域一律用组件;`<button>` `<input>` `<select>` `<textarea>` **带 `class` 承载外观**违规;**无 `href` 的 `<a class>`** 违规(「按钮的伪装」) | 原生控件拿不到令牌、键盘与语义也不对 |
383
392
  | **L3-5 浮层归组件与服务层** | 模态 → `Dialog`;贴边 → `Drawer`;轻提示 → `toast()`;确认 / 告知 → `confirm()` / `alert()`;忙等 → `showLoading()`。**不自己写 `position: fixed` + `z-index` 的遮罩** | 自建遮罩拿不到令牌,也逃不过微前端的 `scopecss` |
384
393
 
@@ -409,13 +418,15 @@ configureHost(hostEl)
409
418
  ### 正误对照
410
419
 
411
420
  ```tsx
412
- // ✗ import 越界 / 用不存在的成员 / 传底层风格的 prop
421
+ // ✗ 从别处取外观 / 用不存在的成员 / 传底层风格的 prop
413
422
  import { Table } from '@farris/ui-vue'
414
423
  import { Button } from '@manohub/ui/dist/components/button'
415
424
  <Page.Toolbar /> <Input.Group />
416
425
  <Table valueField="id" :rowOption="{ … }" />
417
426
  // ✓
418
427
  import { Page, Panel, Table, Button } from '@manohub/ui'
428
+ import { repositoriesApi } from '@manohub/api-client' // 业务包:不产生外观,L3-3 不管
429
+ import Sortable from 'sortablejs' // 行为库:不产生外观,L3-3 不管
419
430
  <Page.Header :extra="<Search … />" />
420
431
  ```
421
432
 
@@ -429,7 +440,7 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
429
440
 
430
441
  **L0**
431
442
 
432
- 1. 我的样式链前两条 `@import` 逐字对吗?顺序对吗(theme 在前)?
443
+ 1. 我的样式链前两条 `@import` 逐字对吗?顺序对吗(theme 在前)?**入口基线**(`html` / `body` / `#app` 的高度链)给了吗(在 ③ 里或入口 HTML 里)?
433
444
  2. 有没有自己写 `data-manohub-ui`?有没有依赖 `.app-container`?
434
445
  3. `createSubApp` 还是只有一处?`createI18n` 是 0 次吗?
435
446
 
@@ -438,7 +449,7 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
438
449
  4. 我写的每个 CSS 属性,都在 §3 的白名单里吗?把不在的列出来。
439
450
  5. 我写的每个 `var(--xxx)`,在 theme 六片或 `<件>.tokens.css` 里搜得到吗?
440
451
  6. 我有没有**新增** `--` 开头的名字(而不是重设已有令牌的值)?
441
- 7. 类名都以本仓命名空间开头吗?`class=` 里每个 token 都过了吗?有没有 `.mh-` / `!important` / `rem` / `:root` / 裸元素选择器 / `tailwind`?
452
+ 7. 类名都以本仓命名空间开头吗?`class=` 里每个 token 都过了吗?有没有 `.mh-` / `!important` / `rem` / 裸元素选择器 / `tailwind`?(**入口基线的 `html` / `body` / `#app` 除外** —— 那是唯一例外)
442
453
  8. 尺寸值都取令牌了吗?
443
454
 
444
455
  **L1.5**
@@ -463,7 +474,7 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
463
474
 
464
475
  21. 我用的每个件都在导出表里吗?每个复合成员都在成员表里吗?
465
476
  22. 我传的每个 prop 都能在 `.d.ts` 里找到吗?改外观是走词表维度而不是写 CSS 吗?
466
- 23. 我新增的 import 源都在 §6 L3-3 那 5 处里吗?图标的入口是主入口(不是 `/glyphs`)吗?有没有用原生控件承载外观(含无 `href` 的 `<a class>`)?
477
+ 23. 我用到的每个 import,**有没有哪一处是从 L3-3 白名单之外取外观的**?(业务域自有包与不产生外观的行为库不在 L3-3 管辖内。)图标的入口是主入口(不是 `/glyphs`)吗?有没有用原生控件承载外观(含无 `href` 的 `<a class>`)?
467
478
  24. 浮层走组件 / 服务层了吗?微前端下宿主落回本应用容器了吗?
468
479
 
469
480
  ---
@@ -510,9 +521,11 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
510
521
  | `Filter` 无关键字输入与就绪轮询 | 「关键字」就是普通 `Filter.Item` + `Input`;就绪时序归页面 |
511
522
  | `Form` 只有一个头 | 分组用 `Panel` 或拆区域——多头会让「哪个头管哪些字段」说不清 |
512
523
  | 命令式服务不提供异步 `confirm` | 需要「确定按钮进加载态」时直接用 `Dialog` 的 `onOk`(返回 Promise 自动进加载态) |
524
+ | 命令式 `confirm()` / `alert()` **显式关掉**「点遮罩关闭」 | 组件形态默认**开**(与主流一致,见 §12.2);命令式一条误点就丢一次决策,故显式关掉 —— 与 AntD 的 `<Modal maskClosable>`(开)/ `Modal.confirm`(关)同一分工 |
525
+ | `Text` 只做六个维度(字号 / 行高 / 字重 / 语义色 / 等宽 / 截断) | 它补的是「容器里的文字层级」这条一直缺的路径;富文本解析、省略的展开交互都不归它 |
513
526
  | 本包零样式(无 reset、无富文本预设) | 样式只有两个来源:theme(值)与 ui(面)。本包夹在中间转发样式,只会让「值的来源」说不清 |
514
527
  | `theme` **有意不建 icons / motion 两片** | 图标不承载颜色(随文案色,见 L1.5-3);动效目前没有跨组件统一的语义。这两片是**有意未建**,不是遗漏 |
515
- | **已知缺口:富文本排版暂无归属** | 此前由本包的 `.app-markdown` 预设承担,现已随样式一并删除;而 §3 又禁应用侧写 `font-size` 与裸元素选择器——需要富文本排版的页面暂时只能整段进 §11 登记,或在 ui 提一个 `Markdown` 件 |
528
+ | **已知缺口:富文本排版暂无归属** | 此前由本包的 `.app-markdown` 预设承担,已随样式删除;`@manohub/ui` 的 `reset` 又归零了 `ul` / `ol` 的序号与 `a` 的下划线,**富文本容器必须自己补回** `list-style` / 链接样式 / 段落边距。需要富文本排版的页面暂时只能整段进 §11 登记,或在 ui 提一个 `Markdown` 件 |
516
529
 
517
530
  ---
518
531
 
@@ -523,8 +536,8 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
523
536
 
524
537
  - 登记的作用是**让下一个人知道**:这里为什么和 §3 不一样、改它要人工确认。
525
538
  - **色值字面量只减不增**:登记之后新加的视觉值仍然违规。
526
- - **登记不放行的是这些**(无论怎么登记都仍然违规):导入越界(L3-3)、自绘页头 / 面板头(L2-3)、
527
- 原生控件承载外观(L3-4)、`!important`、`.mh-*` 覆写、`:root`、令牌名拼错(L1-2)。
539
+ - **登记不放行的是这些**(无论怎么登记都仍然违规):从白名单之外取外观(L3-3)、自绘页头 / 面板头(L2-3)、
540
+ 原生控件承载外观(L3-4)、`!important`、`.mh-*` 覆写、令牌名拼错(L1-2)。
528
541
 
529
542
  登记表放本工程的 `docs/figma-fidelity.md`,格式:
530
543
 
@@ -538,12 +551,15 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
538
551
 
539
552
  ## §12 升级(破坏性)
540
553
 
541
- > **版本口径**:本次统一发 **0.6.0**(上一个已发布版本是 `@manohub/app-kit@0.4.3`)。
542
- > 下面三组变化是**同一次重构**的三个面 —— 组件换库、主题与样式链独立、契约与护栏重做,
554
+ > **版本口径**:**0.6.0** 是一次四包重构(上一个已发布版本是 `@manohub/app-kit@0.4.3`);
555
+ > 下面 12.1 的三组变化是**同一次重构**的三个面 —— 组件换库、主题与样式链独立、契约与护栏重做,
543
556
  > **不存在「先升到某个中间版本」的路径**,一次性做完。`AppShell` → `Page` 与 `AppTable` → `Table`
544
557
  > 常常落在同一处代码,拆成几轮只会把同一段改两遍。
558
+ >
559
+ > **0.7.0** 是它之后的第一批修复与补齐(12.2),带去**四处行为变更** ——
560
+ > 从 0.6.x 升上来的应用**只需读 12.2**。
545
561
 
546
- ### 12.1 本次(0.4.3 → 0.6.0)变了什么
562
+ ### 12.1 四包重构(0.4.3 → 0.6.0)变了什么
547
563
 
548
564
  **一、组件换库(`App*` 与 `.ak-*` 退场)**
549
565
 
@@ -565,22 +581,68 @@ import { Page, Panel, Table, Button } from '@manohub/ui'
565
581
  | **属性锚改名** | 容器上的 `data-app-container` → **`data-manohub-ui`**;旧名不再被任何一方识别(不留兼容别名) |
566
582
  | **作用域统一** | 主题令牌、组件令牌、服务层宿主解析**全锚 `data-manohub-ui` 一个属性** |
567
583
  | **组件令牌变可覆盖** | 组件令牌基础值锚从「元件根类」上提到「容器锚」——表行高、label 宽这类终于能在容器上被覆盖(也可被误覆盖) |
584
+ | **`reset` 改由 `@manohub/ui` 提供(0.7.0)** | 元素级基线并入 `@manohub/ui/styles.css` 的**首条** import(锚 `[data-manohub-ui]`、特异性 0):应用侧不必再自己写 reset,消费方自建的全局 reset 可以移除 —— 但**富文本容器的复权要保留**(reset 归零了 `ul` / `ol` 的序号与 `a` 的下划线) |
568
585
 
569
586
  **三、契约与护栏(本文件与 §7 自检清单)**
570
587
 
571
588
  | 变化 | 说明 |
572
589
  | --- | --- |
573
590
  | **契约改成五层** | 本文件重写为 L0 / L1 / L1.5 / L2 / L3 五层,每条判据是**闭集**;原先按「检查手段」分的样式 / 接口 / 结构三域并入层内 |
574
- | **`kit lint` 系列命令移除** | 三条脚本护栏(样式 / 接口 / 结构)整体下线,改为**本文 + §7 自检清单**。原 `appkit-guardrails.config.json` 不再被读取,请删除 |
591
+ | **`kit lint` 系列命令移除** | 三条脚本护栏(样式 / 接口 / 结构)整体下线,改为**本文 + §7 自检清单**。原 `appkit-guardrails.config.json` 不再被读取,请删除。(**0.7.0 起 `lint` 以新的立足点恢复**,见 §12.2 第三项) |
575
592
  | **`api/*` 判据改白名单** | import 源从「黑名单」改为 5 处白名单(L3-3),更严 |
576
593
  | **图标层进契约** | 新增 L1.5 七条(来源 / 尺寸 / 颜色 / 方位 / 裸符号 / 名清单 / 入口),原先只在包内自测 |
577
594
  | **骨架层补齐** | L2 从「几种页面模板」扩到 20 条,含归位、直接子节点、页头两模式、区域头形态等原先没写下的规则 |
578
595
 
579
- **三组一起怎么迁**:装包 → 样式链改由自己引(§1.2 两行)→ 换主题入口 → 自建容器换锚 →
580
- 补回 reset 与富文本(或提件)→ 换骨架与件 → 收样式与图形。类名 `class="app-container"` 不必动
596
+ **三组一起怎么迁**:装包 → 样式链改由自己引(§1.2 两行;reset 自 0.7.0 起内含在 ② 里)→ 换主题入口 →
597
+ 自建容器换锚 → 补富文本复权(或提件)→ 换骨架与件 → 收样式与图形。类名 `class="app-container"` 不必动
581
598
  (已降级为本包内部命名)。
582
599
 
583
- ### 12.2 存量应用怎么迁
600
+ ### 12.2 修复与补齐(0.6.x → 0.7.0)变了什么
601
+
602
+ #### 一、行为变更(五处,逐条确认)
603
+
604
+ | 变更 | 0.6.x | 0.7.0 | 为什么要改 / 怎么迁 |
605
+ | --- | --- | --- | --- |
606
+ | `Dialog` / `Drawer` 的 `closeOnBackdrop` / `maskClosable` | `false` | **`true`** | 点遮罩**从此会关**。组件形态跟主流(Element Plus 的 `close-on-click-modal`、AntD 的 `<Modal maskClosable>` 都是开);「防误关」是**命令式**的口径,`confirm()` / `alert()` 已显式关掉,**不受影响**。表单类弹窗若怕手滑丢内容,自己传 `:close-on-backdrop="false"` |
607
+ | `Upload.multiple` | `true` | **`false`** | 此前默认多选 + `maxCount` 不限量 ⇒ 单文件场景会**静默多收**。要多选显式给 `multiple` |
608
+ | `Notice` 的图标位 | `showIcon`(`boolean`) | **`icon`**(`boolean \| IconName`) | 与 `Toast` / `Notification` **同名同型**(三件原本三个名字)。模板里 `show-icon` → `icon` |
609
+ | `Search` 的触发位 | 只认 `searchText` | 新增 `action="icon"` | **取值不冲突**:不传 `action` 的行为一字未变。要「只有图标按钮可点」这一档时用它(框内的装饰放大镜会自动让位,不会同屏两个放大镜) |
610
+ | **`@manohub/icon` 的 7 个字形名** | `bell` / `wrench` / `heart` / `heart-filled` / `eye` / `grid-dots` / `sparkles` | **`notification` / `tool` / `favorite` / `favorite-filled` / `preview` / `apps` + `drag-handle` / `ai`** | 旧名说的是「画的是什么」,不是「该在什么场景用它」。**不给别名**(`IconName` 是 `keyof`,没有 alias 层)—— 升级后按类型报错逐个替换,对照表见 icon 包 README。`grid-dots` 原是一位两用(宫格入口 + 拖拽手柄),拆成 `apps` 与 `drag-handle` 两个字形 |
611
+
612
+ #### 二、修复(不改行为,只修外观与可用性)
613
+
614
+ | 修复 | 0.6.x 的表现 |
615
+ | --- | --- |
616
+ | `Select` 的选项行补按钮重置(`border` / `background` / `font-family` / `text-align` 四条) | 选项行呈**原生按钮外观**:灰底 + 2px 立体边框 + 居中 Arial —— 而同一个面板里的「创建 xxx」行是正常的(那个类写齐了重置) |
617
+ | `Dialog` 补三段 flex 布局 + 新增 `panelHeight` | 设固定高度时**底栏不贴底**(body 只有内容高,剩余空间全留在 footer 之后);且此前「固定高度」只能经 `attrs.style` 传给未定义路径 |
618
+ | `Tabs` / `Tabset` 补 `emits.update:value` | `v-model:value="current"` **静默失效** —— 受控值不变、内部也不更新,点 tab **毫无反应且不报错**(两件的文档注释都教 `v-model:value`) |
619
+ | `reset` 的两条明文禁例对齐实现 | 契约曾写「选择器里不得出现 `:root` / `html` / `body`」,而 reset 自身又要求「整链高度由消费方自理」 ⇒ 那条链既必须给、又不得写。**该条款已删除**,入口基线改为显式合法(见 §1.2) |
620
+ | L3-3 的措辞 | 旧文写成「import 源白名单」,把**业务域自有包**(`@manohub/api-client`)与**不产生外观的行为库**也判成越界;而契约 §11 又把「导入越界」列为**登记也不放行** ⇒ 每个已迁移应用都带着一条不可豁免的违规。**已改为「外观来源白名单」** |
621
+
622
+ #### 三、补齐(新增的能力与路径)
623
+
624
+ - **`drag-handle`**(`@manohub/icon`):6 点拖拽手柄(2 列 × 3 行)。原先列表排序借的是 `grid-dots`,
625
+ 而 `grid-dots` 同时还是「我的技能」的宫格入口 —— 一个字形担两个语义,改一处必然误伤另一处。
626
+ - **`Text`**(`@manohub/ui`):最小排版件(`size` / `tone` / `weight` / `mono` / `truncate` / `as`),
627
+ **消费 theme 一直有、却没有件消费的那套 `--ui-font-*` 档位令牌**。此前「容器里的文字层级」
628
+ (卡片描述、只读值、次级信息)在应用侧无合规落点,每个应用都要为它留一条定版例外登记 ——
629
+ 这条路径至此补上。
630
+ - **`Dialog.tone` 与服务层 `tone`**:`alert()` / `confirm()` 现在能表达 `info` / `success` / `warning` / `error`
631
+ 四档(标题左侧一个裸符号 + 配色),`confirm({ tone: 'error' })` 还会把确定按钮自动染成危险色 ——
632
+ 「删除确认」与「保存成功」不再长得一样。
633
+ - **`reset` 进驻 `@manohub/ui/styles.css` 首条**(0.6.x 里由应用自补):
634
+ **已经在 `app.css` 自补过 reset 的应用,可以删掉其中「盒模型 / 按钮外观 / 列表序号 / 链接 / 标题字阶」这一族
635
+ 与「元素 margin 归零」**(② 已经给了);但**高度链(`html` / `body` / `#app`)必须留着** ——
636
+ 那是入口基线,包的 reset **有意不写**(见 §1.2)。
637
+ - **`kit lint` 恢复**(`pnpm exec kit lint --root apps/<app> --namespace <前缀>`):
638
+ 0.6.0 整批下线后,三个应用迁完就累计出「3 份重复 reset / 1 处登记描述错误 / 1 处注释引错文件名」——
639
+ 都是「有脚本就当场红」的类型。恢复的版本**换了立足点**:不查目录结构,只查本契约里能机械判定的四组
640
+ (`style` 红线条 / `source` 外观来源 / `namespace` 类名前缀 / `property` 属性闭集)。
641
+ ⚠️ 它是**应用侧工具**:L1-4 / L1-6 约束的是「应用自绘的东西」,对四包源码跑必然满屏假红
642
+ (脚本按包名直接拦住并提示该给哪个根)。**它只覆盖能机械判定的部分** ——
643
+ 组件默认值是否与文档一致、骨架归位、三态分工这些仍走 §7 自检清单。
644
+
645
+ ### 12.3 存量应用怎么迁
584
646
 
585
647
  按**层**推进,每步单独可跑通(这也是最优顺序):
586
648
 
package/bin/kit.mjs CHANGED
@@ -10,15 +10,20 @@
10
10
  * pnpm exec kit install --also-claude
11
11
  * pnpm exec kit install --target .x/skills
12
12
  * pnpm exec kit install --dry-run
13
+ * pnpm exec kit lint # 契约机械护栏(默认全跑,只报不修)
14
+ * pnpm exec kit lint --group source --json
13
15
  * pnpm exec kit help
14
16
  *
15
17
  * npm 消费方把 `pnpm exec` 换成 `npx`(两者都解析本地 node_modules/.bin)。
16
18
  * package.json 的 scripts 里可以省略前缀(npm/pnpm 会把 .bin 加进 PATH):
17
19
  * "skills:sync": "kit install"
18
20
  *
19
- * 0.6.0 起 `lint` / `lint:style` / `lint:component` / `lint:structure` 四个子命令**已下线**
20
- * (消费侧机器规则整批退场,合规改为「CONTRACT.md 条款 + §7 自检清单」)。
21
- * 旧脚本若还写着 `kit lint`,会得到「未知命令」并附帮助 —— 不是静默通过。
21
+ * 版本史:
22
+ * - 0.6.0 起 `lint:style` / `lint:component` / `lint:structure`(旧的消费侧机器规则)**已下线**
23
+ * —— 它们按目录/结构硬编码,语义与四包重构后的契约脱节。
24
+ * - 0.7.0 起 `lint` **重新上线**,但换了立足点:不查目录,只查契约里能机械判定的事
25
+ * (外观来源白名单 / 布局属性闭集 / 类名命名空间),见 `skills/lint.mjs` 头注释。
26
+ * 旧脚本若写着已下线的子命令名,会得到「未知命令」并附帮助 —— 不是静默通过。
22
27
  */
23
28
  import { spawnSync } from 'node:child_process'
24
29
  import { existsSync, readFileSync } from 'node:fs'
@@ -37,6 +42,10 @@ export const COMMANDS = {
37
42
  script: 'skills/install.mjs',
38
43
  summary: '把随包分发的三个 AI 技能落到本工程(--also-claude / --target <dir> / --dry-run)',
39
44
  },
45
+ lint: {
46
+ script: 'skills/lint.mjs',
47
+ summary: '契约机械护栏:红线条 / 外观来源 / 属性闭集 / 类名前缀(--root / --namespace / --group / --json)',
48
+ },
40
49
  }
41
50
 
42
51
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manohub/kit",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "子应用入口编排层:createSubApp(作用域容器与宿主锚点、pinia/路由/vue-query 装配、宿主挂载协议)、i18n 单实例与语言探测,外加随包分发的接入契约(CONTRACT.md,五层闭集条款 + 自检清单)与三个 AI 技能包。本包**零样式产物**:设计令牌(值)在 @manohub/theme,组件(类与行为)在 @manohub/ui,两者由消费方直接引入。",