@qilin-agent/client-locale 0.0.0-stage → 3.1.4
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/LICENSE +21 -0
- package/README.i18n.yaml +61 -0
- package/README.md +139 -2
- package/README.zh.md +140 -0
- package/lib/client.js +1390 -0
- package/lib/index.js +27 -0
- package/lib/types/client/index.d.ts +238 -0
- package/lib/types/index.d.ts +9 -0
- package/lib/types/locale-settings.d.ts +22 -0
- package/lib/types/locales/en.d.ts +43 -0
- package/lib/types/locales/index.d.ts +9 -0
- package/lib/types/locales/zh.d.ts +45 -0
- package/package.json +71 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kkutysllb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/client/locale/README.md
|
|
5
|
+
/:
|
|
6
|
+
en: d2aaa955e01c2679
|
|
7
|
+
zh: a931126ab9ab926b
|
|
8
|
+
/qilin-agent-client-locale:
|
|
9
|
+
en: d02cd6b9890e9c58
|
|
10
|
+
zh: b11d4fe387081a59
|
|
11
|
+
/qilin-agent-client-locale/summary:
|
|
12
|
+
en: 1c05578df3329b4f
|
|
13
|
+
zh: 623a745a5c8c67ba
|
|
14
|
+
/qilin-agent-client-locale/table-of-contents:
|
|
15
|
+
en: d152484eb41ac6b4
|
|
16
|
+
zh: 09388d293f9be9cb
|
|
17
|
+
/qilin-agent-client-locale/use-this-package:
|
|
18
|
+
en: 7fedfbcbc3ad8cea
|
|
19
|
+
zh: 210d6b20de8ed41e
|
|
20
|
+
/qilin-agent-client-locale/use-this-package/choosing-a-language:
|
|
21
|
+
en: 72b9fd7f3a7e728d
|
|
22
|
+
zh: d2e38e1c85c76556
|
|
23
|
+
/qilin-agent-client-locale/use-this-package/registering-a-dictionary:
|
|
24
|
+
en: 9b2fcfa8cae8dc4b
|
|
25
|
+
zh: 5926a024465347f5
|
|
26
|
+
/qilin-agent-client-locale/use-this-package/registering-a-language-pack:
|
|
27
|
+
en: aa4e9c70523339cc
|
|
28
|
+
zh: 3359eddc4e9ef15e
|
|
29
|
+
/qilin-agent-client-locale/use-this-package/what-the-host-half-does:
|
|
30
|
+
en: 8fa91333f7fc3387
|
|
31
|
+
zh: 789a9cbb3eace3b0
|
|
32
|
+
/qilin-agent-client-locale/understand-the-implementation:
|
|
33
|
+
en: 288d8db39f9acfc5
|
|
34
|
+
zh: d65cf2ffae8ad35c
|
|
35
|
+
/qilin-agent-client-locale/understand-the-implementation/design-concept:
|
|
36
|
+
en: 79dbe4d0f1477a53
|
|
37
|
+
zh: d3bf1ebae92ed381
|
|
38
|
+
/qilin-agent-client-locale/understand-the-implementation/preference-resolution:
|
|
39
|
+
en: 4bc9dffa4629f537
|
|
40
|
+
zh: 0b5049f08416b55c
|
|
41
|
+
/qilin-agent-client-locale/understand-the-implementation/dictionary-lookup:
|
|
42
|
+
en: e84e0b8712988d24
|
|
43
|
+
zh: 0adf3e8777a3efa8
|
|
44
|
+
/qilin-agent-client-locale/understand-the-implementation/source-map:
|
|
45
|
+
en: ceec358b08427206
|
|
46
|
+
zh: 7fb2acb0de9fb1d1
|
|
47
|
+
/qilin-agent-client-locale/further-exploration:
|
|
48
|
+
en: 9774cddcd866f390
|
|
49
|
+
zh: 009b7737a580b20a
|
|
50
|
+
/qilin-agent-client-locale/model-experience:
|
|
51
|
+
en: 209321ba2d2e6710
|
|
52
|
+
zh: 21deb6c973f69b66
|
|
53
|
+
/qilin-agent-client-locale/model-experience/kv-cache-effect:
|
|
54
|
+
en: ca75c51c89c2c9b0
|
|
55
|
+
zh: de54f3467ef3b9be
|
|
56
|
+
/qilin-agent-client-locale/known-limitations-and-deferred-work:
|
|
57
|
+
en: 500ede048ef44c6a
|
|
58
|
+
zh: b134cb622f75b077
|
|
59
|
+
/qilin-agent-client-locale/known-limitations-and-deferred-work/dev-note:
|
|
60
|
+
en: e67f633dc6fe7773
|
|
61
|
+
zh: 3bb0c20c93f16f98
|
package/README.md
CHANGED
|
@@ -1,3 +1,140 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "Localization for the web GUI: the zh/en preference, browser-derived fallback, typed namespace dictionaries, and the framework translation seat, for users and plugin authors."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# @qilin-agent/client-locale
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
Use `qilin-client-locale` to switch the web GUI between the shipped English and Chinese locales or languages added by client plugins. User selections take effect immediately; loopback pages persist them in `$QILIN_HOME/settings.yaml`, while non-loopback pages keep them only for the current process. New browsers use the first supported language requested by the browser until an allowed stored preference arrives. Plugin authors add typed namespace dictionaries and translate through the public locale API; slot-rendered copy updates without a reload.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
Use it wherever the web GUI needs a language switch or translated copy: the shipped settings row covers users, and plugin authors register their own dictionaries. Nothing needs configuration to mount — the package activates with the client tree.
|
|
29
|
+
|
|
30
|
+
### Choosing a language
|
|
31
|
+
|
|
32
|
+
Open Settings → General and select a registered language. The active locale is applied immediately: the UI copy switches, `<html lang>` points at the external id or built-in document tag, and the choice is written to the durable settings section. A browser without an explicit Host preference selects the first registered language that matches `navigator` by full tag and then primary subtag, falling back to English. A stored external locale waits for its definition to register instead of becoming active while unavailable.
|
|
33
|
+
|
|
34
|
+
### Registering a dictionary
|
|
35
|
+
|
|
36
|
+
Call `ctx.locale.register(ns, { zh, en })` with a namespace merged into `LocaleNamespaceMap`; the compiler checks every key against the namespace's typed key union and requires both shipped locales. Consumers translate through `ctx.locale.bind(ns)` or the framework-injected `t` seat. A dictionary registered after the UI is already mounted is picked up without a remount.
|
|
37
|
+
|
|
38
|
+
### Registering a language pack
|
|
39
|
+
|
|
40
|
+
An external client plugin registers the language definition and each translated namespace as owned effects; definitions and dictionaries may register in either order:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
export const inject = ['locale']
|
|
44
|
+
|
|
45
|
+
export function apply(ctx) {
|
|
46
|
+
ctx.effect(
|
|
47
|
+
() => ctx.locale.addLanguage({ id: 'ja', label: '日本語', fallback: 'en' }),
|
|
48
|
+
'my-locale: language',
|
|
49
|
+
)
|
|
50
|
+
ctx.effect(
|
|
51
|
+
() => ctx.locale.register('common', 'ja', {
|
|
52
|
+
cancel: 'キャンセル',
|
|
53
|
+
close: '閉じる',
|
|
54
|
+
}),
|
|
55
|
+
'my-locale: common dictionary',
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
An external id is a non-empty ASCII BCP 47-style tag. Its fallback must already be registered, and the chain must terminate at `en`; unknown targets, duplicate ids, and cycles fail at registration. Lookup walks the fallback chain in the requested namespace, repeats it in `common`, then displays the key. Unloading a definition removes it from the selector and returns an active selection to the available browser/default locale.
|
|
61
|
+
|
|
62
|
+
### What the Host half does
|
|
63
|
+
|
|
64
|
+
The Host persists the preference through the settings service on loopback pages. The Client deliberately withholds that settings scope on non-loopback pages, so their locale selection remains process-local even though Connection authenticates every API method.
|
|
65
|
+
|
|
66
|
+
-----
|
|
67
|
+
|
|
68
|
+
<a id="understand-the-implementation"></a>
|
|
69
|
+
## Understand the implementation
|
|
70
|
+
|
|
71
|
+
<details>
|
|
72
|
+
<summary>Implementation internals — click to expand</summary>
|
|
73
|
+
|
|
74
|
+
This section explains how the locale service is built; observable behavior is covered in [Use this package](#use-this-package).
|
|
75
|
+
|
|
76
|
+
### Design concept
|
|
77
|
+
|
|
78
|
+
One `LocaleRuntime` owns the preference and the dictionary registry, and is itself the slot system's `LocaleFace`: `getSnapshot`/`subscribe` back the framework-injected `t` seat through `ctx.slots.installLocale`. The immutable snapshot carries the active locale, the selectable locales, and a monotonic revision; dictionary registration and locale switches both advance the revision, but only a switch emits the `locale/change` event. Product-authored Client UI text must enter through these typed dictionaries or an already-localized primitive prop; `verify-client-ui-i18n` enforces that source ownership ([decision](../../../.agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.md)).
|
|
79
|
+
|
|
80
|
+
### Preference resolution
|
|
81
|
+
|
|
82
|
+
The provisional locale comes from the browser (`navigator.languages` matched by full tag and then primary subtag, English as the fallback), standing in until the allowed Host-backed settings scope delivers its stored preference. The Host read runs after plugin activation so an unavailable or withheld settings scope cannot block the page, and the result replaces the provisional value live. A stored external locale waits for its definition to register. `setLocale` is the only write entry; it persists even when the id already matches the active locale, because the active value may be provisional and must survive a different browser sharing the same home.
|
|
83
|
+
|
|
84
|
+
### Dictionary lookup
|
|
85
|
+
|
|
86
|
+
The typed object form requires complete dictionaries for both built-in locales. The per-locale form lets language packs register each namespace independently. For each key, lookup walks the active language's declared fallback chain in the requested namespace, repeats that chain in `common`, then displays the key itself. Bound translate functions retain stable identity per namespace so they can ride inject surfaces without breaking memoization.
|
|
87
|
+
|
|
88
|
+
### Source map
|
|
89
|
+
|
|
90
|
+
| File | Role |
|
|
91
|
+
|---|---|
|
|
92
|
+
| [`src/client/index.ts`](src/client/index.ts) | `LocaleRuntime`, dictionary registry, document language synchronization, `locale/change` event |
|
|
93
|
+
| [`src/index.ts`](src/index.ts) | Node half: registers the `locale` settings namespace |
|
|
94
|
+
| [`src/locale-settings.ts`](src/locale-settings.ts) | The durable schema for `locale.preference` |
|
|
95
|
+
| [`src/locales/`](src/locales/) | The shipped `zh`/`en` dictionaries |
|
|
96
|
+
|
|
97
|
+
</details>
|
|
98
|
+
|
|
99
|
+
-----
|
|
100
|
+
|
|
101
|
+
<a id="further-exploration"></a>
|
|
102
|
+
## Further Exploration
|
|
103
|
+
|
|
104
|
+
Read these when the locale contract is not enough: the slot face it implements, the settings surface it rides, and the persistence decision behind the preference.
|
|
105
|
+
|
|
106
|
+
- [Client slot system](../ui-slots/README.md) — the slot model and the `LocaleFace` seat this package implements.
|
|
107
|
+
- [Host-backed preferences decision](../../../.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.md) — why the preference persists in Host settings instead of the browser.
|
|
108
|
+
- [Settings group map](../../settings/README.md) — the settings service that stores the preference.
|
|
109
|
+
- [Client group map](../README.md) — the browser half this package belongs to.
|
|
110
|
+
|
|
111
|
+
-----
|
|
112
|
+
|
|
113
|
+
<a id="model-experience"></a>
|
|
114
|
+
## Model Experience
|
|
115
|
+
|
|
116
|
+
None, as the locale service is a browser-side UI plugin layer that registers nothing model-facing.
|
|
117
|
+
|
|
118
|
+
#### KV Cache effect
|
|
119
|
+
|
|
120
|
+
None; this package neither assembles nor sends a provider request.
|
|
121
|
+
|
|
122
|
+
## Known Limitations and Deferred Work
|
|
123
|
+
|
|
124
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
These limits define where localization is incomplete or frozen at registration time. They are current package constraints, not a task backlog.
|
|
128
|
+
|
|
129
|
+
- **Registry-held text reads its translation once** — copy captured at registration time outside the slot render path (e.g. the `/model` command description in the command registry) keeps the language it was registered under until re-registration; slot-rendered copy follows switches live.
|
|
130
|
+
- **Language packs own language-specific behavior** — the registry supplies selection, persistence, browser matching, key fallback, and `<html lang>`; it does not add plural rules or bidirectional layout.
|
|
131
|
+
|
|
132
|
+
<a id="dev-note"></a>
|
|
133
|
+
### Dev Note
|
|
134
|
+
|
|
135
|
+
<details>
|
|
136
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
137
|
+
|
|
138
|
+
None.
|
|
139
|
+
|
|
140
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向用户与插件作者的 web GUI 本地化说明:zh/en 偏好、浏览器派生回退、类型化命名空间词典与框架翻译席位。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @qilin-agent/client-locale
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
使用 `qilin-client-locale` 可在 web GUI 中切换内置的 English、中文 locale,或 client 插件添加的语言。用户选择会立即生效;loopback 页面把选择持久化到 `$QILIN_HOME/settings.yaml`,非 loopback 页面则只为当前进程保留选择。全新浏览器会使用浏览器请求的第一个受支持语言,直到允许读取的已存储偏好到达。插件作者可添加类型化命名空间字典,并通过公开 locale API 翻译;经 slot 渲染的文案无需重新加载即可随语言切换更新。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
只要 web GUI 需要语言切换或翻译文案就使用它:已发布的设置行覆盖用户侧,插件作者则注册自己的词典。挂载无需任何配置——本包随客户端树一起激活。
|
|
29
|
+
|
|
30
|
+
### 选择语言
|
|
31
|
+
|
|
32
|
+
打开“设置 → 常规”并选择一种已注册语言。生效中的 locale 会立即应用:UI 文案切换、`<html lang>` 指向外部 id 或内置语言的文档标签,选择写入持久设置分区。没有显式 Host 偏好的浏览器会按完整标签、再按主子标签选择 `navigator` 请求的第一个已注册语言,无法匹配时回退到 English。已存储的外部 locale 会等待其定义注册,不会在不可用时生效。
|
|
33
|
+
|
|
34
|
+
### 注册词典
|
|
35
|
+
|
|
36
|
+
用已合并进 `LocaleNamespaceMap` 的命名空间调用 `ctx.locale.register(ns, { zh, en })`;编译器会对照该命名空间的类型化键并集检查每个键,并要求两个内置 locale 齐全。消费方通过 `ctx.locale.bind(ns)` 或框架注入的 `t` 席位翻译。UI 已挂载后再注册的词典无需重新挂载即可生效。
|
|
37
|
+
|
|
38
|
+
### 注册语言包
|
|
39
|
+
|
|
40
|
+
外部 client 插件把语言定义和每个已翻译命名空间注册为自身拥有的 effect;定义与字典可以按任意顺序注册:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
export const inject = ['locale']
|
|
44
|
+
|
|
45
|
+
export function apply(ctx) {
|
|
46
|
+
ctx.effect(
|
|
47
|
+
() => ctx.locale.addLanguage({ id: 'ja', label: '日本語', fallback: 'en' }),
|
|
48
|
+
'my-locale: language',
|
|
49
|
+
)
|
|
50
|
+
ctx.effect(
|
|
51
|
+
() => ctx.locale.register('common', 'ja', {
|
|
52
|
+
cancel: 'キャンセル',
|
|
53
|
+
close: '閉じる',
|
|
54
|
+
}),
|
|
55
|
+
'my-locale: common dictionary',
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
外部 id 必须是非空的 ASCII BCP 47 风格标签。它的 fallback 必须已经注册,且整条链必须终止于 `en`;未知目标、重复 id 与循环会在注册时失败。查找时先在请求命名空间内遍历生效语言的 fallback 链,再在 `common` 中遍历该链,最后显示键本身。卸载语言定义会将其从选择器移除,并让生效中的选择回落到可用的浏览器语言或默认语言。
|
|
61
|
+
|
|
62
|
+
### Host 半侧做什么
|
|
63
|
+
|
|
64
|
+
Host 通过 settings 服务为 loopback 页面持久化偏好。Client 会刻意拒绝非 loopback 页面使用该 settings scope,因此即使 Connection 认证所有 API 方法,它们的 locale 选择仍只存在于进程内。
|
|
65
|
+
|
|
66
|
+
-----
|
|
67
|
+
|
|
68
|
+
<a id="understand-the-implementation"></a>
|
|
69
|
+
## 理解实现
|
|
70
|
+
|
|
71
|
+
<details>
|
|
72
|
+
<summary>实现细节——点击展开</summary>
|
|
73
|
+
|
|
74
|
+
本节解释 locale 服务的构建方式;可观察行为已在[使用本包](#use-this-package)中说明。
|
|
75
|
+
|
|
76
|
+
### 设计理念
|
|
77
|
+
|
|
78
|
+
一个 `LocaleRuntime` 同时拥有偏好与词典注册表,并且自身就是 slot 系统的 `LocaleFace`:`getSnapshot`/`subscribe` 通过 `ctx.slots.installLocale` 支撑框架注入的 `t` 席位。不可变快照携带生效中的 locale、可选择的 locale 列表与单调 revision;词典注册与 locale 切换都会推进 revision,但只有切换会发出 `locale/change` 事件。产品编写的 Client UI 文本必须来自这些带类型的字典,或来自已经本地化的 primitive prop;`verify-client-ui-i18n` 强制执行该源码归属(见[决策](../../../.agents/notes/implemented/architecture/2026-08-23-locale-owned-client-ui-copy.zh.md))。
|
|
79
|
+
|
|
80
|
+
### 偏好解析
|
|
81
|
+
|
|
82
|
+
临时 locale 来自浏览器(`navigator.languages` 先按完整标签、再按主子标签匹配,以 English 作为回退),在允许使用的 Host-backed settings scope 送达其存储偏好之前生效。Host 读取在插件激活后运行,因此 settings scope 不可用或被拒绝都不会阻塞页面,结果会实时替换临时值。已存储的外部 locale 会等待其定义注册。`setLocale` 是唯一写入入口;即使 id 已与生效中的 locale 匹配也会持久化,因为生效中的值可能是临时的,必须能在共享同一 home 的其他浏览器上存活。
|
|
83
|
+
|
|
84
|
+
### 词典查找
|
|
85
|
+
|
|
86
|
+
带类型的对象形式要求两个内置 locale 都有完整字典;逐 locale 形式允许语言包独立注册每个命名空间。逐键查找会先在请求命名空间中沿生效语言声明的 fallback 链查找,再在 `common` 中重复该链,最后显示键本身。绑定的翻译函数按命名空间保持稳定身份,因此可以挂在 inject 表面上而不破坏 memoization。
|
|
87
|
+
|
|
88
|
+
### 源码地图
|
|
89
|
+
|
|
90
|
+
| 文件 | 职责 |
|
|
91
|
+
|---|---|
|
|
92
|
+
| [`src/client/index.ts`](src/client/index.ts) | `LocaleRuntime`、词典注册表、文档语言同步、`locale/change` 事件 |
|
|
93
|
+
| [`src/index.ts`](src/index.ts) | node 半侧:注册 `locale` 设置命名空间 |
|
|
94
|
+
| [`src/locale-settings.ts`](src/locale-settings.ts) | `locale.preference` 的持久 schema |
|
|
95
|
+
| [`src/locales/`](src/locales/) | 已发布的 `zh`/`en` 词典 |
|
|
96
|
+
|
|
97
|
+
</details>
|
|
98
|
+
|
|
99
|
+
-----
|
|
100
|
+
|
|
101
|
+
<a id="further-exploration"></a>
|
|
102
|
+
## 进一步探索
|
|
103
|
+
|
|
104
|
+
当 locale 约定不够用时阅读以下页面:它所实现的 slot 面孔、它所依托的设置界面,以及偏好背后的持久化决策。
|
|
105
|
+
|
|
106
|
+
- [客户端 slot 系统](../ui-slots/README.zh.md)——本包实现的 slot 模型与 `LocaleFace` 席位。
|
|
107
|
+
- [Host 支撑偏好决策](../../../.agents/notes/implemented/bug-fix/2026-08-06-host-backed-web-preferences.zh.md)——偏好为何持久化在 Host 设置中而非浏览器里。
|
|
108
|
+
- [设置组地图](../../settings/README.zh.md)——存储该偏好的设置服务。
|
|
109
|
+
- [客户端组地图](../README.zh.md)——本包所属的浏览器半侧。
|
|
110
|
+
|
|
111
|
+
-----
|
|
112
|
+
|
|
113
|
+
<a id="model-experience"></a>
|
|
114
|
+
## 模型体验
|
|
115
|
+
|
|
116
|
+
无。locale 服务属于浏览器侧 UI 插件层,不注册任何面向模型的内容。
|
|
117
|
+
|
|
118
|
+
#### KV Cache 影响
|
|
119
|
+
|
|
120
|
+
无;该包既不组装也不发送提供方请求。
|
|
121
|
+
|
|
122
|
+
## 已知限制与延期工作
|
|
123
|
+
|
|
124
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
这些限制说明本地化在哪些地方不完整,或在注册时被冻结。它们是当前包约束,不是任务积压。
|
|
128
|
+
|
|
129
|
+
- **注册表持有的文本只读取一次翻译**——在 slot 渲染路径之外于注册时捕获的文案(例如 command 注册表中的 `/model` 命令描述)在重新注册前保持注册时的语言;slot 渲染的文案随切换实时更新。
|
|
130
|
+
- **语言包负责语言特有行为**——注册表提供选择、持久化、浏览器匹配、逐 key 回退和 `<html lang>`;它不增加复数规则或双向布局。
|
|
131
|
+
|
|
132
|
+
<a id="dev-note"></a>
|
|
133
|
+
### 开发备注
|
|
134
|
+
|
|
135
|
+
<details>
|
|
136
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
137
|
+
|
|
138
|
+
无。
|
|
139
|
+
|
|
140
|
+
</details>
|