dsh-tui-theme 0.7.1 → 0.7.2
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/README.md +6 -0
- package/docs/decisions/2026-09-26-settings-generation-adaptation.md +61 -0
- package/lib/types/index.d.ts +3 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +67 -39
- package/lib/types/liveConfig.d.ts +88 -0
- package/lib/types/liveConfig.d.ts.map +1 -0
- package/lib/types/liveConfig.js +151 -0
- package/lib/types/settingsSection.d.ts +73 -15
- package/lib/types/settingsSection.d.ts.map +1 -1
- package/lib/types/settingsSection.js +214 -52
- package/package.json +3 -2
- package/scripts/verify-package.mjs +3 -0
- package/scripts/verify-settings-generation.mjs +306 -0
- package/scripts/verify.mjs +1573 -1289
package/README.md
CHANGED
|
@@ -117,6 +117,8 @@ dsh plugin --profile dsh-tui add -w dsh-tui-theme@latest
|
|
|
117
117
|
|
|
118
118
|
三项装饰全关时状态行整体消失。另有仅 profile 层的开关(`cordis.patch.yml`,不出现在 /settings):`autoInstallThemes`、`statusEnabled`。
|
|
119
119
|
|
|
120
|
+
上表就是本插件的**可编辑面**:卡片字段与 `src/liveConfig.ts` 的 `LIVE_CONFIG_KEYS` 必须逐键相等(`npm run verify` 双向断言),因为 dsh-TUI ≥ 0.11(`dsh-settings` ≥ 0.1.7)的设置服务不再接受插件注册命名空间,而是把**本插件 Config 里标了 volatile 的字段**投影成表单、以 **Loader 条目 id**(默认 `dsh-tui-theme`)作命名空间;保存直接写进 profile 补丁并即时生效。老宿主(≤ 0.10.x,`dsh-settings` ≤ 0.1.6)仍走插件自己注册命名空间的旧路径,行为不变。两条路径共用同一串命名空间,因此给插件行改过 id 的用户在新宿主上会以新 id 存取设置(旧代下改动 id 也会跟着走)。
|
|
121
|
+
|
|
120
122
|
## 受宿主限制、目前无法定制的部分
|
|
121
123
|
|
|
122
124
|
以下元素的颜色/形态由 dsh-TUI 宿主**硬编码**,不读取任何主题键,主题 JSON 与插件接缝都覆盖不到(dsh-TUI 0.9.3 实测):
|
|
@@ -154,6 +156,9 @@ npm install --include=dev # 见下方安装前提,本仓不提交 lockfile
|
|
|
154
156
|
npm run build
|
|
155
157
|
npm run verify
|
|
156
158
|
npm run verify:package
|
|
159
|
+
# 代际门禁:本仓 devDependency 的 dsh-settings 是旧代,脚本会明确跳过并以 0 退出;
|
|
160
|
+
# 要真正验证 ≥0.1.7 的 Config 投影,把 DSH_SETTINGS_DIR 指到真机那份安装
|
|
161
|
+
DSH_SETTINGS_DIR="$HOME/.dsh/profiles/node_modules/@deepseek-ai/dsh-settings" npm run verify:settings
|
|
157
162
|
DSH_TUI_ADAPTER_DIR=/path/to/dsh-TUI/lib/types/dsh-adapter \
|
|
158
163
|
DSH_TUI_SOURCE_ROOT=/path/to/dsh-TUI-source \
|
|
159
164
|
npm run verify:host
|
|
@@ -171,4 +176,5 @@ npm run verify:host
|
|
|
171
176
|
## 兼容性
|
|
172
177
|
|
|
173
178
|
- **dsh-TUI 版本下限:0.8.8**(状态行与设置面板;0.9.3 实测)。0.10.0 及更新版本使用运行时主题注册;0.10.1 起状态行经富状态视图按主题配色(更旧宿主自动回退无色标量行);更旧的宿主缺 `dsh-tui-extensions` 扩展面时,插件自动降级为“仅安装三套主题”,不报错。
|
|
179
|
+
- **设置服务两代都支持**:`dsh-settings` ≤ 0.1.6(dsh-TUI 0.9.x/0.10.x)走插件注册命名空间 + `scope.watch`;≥ 0.1.7(dsh-TUI 0.11+,`/settings` 曾显示「命名空间未注册」)走 Config volatile 字段投影 + `loader/volatile-update` 重读。判定按能力探测,不解析版本号;两条路径的失败都会写日志而不是静默。适配依据见 `docs/decisions/2026-09-26-settings-generation-adaptation.md`。
|
|
174
180
|
- Node `^22.19 || >=24`,纯 ESM,MIT。
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# 决策:dsh-settings 两代适配 —— Config volatile 投影 + 命名空间跟随 Loader 条目 id
|
|
2
|
+
|
|
3
|
+
- 日期:2026-09-26
|
|
4
|
+
- 状态:已采纳
|
|
5
|
+
- 来源:迁移清单(dsh-tui-find 仓的 `docs/decisions/2026-09-24-settings-generation-adaptation.md`,本决策是它在本仓的落地记录);代码审查条目 T1–T3(工作区 `REVIEW.md`)
|
|
6
|
+
|
|
7
|
+
## 背景
|
|
8
|
+
|
|
9
|
+
**现象**:dsh-TUI 升到 0.11.0(`@deepseek-ai/dsh-settings@0.1.7-rc.1`、schemastery 3.18.4)后,`/settings` 里 **dsh-tui-theme 卡片右侧打上 `命名空间未注册` 徽标**,七个字段全部不可编辑。原实现(v0.7.1)在 `ctx.inject(['settings'])` 里调 `settings.register(PLUGIN_ID, schema)`:新代服务**没有** `register`,调用抛 `TypeError` 被 `catch {}` 静默吞掉 → 命名空间从未存在 → 徽标(`lib/types/settingsSection.js`)。
|
|
10
|
+
|
|
11
|
+
**根因**:`dsh-settings` 0.1.7 换代。旧代 `SettingsProvider` 由插件用 `register(ns, schema)` 自注册命名空间;新代 `SettingsForms` 改为:
|
|
12
|
+
|
|
13
|
+
- 命名空间 = **profile 条目 id**(本插件默认即 `dsh-tui-theme`,`cordis.patch.yml` 钉死);
|
|
14
|
+
- 表单 schema = 插件 **Cordis `Config`** 里标了 volatile 的字段(`volatileForm(schema)`,投影侧只读 `meta.volatile` 这份普通数据);
|
|
15
|
+
- `describe()` 只列 `volatileForm(Config)` 非空的条目;
|
|
16
|
+
- 写入经 `configEditor` 落进当前 profile 的补丁,loader 就地把 volatile 引用改值并以 `entry.fiber.ctx.emit(self, 'loader/volatile-update', paths)` 广播(`Context.filter` 只投给该条目自己的 fiber);
|
|
17
|
+
- 自带卡片的插件用 `configure({ auto: false }, ctx.fiber)` 关掉自动生成页,`configure` 对同一 fiber 二次调用会 throw。
|
|
18
|
+
|
|
19
|
+
另有两条硬约束:`.volatile()` 直到 **schemastery 3.18.3** 才有(本仓基线 3.18.1/3.18.2 没有);volatile 字段在 `apply` 期是**引用不是值**(`Schema.resolve` 用 `createVolatile()` 包一层)。
|
|
20
|
+
|
|
21
|
+
## 决策(本仓落地)
|
|
22
|
+
|
|
23
|
+
1. **双路径按能力分支,永不解析版本号**:`typeof settings.register === 'function'` → 旧代(注册命名空间 + `scope.watch`);否则视为新代(`configure({ auto: false }, ctx.fiber)` + 读活配置 + 订阅 `loader/volatile-update`);两者皆无则 `info` 说明卡片本会话不可用。
|
|
24
|
+
2. **可编辑集合只有一个事实来源**:`src/liveConfig.ts` 的 `LIVE_CONFIG_KEYS` 驱动 `Config` 的 volatile 标记(`src/index.ts` 的 `configFields` + `liveField`),卡片字段与它**双向对拍**(`npm run verify` 断言,`npm run verify:settings` 再对真宿主投影断言一次)。
|
|
25
|
+
3. **`liveField` 两级能力探测**:先 `.volatile()`(3.18.3+,走框架自带校验),没有就把 `meta.volatile` 直接写 true(照抄 dsh-TUI #990 给自家 Config 的修法);`meta` 被冻结时安静退化为不标记。
|
|
26
|
+
4. **命名空间取 Loader 条目 id**(`resolveSettingsNamespace`):新代 `describe()` 直接以 `entry.options.id` 当 ns 且不校验,而插件自有分区在 `tuiSettingsSections.register()` 里仍受 `^[a-z][a-z0-9_-]*$` 约束——entry id 合法时以它为准,否则回落 `PLUGIN_ID` 并 warn;两代共用同一串,卡片、旧代注册与宿主投影不可能互相错位。
|
|
27
|
+
5. **apply 期 config 一律先解包**:`readConfigValues` 逐键解引用,判定按 **cosmokit 的 Volatile 协议**(`Symbol.for('cosmokit.volatile.write') in value`),`{ get }` 单键形状只作兜底。`apply` 里构造 `cordis` 层与 `readLive()` 探针都走它,杜绝把 ref 当字符串/布尔用(形状判定在 ref 多带一个普通键时就静默失效)。
|
|
28
|
+
6. **失败不再静默**:旧代注册失败 warn(原为裸 `catch {}`,正是这次「无日志可查」的来源);新代下 entry id 不可用、或一个 live 字段都没有(`hasLiveConfigFields`)时各给一条可诊断的 warn;缺 `loader/volatile-update` 时 `info` 说明「改动下次加载才生效」。
|
|
29
|
+
7. **新增代际验证入口**:`npm run verify:settings`(`scripts/verify-settings-generation.mjs`)——对真实安装的 dsh-settings 判定世代;≥0.1.7 时用**真实的** `volatileForm`/`projectForm`/`isVolatilePath` 对构建产物 `lib/types/` 跑 20 条投影断言,旧代明确报告「无需验证」并以 0 退出(CI 安全,已挂进 CI verify 档与 `release:check`)。
|
|
30
|
+
8. **`settings.register` 必须按方法调用**(`settings.register?.(...)`,可选调用保留 receiver):真 provider 的 `register()` 读自身状态,摘成局部变量再调用会丢 `this` 抛错——这条由 `verify:host` 的真实 provider 相位咬出,已补进 `scripts/verify.mjs` 的假服务(`this === undefined` 即抛)作为回归。
|
|
31
|
+
|
|
32
|
+
## 本仓特有的取舍
|
|
33
|
+
|
|
34
|
+
- **可编辑面 = 7 键**:`followSystem` / `showGlyph` / `statusGlyph` / `showClock` / `showTurns` / `statusSeparator` / `statusScope`,与卡片字段逐一对应。`autoInstallThemes` / `statusEnabled` **有意不标 live**:它们是仅 profile 层的开关(README 已写明不出现在 /settings),标了反而会出现「可编辑但无 UI」的错位。
|
|
35
|
+
- 新代下 setter 的取值来自插件自己的行配置,因此首帧 `onDoc` 携带的是**全量已解析配置**(含 schema 默认值),与旧代「只有用户层」的形状不同;`index.ts` 的 `{ ...cordis, ...doc }` 合并对两者都成立,`followActive` 的基线语义不变。
|
|
36
|
+
- `configure` 的 owner 必须是 **Config 所属的插件 fiber**(`apply` 的 `ctx.fiber`),`loader/volatile-update` 也注册在插件自身 context 上(loader 只投给被更新条目的 fiber);两者都挂在 inject 子 ctx 的 effect 上做清理。
|
|
37
|
+
|
|
38
|
+
## 替代方案
|
|
39
|
+
|
|
40
|
+
- **抬高 peer 下限到 ≥0.1.7、只支持新代**:把 0.9.x/0.10.x 用户挡在门外,与既有双宿主兼容策略冲突——否决。
|
|
41
|
+
- **放弃卡片、让新代自动生成页面**(不调 `configure`):字段标签/分组/中英文案/hint 全丢,且与已注册的卡片重复——否决。
|
|
42
|
+
- **逐字段手写 `.volatile()`、不设 `LIVE_CONFIG_KEYS`**:卡片与 schema 的对应关系无人守,漂移即静默死卡——否决。
|
|
43
|
+
- **只探测 `.volatile()`、不做 meta 兜底**:3.18.1/3.18.2 上标记静默失效,整套设置页变死(#990 的病根)——否决。
|
|
44
|
+
- **按 #991 的方式在标记失败时启动即报错**:第三方插件会把 TUI 启动一起带走——改为 warn + 验证脚本兜底。
|
|
45
|
+
|
|
46
|
+
## 影响
|
|
47
|
+
|
|
48
|
+
- 收益:dsh-TUI 0.11/新代设置服务下卡片恢复可编辑、保存即生效;0.9.x/0.10.x 行为不变;三类静默失败(注册被吞、标记失效、命名空间错位)各自有 warn、脚本与测试兜底。
|
|
49
|
+
- 成本:新增 `src/liveConfig.ts`;`settingsSection.ts` 多一条世代分支;`verify.mjs` 多 3 个场景;多一个代际脚本随包分发。
|
|
50
|
+
- 风险:
|
|
51
|
+
- 宿主 `loader/volatile-update` 语义再变 → 症状是「保存后不生效」,`verify:settings` 的重读断言会先红。
|
|
52
|
+
- schemastery 未来把 `.volatile()` 改名 **且** 冻结 `meta` → 标记彻底失效,`verify:settings` 的「live 标记存在」断言会红。
|
|
53
|
+
- 直接写 `meta.volatile` 绕过框架的 volatile 校验;本仓只在**扁平** Config(标的是叶子)上用它。
|
|
54
|
+
- 旧代下给插件行改过 id 的用户,`settings.yaml` 里旧 `dsh-tui-theme` 一节不再生效(键跟随新 id);默认安装 id 不变,且新代本来就以 entry id 为身份——接受并在此记录。
|
|
55
|
+
- 真机确认(2026-09-26):`verify:settings` 对真机 `0.1.7-rc.1` + schemastery 3.18.4 的 20 条断言全绿;构建产物装进本机 `dsh-tui` profile(原 0.7.1 目录整目录备份、profile 依赖声明未改),`dsh --profile dsh-tui --dump-config` 条目 id 与卡片 `ns` 一致;**用户肉眼确认 `/settings` 里 pink-theme 卡片已无 `命名空间未注册` 徽标**(见 `REVIEW.md` T4)。
|
|
56
|
+
|
|
57
|
+
## 关联
|
|
58
|
+
|
|
59
|
+
- 迁移清单与上游动向:dsh-tui-find `docs/decisions/2026-09-24-settings-generation-adaptation.md`(含 dsh-TUI [#990](https://github.com/ccch1mneyyy/dsh-TUI/issues/990) / [PR #991](https://github.com/ccch1mneyyy/dsh-TUI/pull/991))
|
|
60
|
+
- 相关代码:`src/liveConfig.ts`、`src/settingsSection.ts`、`src/index.ts`
|
|
61
|
+
- 相关脚本:`scripts/verify-settings-generation.mjs`(`npm run verify:settings`)、`scripts/verify.mjs` 场景 2d/2e/2f
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* - 缓存背景跟随:安全应用已有的终端背景缓存,在昼樱/夜樱间切换;
|
|
8
8
|
* dsh-TUI 未提供插件终端查询接缝时,不直接读写 stdin、raw mode 或 OSC 11;
|
|
9
9
|
* - 接缝十一(状态行):输入框上方一行小装饰(✿ · 时钟 · 本轮轮数);
|
|
10
|
-
* - 接缝六(设置区块):/settings
|
|
10
|
+
* - 接缝六(设置区块):/settings 里一个可编辑面板,即时生效;宿主设置服务
|
|
11
|
+
* 换代后(dsh-settings ≥0.1.7,dsh-TUI ≥0.11)面板改由本插件 Config 里标了
|
|
12
|
+
* live 的字段投影,命名空间取 Loader 条目 id(liveConfig.ts / settingsSection.ts)。
|
|
11
13
|
*
|
|
12
14
|
* 遵循 #183 纪律:所有宿主服务用 ctx.inject 软探测,缺席即静默降级;
|
|
13
15
|
* 插件缺失或宿主较旧时行为退化为“什么都没发生”,绝不拖垮启动。
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAMjF,eAAO,MAAM,IAAI,kBAAY,CAAA;AAE7B,wDAAwD;AACxD,MAAM,MAAM,MAAM,GAAG,eAAe,CAAA;AAgCpC,eAAO,MAAM,MAAM,EAAE,WAAW,CAAC,MAAM,CAOtC,CAAA;AAoBD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,IAAI,CAmL7D"}
|
package/lib/types/index.js
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* - 缓存背景跟随:安全应用已有的终端背景缓存,在昼樱/夜樱间切换;
|
|
8
8
|
* dsh-TUI 未提供插件终端查询接缝时,不直接读写 stdin、raw mode 或 OSC 11;
|
|
9
9
|
* - 接缝十一(状态行):输入框上方一行小装饰(✿ · 时钟 · 本轮轮数);
|
|
10
|
-
* - 接缝六(设置区块):/settings
|
|
10
|
+
* - 接缝六(设置区块):/settings 里一个可编辑面板,即时生效;宿主设置服务
|
|
11
|
+
* 换代后(dsh-settings ≥0.1.7,dsh-TUI ≥0.11)面板改由本插件 Config 里标了
|
|
12
|
+
* live 的字段投影,命名空间取 Loader 条目 id(liveConfig.ts / settingsSection.ts)。
|
|
11
13
|
*
|
|
12
14
|
* 遵循 #183 纪律:所有宿主服务用 ctx.inject 软探测,缺席即静默降级;
|
|
13
15
|
* 插件缺失或宿主较旧时行为退化为“什么都没发生”,绝不拖垮启动。
|
|
@@ -22,17 +24,14 @@ import { runFollowSystem } from './autoTheme.js';
|
|
|
22
24
|
import { registerPinkSettings } from './settingsSection.js';
|
|
23
25
|
import { startShadowCleanup } from './shadowCleanup.js';
|
|
24
26
|
import { startToastRelay } from './toast.js';
|
|
27
|
+
import { hasLiveConfigFields, isLiveConfigKey, liveField, readConfigValues } from './liveConfig.js';
|
|
25
28
|
import { PLUGIN_ID } from './pluginId.js';
|
|
26
29
|
export const name = PLUGIN_ID;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// in /settings): turning the garnish off entirely is what uninstalling is
|
|
33
|
-
// for, per user feedback. followSystem defaults off for generic installs;
|
|
34
|
-
// the shipped cordis.patch.yml opts this deployment in.
|
|
35
|
-
export const Config = z.object({
|
|
30
|
+
/** The row-config fields in declaration order. The live marking is applied
|
|
31
|
+
* afterwards from `LIVE_CONFIG_KEYS` (liveConfig.ts) so the /settings card's
|
|
32
|
+
* editable set and the marked set cannot drift apart — scripts/verify.mjs
|
|
33
|
+
* asserts both directions of that parity. */
|
|
34
|
+
const configFields = {
|
|
36
35
|
autoInstallThemes: z.boolean().default(true),
|
|
37
36
|
statusEnabled: z.boolean().default(true),
|
|
38
37
|
followSystem: z.boolean().default(false),
|
|
@@ -42,7 +41,25 @@ export const Config = z.object({
|
|
|
42
41
|
showClock: z.boolean().default(true),
|
|
43
42
|
showTurns: z.boolean().default(true),
|
|
44
43
|
statusScope: z.union(['pink-only', 'all-themes']).default('pink-only'),
|
|
45
|
-
}
|
|
44
|
+
};
|
|
45
|
+
// Explicit annotation: the inferred z.dict output references cosmokit's Dict
|
|
46
|
+
// through a pnpm-virtual path, which is not portable in declaration emit
|
|
47
|
+
// (TS2883). Mirrors the official plugin-template's workaround.
|
|
48
|
+
//
|
|
49
|
+
// statusEnabled / autoInstallThemes stay cordis-config knobs only (invisible
|
|
50
|
+
// in /settings, and therefore not marked live): turning the garnish off
|
|
51
|
+
// entirely is what uninstalling is for, per user feedback. followSystem
|
|
52
|
+
// defaults off for generic installs; the shipped cordis.patch.yml opts this
|
|
53
|
+
// deployment in.
|
|
54
|
+
//
|
|
55
|
+
// On a `dsh-settings` ≥0.1.7 host the marked fields below ARE the /settings
|
|
56
|
+
// form schema (the namespace is the profile entry id); on ≤0.1.6 hosts they
|
|
57
|
+
// are ordinary config values and the card's values come from the namespace
|
|
58
|
+
// registration instead.
|
|
59
|
+
export const Config = z.object(Object.fromEntries(Object.entries(configFields).map(([key, field]) => [
|
|
60
|
+
key,
|
|
61
|
+
isLiveConfigKey(key) ? liveField(field) : field,
|
|
62
|
+
])));
|
|
46
63
|
const DEFAULTS = {
|
|
47
64
|
autoInstallThemes: true,
|
|
48
65
|
statusEnabled: true,
|
|
@@ -60,18 +77,22 @@ const DEFAULTS = {
|
|
|
60
77
|
* @param config - Validated plugin config (schema defaults applied).
|
|
61
78
|
*/
|
|
62
79
|
export function apply(ctx, config = {}) {
|
|
80
|
+
// A `dsh-settings` ≥0.1.7 host hands every marked field to apply as a live
|
|
81
|
+
// ref, not as the value it stands for (liveConfig.ts); unwrap before any
|
|
82
|
+
// read, here and in the readLive() probe the settings wiring re-runs.
|
|
83
|
+
const live = readConfigValues(config);
|
|
63
84
|
// The cordis.yml layer: schema defaults plus explicit ?? fallbacks so a
|
|
64
85
|
// bare composition still resolves every knob.
|
|
65
86
|
const cordis = {
|
|
66
|
-
autoInstallThemes:
|
|
67
|
-
statusEnabled:
|
|
68
|
-
followSystem:
|
|
69
|
-
statusGlyph:
|
|
70
|
-
statusSeparator:
|
|
71
|
-
showGlyph:
|
|
72
|
-
showClock:
|
|
73
|
-
showTurns:
|
|
74
|
-
statusScope:
|
|
87
|
+
autoInstallThemes: live.autoInstallThemes ?? DEFAULTS.autoInstallThemes,
|
|
88
|
+
statusEnabled: live.statusEnabled ?? DEFAULTS.statusEnabled,
|
|
89
|
+
followSystem: live.followSystem ?? DEFAULTS.followSystem,
|
|
90
|
+
statusGlyph: live.statusGlyph ?? DEFAULTS.statusGlyph,
|
|
91
|
+
statusSeparator: live.statusSeparator ?? DEFAULTS.statusSeparator,
|
|
92
|
+
showGlyph: live.showGlyph ?? DEFAULTS.showGlyph,
|
|
93
|
+
showClock: live.showClock ?? DEFAULTS.showClock,
|
|
94
|
+
showTurns: live.showTurns ?? DEFAULTS.showTurns,
|
|
95
|
+
statusScope: live.statusScope ?? DEFAULTS.statusScope,
|
|
75
96
|
};
|
|
76
97
|
// User-visible one-liners for the few events worth surfacing (the plugin
|
|
77
98
|
// logger is invisible to a TUI user). Hosts without the 0.10 toast seam
|
|
@@ -189,27 +210,34 @@ export function apply(ctx, config = {}) {
|
|
|
189
210
|
}
|
|
190
211
|
});
|
|
191
212
|
};
|
|
192
|
-
registerPinkSettings(ctx,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
213
|
+
registerPinkSettings(ctx, {
|
|
214
|
+
cordis,
|
|
215
|
+
// The live row config: on ≥0.1.7 hosts the loader rewrites these refs in
|
|
216
|
+
// place, so re-reading after `loader/volatile-update` yields the edit.
|
|
217
|
+
readLive: () => readConfigValues(config),
|
|
218
|
+
hasLiveFields: hasLiveConfigFields(Config),
|
|
219
|
+
onDoc: doc => {
|
|
220
|
+
effective = { ...cordis, ...doc };
|
|
221
|
+
const follow = effective.followSystem === true;
|
|
222
|
+
if (followActive === undefined) {
|
|
223
|
+
// First document: align the baseline, not a switch. A value that only
|
|
224
|
+
// matches the default logs nothing; a user layer that starts enabled
|
|
225
|
+
// still applies the cache immediately.
|
|
226
|
+
followActive = follow;
|
|
227
|
+
if (follow)
|
|
228
|
+
applyFollow(false);
|
|
229
|
+
return;
|
|
208
230
|
}
|
|
209
|
-
|
|
210
|
-
|
|
231
|
+
if (followActive !== follow) {
|
|
232
|
+
followActive = follow;
|
|
233
|
+
if (follow) {
|
|
234
|
+
applyFollow(true);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
ctx.logger.info(`${PLUGIN_ID}: follow: disabled, manual /theme choice preserved`);
|
|
238
|
+
}
|
|
211
239
|
}
|
|
212
|
-
}
|
|
240
|
+
},
|
|
213
241
|
}, dataDir);
|
|
214
242
|
// The follow decision is owned entirely by the /settings layer above: there
|
|
215
243
|
// is no timer or fallback path on hosts without a settings service — the
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live-editable slice of the plugin's row config — the support the
|
|
3
|
+
* `dsh-settings` ≥0.1.7 generation needs (dsh-TUI 0.11+) while the ≤0.1.6
|
|
4
|
+
* generation keeps working unchanged.
|
|
5
|
+
*
|
|
6
|
+
* Two host generations read the same {@link Config} differently, and both must
|
|
7
|
+
* keep working (docs/decisions/… in the dsh-tui-find repo,
|
|
8
|
+
* `2026-09-24-settings-generation-adaptation.md`, is the reference record):
|
|
9
|
+
*
|
|
10
|
+
* - `dsh-settings` ≤0.1.6 (dsh-TUI 0.9.x/0.10.x): the `/settings` namespace is
|
|
11
|
+
* registered by the plugin and its form values come from that registration
|
|
12
|
+
* schema (settingsSection.ts). The row config is a frozen value.
|
|
13
|
+
* - `dsh-settings` ≥0.1.7 (dsh-TUI 0.11+): there is no registration API — the
|
|
14
|
+
* namespace is the profile entry id and the form schema is *this* schema
|
|
15
|
+
* projected onto the fields carrying the volatile marker. Those fields then
|
|
16
|
+
* reach `apply` as live refs whose value the loader rewrites in place, so
|
|
17
|
+
* every read goes through {@link readConfigValues} first.
|
|
18
|
+
*
|
|
19
|
+
* `.volatile()` landed in schemastery 3.18.3 while this plugin's baseline is
|
|
20
|
+
* 3.18.1/3.18.2, hence the capability probe in {@link liveField} — never a
|
|
21
|
+
* version parse. A plugin that misses the transition still boots, still
|
|
22
|
+
* registers its card, and simply renders `命名空间未注册`; a card field whose
|
|
23
|
+
* Config key is not marked renders `(未设置)` forever. Both are silent, which
|
|
24
|
+
* is why the marking is driven by one exported key list (the card↔schema
|
|
25
|
+
* parity is asserted in scripts/verify.mjs and
|
|
26
|
+
* scripts/verify-settings-generation.mjs).
|
|
27
|
+
*
|
|
28
|
+
* @module dsh-tui-theme/liveConfig
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Keys the `/settings` card owns, and therefore the keys the host may edit
|
|
32
|
+
* live. On `dsh-settings` ≥0.1.7 these are exactly the fields the plugin's
|
|
33
|
+
* form projects, so the card's field paths, this list and the marked fields
|
|
34
|
+
* must stay equal — a card field outside the list would render editable yet
|
|
35
|
+
* never be served (the host's own status-bar `cost` field shows that failure
|
|
36
|
+
* mode as `(未设置)` forever), and a marked key without a field would be
|
|
37
|
+
* live-editable with no UI. `autoInstallThemes` / `statusEnabled` are
|
|
38
|
+
* deliberately absent: they stay cordis-config knobs (README §配置).
|
|
39
|
+
*/
|
|
40
|
+
export declare const LIVE_CONFIG_KEYS: readonly ["followSystem", "showGlyph", "statusGlyph", "showClock", "showTurns", "statusSeparator", "statusScope"];
|
|
41
|
+
/** Whether one row-config key is part of the card's editable set. */
|
|
42
|
+
export declare function isLiveConfigKey(key: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Mark one schema field live-editable when the host can project it.
|
|
45
|
+
*
|
|
46
|
+
* Two capability steps, never a version parse:
|
|
47
|
+
*
|
|
48
|
+
* 1. `.volatile()` — schemastery 3.18.3+; returns a marked clone and runs the
|
|
49
|
+
* framework's own volatile validation, so it is preferred wherever it
|
|
50
|
+
* exists.
|
|
51
|
+
* 2. `meta.volatile = true` — the settings projection only reads that plain
|
|
52
|
+
* meta field, so writing it directly works on the 3.18.1/3.18.2 baselines
|
|
53
|
+
* too. This is the fallback dsh-TUI shipped for its own Config after issue
|
|
54
|
+
* #990 (its `editableConfig` silently no-opped on older schemastery and the
|
|
55
|
+
* whole settings page went dead on a 0.1.7 host).
|
|
56
|
+
*
|
|
57
|
+
* Calling `.volatile()` twice throws, so the marker is applied exactly once,
|
|
58
|
+
* from the single {@link LIVE_CONFIG_KEYS} list. A schemastery that froze its
|
|
59
|
+
* `meta` leaves the field unmarked (a dead card, but no boot failure — the
|
|
60
|
+
* host's own choice for third-party plugins).
|
|
61
|
+
*/
|
|
62
|
+
export declare function liveField<T>(field: T): T;
|
|
63
|
+
/**
|
|
64
|
+
* Read a row config down to plain values.
|
|
65
|
+
*
|
|
66
|
+
* On `dsh-settings` ≥0.1.7 (schemastery ≥3.18.3) the loader hands every
|
|
67
|
+
* volatile field to `apply` as a live ref — a frozen object carrying the
|
|
68
|
+
* cosmokit Volatile protocol whose value the loader rewrites in place — so
|
|
69
|
+
* reading the config object again after `loader/volatile-update` yields the
|
|
70
|
+
* edited values (settingsSection.ts rides exactly that). Structural, not an
|
|
71
|
+
* import: the refs are cosmokit's Volatile protocol and cosmokit is not a
|
|
72
|
+
* dependency of this plugin. The row config is flat, so one unwrap level per
|
|
73
|
+
* key is enough; a nested knob would need a recursive walk here.
|
|
74
|
+
*/
|
|
75
|
+
export declare function readConfigValues<T extends object>(config: T | undefined): T;
|
|
76
|
+
/**
|
|
77
|
+
* Whether a row-config schema carries the live marker anywhere — exactly what
|
|
78
|
+
* a `dsh-settings` ≥0.1.7 host needs to serve this plugin's `/settings` page
|
|
79
|
+
* (`volatileForm()` returns undefined without it and the entry never reaches
|
|
80
|
+
* `describe()`, which the TUI renders as `命名空间未注册`).
|
|
81
|
+
*
|
|
82
|
+
* Read structurally: the schemastery 3.18.1/3.18.2 types this repo builds
|
|
83
|
+
* against do not expose `.dict` on the schema type, and the caller owns the
|
|
84
|
+
* schema. settingsSection.ts warns with this when a new-generation host cannot
|
|
85
|
+
* serve the card, instead of leaving a bare badge as the only clue.
|
|
86
|
+
*/
|
|
87
|
+
export declare function hasLiveConfigFields(schema: unknown): boolean;
|
|
88
|
+
//# sourceMappingURL=liveConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveConfig.d.ts","sourceRoot":"","sources":["../../src/liveConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,mHAQnB,CAAA;AAEV,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAYxC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,GAAG,CAAC,CAI3E;AAiCD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAI5D"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live-editable slice of the plugin's row config — the support the
|
|
3
|
+
* `dsh-settings` ≥0.1.7 generation needs (dsh-TUI 0.11+) while the ≤0.1.6
|
|
4
|
+
* generation keeps working unchanged.
|
|
5
|
+
*
|
|
6
|
+
* Two host generations read the same {@link Config} differently, and both must
|
|
7
|
+
* keep working (docs/decisions/… in the dsh-tui-find repo,
|
|
8
|
+
* `2026-09-24-settings-generation-adaptation.md`, is the reference record):
|
|
9
|
+
*
|
|
10
|
+
* - `dsh-settings` ≤0.1.6 (dsh-TUI 0.9.x/0.10.x): the `/settings` namespace is
|
|
11
|
+
* registered by the plugin and its form values come from that registration
|
|
12
|
+
* schema (settingsSection.ts). The row config is a frozen value.
|
|
13
|
+
* - `dsh-settings` ≥0.1.7 (dsh-TUI 0.11+): there is no registration API — the
|
|
14
|
+
* namespace is the profile entry id and the form schema is *this* schema
|
|
15
|
+
* projected onto the fields carrying the volatile marker. Those fields then
|
|
16
|
+
* reach `apply` as live refs whose value the loader rewrites in place, so
|
|
17
|
+
* every read goes through {@link readConfigValues} first.
|
|
18
|
+
*
|
|
19
|
+
* `.volatile()` landed in schemastery 3.18.3 while this plugin's baseline is
|
|
20
|
+
* 3.18.1/3.18.2, hence the capability probe in {@link liveField} — never a
|
|
21
|
+
* version parse. A plugin that misses the transition still boots, still
|
|
22
|
+
* registers its card, and simply renders `命名空间未注册`; a card field whose
|
|
23
|
+
* Config key is not marked renders `(未设置)` forever. Both are silent, which
|
|
24
|
+
* is why the marking is driven by one exported key list (the card↔schema
|
|
25
|
+
* parity is asserted in scripts/verify.mjs and
|
|
26
|
+
* scripts/verify-settings-generation.mjs).
|
|
27
|
+
*
|
|
28
|
+
* @module dsh-tui-theme/liveConfig
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Keys the `/settings` card owns, and therefore the keys the host may edit
|
|
32
|
+
* live. On `dsh-settings` ≥0.1.7 these are exactly the fields the plugin's
|
|
33
|
+
* form projects, so the card's field paths, this list and the marked fields
|
|
34
|
+
* must stay equal — a card field outside the list would render editable yet
|
|
35
|
+
* never be served (the host's own status-bar `cost` field shows that failure
|
|
36
|
+
* mode as `(未设置)` forever), and a marked key without a field would be
|
|
37
|
+
* live-editable with no UI. `autoInstallThemes` / `statusEnabled` are
|
|
38
|
+
* deliberately absent: they stay cordis-config knobs (README §配置).
|
|
39
|
+
*/
|
|
40
|
+
export const LIVE_CONFIG_KEYS = [
|
|
41
|
+
'followSystem',
|
|
42
|
+
'showGlyph',
|
|
43
|
+
'statusGlyph',
|
|
44
|
+
'showClock',
|
|
45
|
+
'showTurns',
|
|
46
|
+
'statusSeparator',
|
|
47
|
+
'statusScope',
|
|
48
|
+
];
|
|
49
|
+
/** Whether one row-config key is part of the card's editable set. */
|
|
50
|
+
export function isLiveConfigKey(key) {
|
|
51
|
+
return LIVE_CONFIG_KEYS.includes(key);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Mark one schema field live-editable when the host can project it.
|
|
55
|
+
*
|
|
56
|
+
* Two capability steps, never a version parse:
|
|
57
|
+
*
|
|
58
|
+
* 1. `.volatile()` — schemastery 3.18.3+; returns a marked clone and runs the
|
|
59
|
+
* framework's own volatile validation, so it is preferred wherever it
|
|
60
|
+
* exists.
|
|
61
|
+
* 2. `meta.volatile = true` — the settings projection only reads that plain
|
|
62
|
+
* meta field, so writing it directly works on the 3.18.1/3.18.2 baselines
|
|
63
|
+
* too. This is the fallback dsh-TUI shipped for its own Config after issue
|
|
64
|
+
* #990 (its `editableConfig` silently no-opped on older schemastery and the
|
|
65
|
+
* whole settings page went dead on a 0.1.7 host).
|
|
66
|
+
*
|
|
67
|
+
* Calling `.volatile()` twice throws, so the marker is applied exactly once,
|
|
68
|
+
* from the single {@link LIVE_CONFIG_KEYS} list. A schemastery that froze its
|
|
69
|
+
* `meta` leaves the field unmarked (a dead card, but no boot failure — the
|
|
70
|
+
* host's own choice for third-party plugins).
|
|
71
|
+
*/
|
|
72
|
+
export function liveField(field) {
|
|
73
|
+
const candidate = field;
|
|
74
|
+
if (typeof candidate.volatile === 'function')
|
|
75
|
+
return candidate.volatile();
|
|
76
|
+
const meta = candidate.meta;
|
|
77
|
+
if (typeof meta === 'object' && meta !== null) {
|
|
78
|
+
try {
|
|
79
|
+
meta.volatile = true;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return field;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return field;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Read a row config down to plain values.
|
|
89
|
+
*
|
|
90
|
+
* On `dsh-settings` ≥0.1.7 (schemastery ≥3.18.3) the loader hands every
|
|
91
|
+
* volatile field to `apply` as a live ref — a frozen object carrying the
|
|
92
|
+
* cosmokit Volatile protocol whose value the loader rewrites in place — so
|
|
93
|
+
* reading the config object again after `loader/volatile-update` yields the
|
|
94
|
+
* edited values (settingsSection.ts rides exactly that). Structural, not an
|
|
95
|
+
* import: the refs are cosmokit's Volatile protocol and cosmokit is not a
|
|
96
|
+
* dependency of this plugin. The row config is flat, so one unwrap level per
|
|
97
|
+
* key is enough; a nested knob would need a recursive walk here.
|
|
98
|
+
*/
|
|
99
|
+
export function readConfigValues(config) {
|
|
100
|
+
const plain = {};
|
|
101
|
+
for (const [key, value] of Object.entries(config ?? {}))
|
|
102
|
+
plain[key] = readRef(value);
|
|
103
|
+
return plain;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The cosmokit Volatile brand, read by name so it matches the host's own copy
|
|
107
|
+
* across module instances (`cosmokit/src/volatile.ts`). Absent from the
|
|
108
|
+
* schemastery 3.18.1/3.18.2 generations this plugin also supports — probing it
|
|
109
|
+
* is a plain symbol lookup, never a version parse, and the shape fallback
|
|
110
|
+
* below still covers a hand-rolled ref.
|
|
111
|
+
*/
|
|
112
|
+
const VOLATILE_WRITE = Symbol.for('cosmokit.volatile.write');
|
|
113
|
+
/**
|
|
114
|
+
* Unwrap one live config ref, if that is what it is.
|
|
115
|
+
*
|
|
116
|
+
* The protocol brand (`cosmokit.volatile.write` in the value, exactly what
|
|
117
|
+
* `isVolatile` checks) is authoritative and is probed FIRST: a real ref may
|
|
118
|
+
* legitimately carry more than the `get` key, and the shape heuristic below
|
|
119
|
+
* would then hand the ref object itself to the caller, which reads it as "not
|
|
120
|
+
* a string/boolean" and silently falls back to the documented default — no
|
|
121
|
+
* warning, no error. The shape check stays as a fallback for a ref built
|
|
122
|
+
* without the brand.
|
|
123
|
+
*/
|
|
124
|
+
function readRef(value) {
|
|
125
|
+
if (typeof value !== 'object' || value === null)
|
|
126
|
+
return value;
|
|
127
|
+
const ref = value;
|
|
128
|
+
const branded = VOLATILE_WRITE in value;
|
|
129
|
+
if (!branded) {
|
|
130
|
+
const keys = Object.keys(value);
|
|
131
|
+
if (keys.length !== 1 || keys[0] !== 'get')
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
134
|
+
return typeof ref.get === 'function' ? readRef(ref.get()) : value;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Whether a row-config schema carries the live marker anywhere — exactly what
|
|
138
|
+
* a `dsh-settings` ≥0.1.7 host needs to serve this plugin's `/settings` page
|
|
139
|
+
* (`volatileForm()` returns undefined without it and the entry never reaches
|
|
140
|
+
* `describe()`, which the TUI renders as `命名空间未注册`).
|
|
141
|
+
*
|
|
142
|
+
* Read structurally: the schemastery 3.18.1/3.18.2 types this repo builds
|
|
143
|
+
* against do not expose `.dict` on the schema type, and the caller owns the
|
|
144
|
+
* schema. settingsSection.ts warns with this when a new-generation host cannot
|
|
145
|
+
* serve the card, instead of leaving a bare badge as the only clue.
|
|
146
|
+
*/
|
|
147
|
+
export function hasLiveConfigFields(schema) {
|
|
148
|
+
const dict = schema
|
|
149
|
+
?.dict;
|
|
150
|
+
return Object.values(dict ?? {}).some(field => field?.meta?.volatile === true);
|
|
151
|
+
}
|
|
@@ -2,12 +2,34 @@
|
|
|
2
2
|
* /settings integration (seam six: tuiSettingsSections over the dsh settings
|
|
3
3
|
* service).
|
|
4
4
|
*
|
|
5
|
-
* Registers the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Registers a declarative editing section for the plugin's settings and, on
|
|
6
|
+
* hosts that still have the registration API, the settings namespace itself.
|
|
7
|
+
* Storage, schema validation, and layered resolution stay on the dsh settings
|
|
8
|
+
* service; the TUI only renders. Fields carry no schema defaults on purpose —
|
|
9
|
+
* an unset user layer must fall through to the cordis config layer (mirrors
|
|
10
|
+
* the host's own lang/fullscreen fields), and format() displays the effective
|
|
11
|
+
* value instead of a misleading blank.
|
|
12
|
+
*
|
|
13
|
+
* Two generations, branched by capability (never by version),
|
|
14
|
+
* `dsh-settings`'s 0.1.7 break being the reason
|
|
15
|
+
* (docs/decisions/2026-09-24-settings-generation-adaptation.md):
|
|
16
|
+
*
|
|
17
|
+
* - **≤0.1.6** (dsh-TUI 0.9.x/0.10.x) — `settings.register(ns, schema)` owns
|
|
18
|
+
* the namespace. The card's paths resolve against the scope schema declared
|
|
19
|
+
* here, and `scope.watch` pushes edits into the plugin.
|
|
20
|
+
* - **≥0.1.7** (dsh-TUI 0.11+) — there is no registration API at all
|
|
21
|
+
* (`SettingsForms` projects each profile entry's *Config* instead). The
|
|
22
|
+
* namespace is this plugin's profile entry id (see
|
|
23
|
+
* {@link resolveSettingsNamespace}) and the form schema is `Config` filtered
|
|
24
|
+
* to its volatile fields (liveConfig.ts). Edits land in the profile patch,
|
|
25
|
+
* the loader rewrites those same refs in place, and
|
|
26
|
+
* `loader/volatile-update` announces it; this module re-reads the live config
|
|
27
|
+
* on that event. The card stays ours, so the auto-generated page is turned
|
|
28
|
+
* off with `configure({ auto: false })`.
|
|
29
|
+
*
|
|
30
|
+
* A miss in either direction is silent and user-visible only as a card that
|
|
31
|
+
* renders but never saves (≤0.1.6) or a `命名空间未注册` badge (≥0.1.7) — hence
|
|
32
|
+
* the branch below warns instead of swallowing the failure.
|
|
11
33
|
*
|
|
12
34
|
* The section splits into two navigation groups (背景跟随 / 状态行). The two
|
|
13
35
|
* text fields (glyph, separator) validate their drafts with parse(): an
|
|
@@ -26,18 +48,54 @@ export type PinkSettingsDoc = StatusOptions & {
|
|
|
26
48
|
/** Apply a cached terminal background: pink-day <-> pink-night. */
|
|
27
49
|
followSystem?: boolean;
|
|
28
50
|
};
|
|
51
|
+
/** The settings namespace this plugin owns by default, and the fallback when
|
|
52
|
+
* the Loader entry id is unusable. On ≥0.1.7 hosts the *entry id* is the
|
|
53
|
+
* namespace the host keys by, so the effective value is
|
|
54
|
+
* {@link resolveSettingsNamespace}: a default install lands on exactly this
|
|
55
|
+
* string (`cordis.patch.yml` pins `id: dsh-tui-theme`), and it stays the name
|
|
56
|
+
* the README documents for settings storage. */
|
|
57
|
+
export declare const SETTINGS_NS = "dsh-tui-theme";
|
|
58
|
+
/**
|
|
59
|
+
* The namespace this plugin's settings live under: the Loader entry id when it
|
|
60
|
+
* satisfies the section grammar, {@link SETTINGS_NS} otherwise.
|
|
61
|
+
*
|
|
62
|
+
* A `dsh-settings` ≥0.1.7 host keys namespaces by the Loader entry id
|
|
63
|
+
* (`SettingsForms.describe()` → `entry.options.id`), so keying the card off
|
|
64
|
+
* anything else breaks the moment the row is renamed — the fragility dsh-TUI
|
|
65
|
+
* #990 records, where even the host's own section had to stop hard-coding its
|
|
66
|
+
* name. Both generations resolve to the same string here, so the card, the
|
|
67
|
+
* legacy registration and the host's projection cannot disagree.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveSettingsNamespace(ctx: Context): string;
|
|
70
|
+
/** Everything the wiring needs from the plugin's own activation. */
|
|
71
|
+
export interface PinkSettingsWiring {
|
|
72
|
+
/** The cordis-config layer (the effective value format() falls back to for
|
|
73
|
+
* still-unset fields). */
|
|
74
|
+
readonly cordis: StatusOptions & {
|
|
75
|
+
followSystem?: boolean;
|
|
76
|
+
};
|
|
77
|
+
/** Current plain values of the plugin's own row config. On ≥0.1.7 hosts the
|
|
78
|
+
* loader rewrites the live refs in place, so calling this again after
|
|
79
|
+
* `loader/volatile-update` yields the edited values. */
|
|
80
|
+
readLive(): PinkSettingsDoc;
|
|
81
|
+
/** Whether the row-config schema carries the live marker
|
|
82
|
+
* (`hasLiveConfigFields(Config)`); diagnostics only. */
|
|
83
|
+
readonly hasLiveFields: boolean;
|
|
84
|
+
/** Receives the defined-valued subset of the settings doc — the initial one
|
|
85
|
+
* and every later edit. */
|
|
86
|
+
onDoc(doc: PinkSettingsDoc): void;
|
|
87
|
+
}
|
|
29
88
|
/**
|
|
30
|
-
* Register the settings
|
|
31
|
-
*
|
|
32
|
-
*
|
|
89
|
+
* Register the /settings section and, on hosts that still have the
|
|
90
|
+
* registration API, the settings namespace behind it. Each part waits for its
|
|
91
|
+
* own service; neither is required for the other.
|
|
33
92
|
*
|
|
34
|
-
* @param ctx - The plugin's own activation context
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* @param
|
|
38
|
-
* initially and on every committed edit.
|
|
93
|
+
* @param ctx - The plugin's own activation context: the Config owner the
|
|
94
|
+
* ≥0.1.7 page policy and the volatile-update listener must attach to (their
|
|
95
|
+
* disposers ride the inject child, which is what a service reload recycles).
|
|
96
|
+
* @param wiring - The value source and sink for the card.
|
|
39
97
|
* @param dataDir - The host data directory (~/.dsh-tui), read by the
|
|
40
98
|
* followSystem field's format() to surface the cached follow state.
|
|
41
99
|
*/
|
|
42
|
-
export declare function registerPinkSettings(ctx: Context,
|
|
100
|
+
export declare function registerPinkSettings(ctx: Context, wiring: PinkSettingsWiring, dataDir?: string): void;
|
|
43
101
|
//# sourceMappingURL=settingsSection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settingsSection.d.ts","sourceRoot":"","sources":["../../src/settingsSection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"settingsSection.d.ts","sourceRoot":"","sources":["../../src/settingsSection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAIpD,+EAA+E;AAC/E,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG;IAC5C,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAkBD;;;;;iDAKiD;AACjD,eAAO,MAAM,WAAW,kBAAY,CAAA;AAcpC;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAG7D;AAED,oEAAoE;AACpE,MAAM,WAAW,kBAAkB;IACjC;+BAC2B;IAC3B,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IAC3D;;6DAEyD;IACzD,QAAQ,IAAI,eAAe,CAAA;IAC3B;6DACyD;IACzD,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B;gCAC4B;IAC5B,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAAA;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,MAA0B,GAClC,IAAI,CAqCN"}
|