# 扩展：配置、贡献与能力合同

从 Node/Mark 与命令到 profile、布局和结构选区的实际职责。

## 配置与组合

| 入口/钩子 | 返回或职责 | 约束 |
| --- | --- | --- |
| `Extension.create(config)` | 行为扩展定义 | 不新增 Schema 节点 |
| `Node.create(config)` / `Mark.create(config)` | 节点/标记定义 | Node 的 group/content、Mark 的约束进入同一个 Schema |
| `.configure(options)` | 配置后的扩展 | 为每个产品实例独立装配，不能修改共享全局 options |
| `.extend(config)` | 在原定义上扩展 | 有意替换同名能力，检查调用原 hook 的方式和顺序 |
| `addOptions()` | 默认配置 | 配置不是持久正文 |
| `addStorage()` | 实例状态 | 不把应持久化的业务属性藏进 storage |
| `addExtensions()` | 子扩展数组 | 预设或聚合包的组合点，避免重复 Schema 所有者 |
| `addAttributes()` / `addGlobalAttributes()` | 属性定义 | 明确默认值、解析、序列化和迁移 |
| `addCommands()` | raw command factories | 增强 `Commands<ReturnType>`，commands/chain/can 使用同一类型 |
| `addKeyboardShortcuts()` | 按键映射 | 调同一命令，返回是否处理 |
| `addInputRules()` / `addPasteRules()` | 输入/粘贴规则 | 与现有历史和 Schema 一起验证 |
| `addProseMirrorPlugins()` | PM plugins | 沿用当前 `@quirekit/pm` 身份，不混装另一份上游内核 |

最小行为例程见[自定义插件](/plugins/custom)；包含规范内容与 retained View 的完整例程见[内容扩展](/build/extension)。

## 能力贡献的所有者

| 钩子 | 下游消费方 | 不是自动获得的能力 |
| --- | --- | --- |
| `addViewAdapters()` | Core 挂载生命周期 | Schema 本身不提供输入与绘制 |
| `addDocumentProfiles()` | 排版引擎的 facet 解析 | Core 不解释 Word 属性或单位 |
| `addLayoutProviders()` | View/Engine | HTML CSS 不自动变成 Canvas 布局 |
| `addSelectionAdapters()` | 结构选择编译与命令目标 | 可绘制不代表可正确跨组选择 |
| `addDocx()` | 实例 `editor.docx` | 序列化为 JSON 不代表 DOCX 往返成立 |
| `addAccessibility()` | 无障碍语义 owner | 只画文字不等于语义可达 |
| `addAiCapabilities()` | AI 核心 | feature 声明事实和 described command，不自建模型工具或提示词 |

产品 UI 的 `addRibbonItems` 等贡献需要相应产品注册表消费；纯 Core 实例不会凭这些声明生成界面。参见[产品插件](/build/product-plugin)。

## 文档 profile 与布局 provider

profile 提供模型级语义，如页面、段落、表格和绘图。一个 facet 只能有一个所有者；缺失项走中立默认。它与单个 custom Node 的布局 provider 不是同一抽象。

### QuireDocumentProfileRegistration

`@quirekit/core/document-profile` · MIT

扩展贡献的文档语义 profile。Core 将载荷视为不透明对象，排版引擎验证并消费所声明的 facet；每项 facet 只能有一个所有者。

```ts
export interface QuireDocumentProfileRegistration<Profile = unknown> {
    readonly id: string;
    readonly facets: readonly string[];
    readonly profile: Profile;
}
```

**id** — 用于诊断和查找的稳定 profile 身份。

**facets** — 该 profile 提供的 facet 名称，每项仅有一个所有者。

**profile** — 由排版引擎验证并消费的不透明载荷。

provider 声明 nodeTypes 和 capability，并返回带源范围/快照版本的布局产品。注册通过公开子入口；不要把内部类型名误当成根入口 export。

### QuireLayoutProviderRegistration

`@quirekit/core/layout-provider` · MIT

扩展贡献的渲染后端中立布局注册，声明 provider 身份、节点类型、能力与依赖。

```ts
export interface QuireLayoutProviderRegistration<Provider = unknown> {
    readonly id: string;
    readonly nodeTypes: readonly string[];
    readonly capabilities: readonly QuireLayoutProviderCapabilityKind[];
    readonly provider: Provider;
    readonly layoutDependency?: QuireLayoutDependency | undefined;
}
```

**id** — 稳定 provider 身份。

**nodeTypes** — 由该 provider 处理的 PM 节点类型。

**capabilities** — 该 provider 实现的能力类别。

**provider** — 由能力所有者消费的不透明 provider 载荷。

**layoutDependency** — 覆盖该具体 provider 及其全部可变依赖的可选证明。

### createQuireLayoutProviderRegistration

`@quirekit/view-engine/layout-provider` · AGPL-3.0-only

将强类型布局 provider 包装为 Core 注册元数据。Core 检查身份与节点归属，View 在执行前验证元数据与载荷一致。
@param provider - 布局算法及其能力声明。
@returns 保留该 provider 载荷的 Core 注册。

```ts
function createQuireLayoutProviderRegistration(provider: QuireLayoutProvider): QuireViewLayoutProviderRegistration
```

具体的测量 → child flow → retained region 和 structured selection 见[完整源码](/build/extension)。`layoutDependency: { kind: 'document' }` 只有在 provider 不读取未声明的外部可变状态时才成立，不能作为通用性能开关。
