Merge remote-tracking branch 'origin/master' into feat/plugin-owned-settings-surface

# Conflicts:
#	packages/client/ui-plugin-config/README.i18n.yaml
#	packages/client/ui-plugin-config/README.md
#	packages/client/ui-plugin-config/README.zh.md
#	packages/client/ui-plugin-config/src/client/PluginConfigSection.tsx
#	packages/client/ui-plugin-config/src/client/index.ts
#	packages/client/ui-plugin-config/tests/apply.client.spec.ts
#	packages/client/ui-plugin-config/tests/section.client.spec.tsx
This commit is contained in:
Yichen Jiang
2026-08-12 22:50:49 +08:00
124 changed files with 2593 additions and 424 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/cookbook/adding-a-settings-card.md
adding-a-settings-card.md: fa5524412e885677d6534702b16787abc135b30d
adding-a-settings-card.zh.md: 9670f815dd23e7f48e12902ca93fd436114431f0
adding-a-settings-card.md: 8b0062286c8265e167c0ed75248d945d955864a6
adding-a-settings-card.zh.md: 6c8b6c45903aa10d66ac630dad202b035da8726f

View File

@@ -69,9 +69,9 @@ export function apply(ctx: ClientContext): void {
The scope snapshot carries what a form needs: the resolved `value`, the composition `base`, and the raw `user` layer, whose key **presence** — not its value — is what marks a field overridden. `scope.set(field, value)` stores one field and `scope.unset(field)` clears it back to the composition layer.
## 3. What the section does with it
## 3. What the tab does with it
The section reads which namespaces the Host serves and dispatches one slot key per namespace. A card is rendered when the Host serves its key and skipped when it does not, so a deployment that never composed the Host half shows no trace of the card. A served namespace no card claims renders nothing — that is how the namespaces owned by other pages (`ui-theme`, `permission`, `llm-*`) stay off this page.
The **Plugin configuration** tab reads which namespaces the Host serves and dispatches one slot key per namespace. A card is rendered when the Host serves its key and skipped when it does not, so a deployment that never composed the Host half shows no trace of the card. A served namespace no card claims renders nothing — that is how the namespaces owned by other pages (`ui-theme`, `permission`, `llm-*`) stay off this tab.
Cards appear in the order they registered into the slot; a keyed entry declares no `order` of its own.

View File

@@ -69,9 +69,9 @@ export function apply(ctx: ClientContext): void {
scope 快照携带表单所需的一切:解析后的 `value`、组装层 `base`,以及原始的 `user` 层——字段是否被覆盖,取决于它在 `user` 层中是否**出现**,而非它的值。`scope.set(field, value)` 存一个字段,`scope.unset(field)` 把它清回组装层。
## 3. 分区拿它做什么
## 3. 标签页拿它做什么
分区读取 Host 服务了哪些命名空间,并为每个命名空间派发一个 slot 键。当 Host 服务了某卡片的键时它被渲染,否则被跳过,因此从未组装过 Host 半侧的部署不会留下这张卡片的任何痕迹。被服务却无人认领的命名空间什么都不渲染——归其他页面所有的那些命名空间(`ui-theme`、`permission`、`llm-*`)正是这样留在本页之外的。
**插件配置**标签页读取 Host 服务了哪些命名空间,并为每个命名空间派发一个 slot 键。当 Host 服务了某卡片的键时它被渲染,否则被跳过,因此从未组装过 Host 半侧的部署不会留下这张卡片的任何痕迹。被服务却无人认领的命名空间什么都不渲染——归其他页面所有的那些命名空间(`ui-theme`、`permission`、`llm-*`)正是这样留在本标签页之外的。
卡片按其注册进该 slot 的顺序出现keyed entry 不声明自己的 `order`。