@coralai/sps-cli 0.69.1 → 0.69.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/CHANGELOG.md +10 -0
- package/assembly/base.yml +5 -0
- package/dist/seams/compat-dsh/index.d.ts.map +1 -1
- package/dist/seams/compat-dsh/index.js +4 -1
- package/dist/seams/compat-dsh/index.js.map +1 -1
- package/dist/seams/compat-dsh/settings.d.ts +35 -0
- package/dist/seams/compat-dsh/settings.d.ts.map +1 -0
- package/dist/seams/compat-dsh/settings.js +35 -0
- package/dist/seams/compat-dsh/settings.js.map +1 -0
- package/dist/seams/settings/index.d.ts +76 -0
- package/dist/seams/settings/index.d.ts.map +1 -0
- package/dist/seams/settings/index.js +99 -0
- package/dist/seams/settings/index.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.69.2
|
|
4
|
+
|
|
5
|
+
- **feat(seam)**: `sps.settings` —— 插件按命名空间读自己的配置(dsh 抽样第 12 位)。
|
|
6
|
+
🔴 **真源仍是装配档那一行的 `config`,不另起一份** —— 另起一份的后果是两个真源:
|
|
7
|
+
页面改了 A、插件读的是 B,而两边都"没错",这类不一致最难查。
|
|
8
|
+
`update` / `replace` 明确不做:插件改自己的持久配置会绕过"改配置即重挂"那条链。
|
|
9
|
+
- **fix(compat)**: `dsh-map-tools` 先前有个内层 fiber 卡在 `缺提供方,在等:settings`,
|
|
10
|
+
现在完整挂起来了。
|
|
11
|
+
|
|
12
|
+
|
|
3
13
|
## 0.69.1
|
|
4
14
|
|
|
5
15
|
- 🔴 **fix(mcp)**: **插件注册的工具从来没到过 agent 面前。**
|
package/assembly/base.yml
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/seams/compat-dsh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/seams/compat-dsh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAanD,eAAO,MAAM,IAAI,mBAAmB,CAAC;AACrC,eAAO,MAAM,MAAM,UAAqE,CAAC;AAEzF,eAAO,MAAM,QAAQ,iBAAO,CAAC;AAC7B,eAAO,MAAM,WAAW,kMAC6B,CAAC;AAEtD,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAOxC"}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { ATTACHMENTS } from '../attachments/index.js';
|
|
2
2
|
import { CREDENTIALS } from '../credentials/index.js';
|
|
3
|
+
import { SETTINGS } from '../settings/index.js';
|
|
3
4
|
import { SUBPROCESS } from '../subprocess/index.js';
|
|
4
5
|
import { TOOLS } from '../tools/index.js';
|
|
5
6
|
import { WEBSERVER } from '../webserver/index.js';
|
|
6
7
|
import { DshCredentialsCompat } from './credentials.js';
|
|
7
8
|
import { DshAttachmentsCompat, DshSubprocessCompat } from './misc.js';
|
|
9
|
+
import { DshSettingsCompat } from './settings.js';
|
|
8
10
|
import { DshToolsCompat } from './tools.js';
|
|
9
11
|
import { DshWebServerCompat } from './webserver.js';
|
|
10
12
|
export const name = 'sps-compat-dsh';
|
|
11
|
-
export const inject = [TOOLS, CREDENTIALS, WEBSERVER, SUBPROCESS, ATTACHMENTS];
|
|
13
|
+
export const inject = [TOOLS, CREDENTIALS, WEBSERVER, SUBPROCESS, ATTACHMENTS, SETTINGS];
|
|
12
14
|
export const category = '兼容';
|
|
13
15
|
export const description = '让 dsh 插件能在 sps 里跑:把 dsh 的服务名映射到 sps 的实现。只挂对得上的那些。';
|
|
14
16
|
export function apply(ctx) {
|
|
@@ -17,5 +19,6 @@ export function apply(ctx) {
|
|
|
17
19
|
ctx.plugin(DshWebServerCompat);
|
|
18
20
|
ctx.plugin(DshSubprocessCompat);
|
|
19
21
|
ctx.plugin(DshAttachmentsCompat);
|
|
22
|
+
ctx.plugin(DshSettingsCompat);
|
|
20
23
|
}
|
|
21
24
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/compat-dsh/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,CAAC,MAAM,IAAI,GAAG,gBAAgB,CAAC;AACrC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/compat-dsh/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,CAAC,MAAM,IAAI,GAAG,gBAAgB,CAAC;AACrC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;AAEzF,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC;AAC7B,MAAM,CAAC,MAAM,WAAW,GACtB,mDAAmD,CAAC;AAEtD,MAAM,UAAU,KAAK,CAAC,GAAY;IAChC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC3B,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACjC,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/B,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAChC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACjC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module seams/compat-dsh/settings
|
|
3
|
+
* @description dsh 的 `ctx.settings` → sps 的 `sps.settings`。
|
|
4
|
+
*
|
|
5
|
+
* @layer seam
|
|
6
|
+
*
|
|
7
|
+
* ⚠️ dsh 插件不只调 `ctx.settings.register`,还会 import
|
|
8
|
+
* `installSettingsSection` / `settingsNamespace`(来自 `@deepseek-ai/dsh-settings`)。
|
|
9
|
+
* 那个包会跟着 `npm install` 一起装下来,而它内部调的就是 `ctx.settings.register` ——
|
|
10
|
+
* 所以我们**只要把服务名挂上**,那条路自然通。
|
|
11
|
+
* 实测 `dsh-map-tools` 的 `settings-ns.js` 走的正是这条。
|
|
12
|
+
*
|
|
13
|
+
* 🔴 `update` / `replace` **不做**:插件自己改自己的持久配置会绕过
|
|
14
|
+
* "改配置 ⇒ 重挂"那条链,变成"进程里变了、文件没变"。明确抛,不静默。
|
|
15
|
+
*/
|
|
16
|
+
import { type Context, Service } from '@deepseek-ai/cordis';
|
|
17
|
+
import { type SettingsScope } from '../settings/index.js';
|
|
18
|
+
export declare class DshSettingsCompat extends Service {
|
|
19
|
+
constructor(ctx: Context);
|
|
20
|
+
register<T>(ns: string, schema?: unknown, options?: {
|
|
21
|
+
base?: T;
|
|
22
|
+
}): SettingsScope<T>;
|
|
23
|
+
describe(): {
|
|
24
|
+
ns: string;
|
|
25
|
+
schema: unknown;
|
|
26
|
+
}[];
|
|
27
|
+
update(): never;
|
|
28
|
+
replace(): never;
|
|
29
|
+
}
|
|
30
|
+
declare module '@deepseek-ai/cordis' {
|
|
31
|
+
interface Context {
|
|
32
|
+
settings: DshSettingsCompat;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/seams/compat-dsh/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEpE,qBAAa,iBAAkB,SAAQ,OAAO;gBAChC,GAAG,EAAE,OAAO;IAIxB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,CAAA;KAAE,GAAG,aAAa,CAAC,CAAC,CAAC;IAInF,QAAQ,IAAI;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE;IAI7C,MAAM,IAAI,KAAK;IAMf,OAAO,IAAI,KAAK;CAGjB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,QAAQ,EAAE,iBAAiB,CAAC;KAC7B;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module seams/compat-dsh/settings
|
|
3
|
+
* @description dsh 的 `ctx.settings` → sps 的 `sps.settings`。
|
|
4
|
+
*
|
|
5
|
+
* @layer seam
|
|
6
|
+
*
|
|
7
|
+
* ⚠️ dsh 插件不只调 `ctx.settings.register`,还会 import
|
|
8
|
+
* `installSettingsSection` / `settingsNamespace`(来自 `@deepseek-ai/dsh-settings`)。
|
|
9
|
+
* 那个包会跟着 `npm install` 一起装下来,而它内部调的就是 `ctx.settings.register` ——
|
|
10
|
+
* 所以我们**只要把服务名挂上**,那条路自然通。
|
|
11
|
+
* 实测 `dsh-map-tools` 的 `settings-ns.js` 走的正是这条。
|
|
12
|
+
*
|
|
13
|
+
* 🔴 `update` / `replace` **不做**:插件自己改自己的持久配置会绕过
|
|
14
|
+
* "改配置 ⇒ 重挂"那条链,变成"进程里变了、文件没变"。明确抛,不静默。
|
|
15
|
+
*/
|
|
16
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
17
|
+
import { SETTINGS } from '../settings/index.js';
|
|
18
|
+
export class DshSettingsCompat extends Service {
|
|
19
|
+
constructor(ctx) {
|
|
20
|
+
super(ctx, 'settings');
|
|
21
|
+
}
|
|
22
|
+
register(ns, schema, options) {
|
|
23
|
+
return this.ctx[SETTINGS].register(ns, schema, options);
|
|
24
|
+
}
|
|
25
|
+
describe() {
|
|
26
|
+
return this.ctx[SETTINGS].describe();
|
|
27
|
+
}
|
|
28
|
+
update() {
|
|
29
|
+
throw new Error('settings.update 尚未支持 —— 插件改自己的持久配置会绕过"改配置即重挂"那条链');
|
|
30
|
+
}
|
|
31
|
+
replace() {
|
|
32
|
+
throw new Error('settings.replace 尚未支持(理由同 update)');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/seams/compat-dsh/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAgB,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAsB,MAAM,sBAAsB,CAAC;AAEpE,MAAM,OAAO,iBAAkB,SAAQ,OAAO;IAC5C,YAAY,GAAY;QACtB,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACzB,CAAC;IAED,QAAQ,CAAI,EAAU,EAAE,MAAgB,EAAE,OAAsB;QAC9D,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACvC,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,KAAK,CACb,kDAAkD,CACnD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module seams/settings
|
|
3
|
+
* @description **设置分区 seam** —— 插件按命名空间读写自己的配置。
|
|
4
|
+
*
|
|
5
|
+
* @layer seam
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **真源是装配档那一行的 `config`,不另起一份。**
|
|
8
|
+
* dsh 的 `settings` 是"插件的配置分区";我们的插件配置已经在
|
|
9
|
+
* `~/.coral/assembly/*.yml` 的 `config` 里,插件页也在改它。
|
|
10
|
+
* 再存一份的后果是**两个真源**:页面改了 A、插件读的是 B,
|
|
11
|
+
* 而两边都"没错" —— 这类不一致最难查。
|
|
12
|
+
*
|
|
13
|
+
* ⇒ 这一层只做三件事:
|
|
14
|
+
* ① 让插件按 ns 拿到自己的值(= 装配档那行的 config,补上 schema 默认值)
|
|
15
|
+
* ② 值变了通知它(`watch`)—— 我们改配置本来就会重挂,`watch` 是给
|
|
16
|
+
* 不想被重挂打断的插件用的
|
|
17
|
+
* ③ 记下 ns → schema,供设置界面渲染
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ **`update` / `replace` 会写装配档**,而装配档的写入方是 console 那条路。
|
|
20
|
+
* 这里的实现故意不写盘 —— 插件自己改自己的持久配置,会绕过
|
|
21
|
+
* "改配置 ⇒ 重挂"那条链,变成"进程里变了、文件没变"。
|
|
22
|
+
* 要支持的话得先把写入收口到一处,那是另一件事。
|
|
23
|
+
*/
|
|
24
|
+
import { type Context, Service } from '@deepseek-ai/cordis';
|
|
25
|
+
export declare const SETTINGS = "sps.settings";
|
|
26
|
+
export declare function settingsNamespace(ns: string): string;
|
|
27
|
+
export interface SettingsScope<T = unknown> {
|
|
28
|
+
get(): T;
|
|
29
|
+
watch(cb: (next: T, prev: T) => void): () => void;
|
|
30
|
+
}
|
|
31
|
+
export default class SettingsSeam extends Service {
|
|
32
|
+
private readonly byNs;
|
|
33
|
+
/** ns → 当前值。由装配档的 config 灌进来(见 `setSection`)。 */
|
|
34
|
+
private readonly values;
|
|
35
|
+
constructor(ctx: Context);
|
|
36
|
+
/**
|
|
37
|
+
* 注册一个命名空间。**重复注册当场抛** —— 两个插件抢同一个 ns,
|
|
38
|
+
* 静默后来者赢会让"没生效的那个"完全无法解释。
|
|
39
|
+
*/
|
|
40
|
+
register<T>(ns: string, schema?: unknown, options?: {
|
|
41
|
+
base?: T;
|
|
42
|
+
}): SettingsScope<T>;
|
|
43
|
+
/** 解析值:注册时的 base 叠上当前分区值。 */
|
|
44
|
+
get(ns: string): unknown;
|
|
45
|
+
/**
|
|
46
|
+
* 灌入一个分区的值(装配档的 config → 这里)。变了才通知 watcher。
|
|
47
|
+
* 🔴 通知失败不能连累其它 watcher —— 一个插件的回调抛了,
|
|
48
|
+
* 不该让同一次变更的其他订阅者收不到。
|
|
49
|
+
*/
|
|
50
|
+
setSection(ns: string, value: unknown): void;
|
|
51
|
+
/** 已注册的命名空间及其 schema —— 设置界面据此渲染。 */
|
|
52
|
+
describe(): {
|
|
53
|
+
ns: string;
|
|
54
|
+
schema: unknown;
|
|
55
|
+
}[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* ⚠️ **这里曾经有一个"把装配档的 config 灌进分区"的函数,已经删掉。**
|
|
59
|
+
*
|
|
60
|
+
* 那个方向是错的,两个理由:
|
|
61
|
+
* ① **时序**:插件在 `apply` 里就要读配置(map-tools 用它拼工具名),
|
|
62
|
+
* 而灌只能发生在 `loader.create` 之后 —— 插件已经拿 base 跑完了。
|
|
63
|
+
* ② **键对不上**:命名空间由插件自己起(map-tools 用 `dsh-map-tools`),
|
|
64
|
+
* 而装配档的行 id 是 `map-tools`。按行 id 灌会灌进一个没人读的分区。
|
|
65
|
+
*
|
|
66
|
+
* 🔴 真正的路是 dsh 已经铺好的那条:**行的 `config` 由 loader 作为
|
|
67
|
+
* `apply(ctx, config)` 的第二参交给插件,插件自己把它当 `base` 传进 register**
|
|
68
|
+
* (`installSettingsSection(ctx, ns, schema, entry, …)` 里的 `entry` 就是它)。
|
|
69
|
+
* 我们什么都不用做 —— 我加的那段是**多余的一条并行链路**。
|
|
70
|
+
*/
|
|
71
|
+
declare module '@deepseek-ai/cordis' {
|
|
72
|
+
interface Context {
|
|
73
|
+
'sps.settings': SettingsSeam;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/seams/settings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE5D,eAAO,MAAM,QAAQ,iBAAiB,CAAC;AAIvC,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,GAAG,IAAI,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACnD;AASD,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IACxD,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;gBAEzC,GAAG,EAAE,OAAO;IAIxB;;;OAGG;IACH,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,CAAC,CAAA;KAAE,GAAG,aAAa,CAAC,CAAC,CAAC;IAoBnF,6BAA6B;IAC7B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAUxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAc5C,qCAAqC;IACrC,QAAQ,IAAI;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE;CAG9C;AAED;;;;;;;;;;;;;GAaG;AAEH,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,cAAc,EAAE,YAAY,CAAC;KAC9B;CACF"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module seams/settings
|
|
3
|
+
* @description **设置分区 seam** —— 插件按命名空间读写自己的配置。
|
|
4
|
+
*
|
|
5
|
+
* @layer seam
|
|
6
|
+
*
|
|
7
|
+
* 🔴 **真源是装配档那一行的 `config`,不另起一份。**
|
|
8
|
+
* dsh 的 `settings` 是"插件的配置分区";我们的插件配置已经在
|
|
9
|
+
* `~/.coral/assembly/*.yml` 的 `config` 里,插件页也在改它。
|
|
10
|
+
* 再存一份的后果是**两个真源**:页面改了 A、插件读的是 B,
|
|
11
|
+
* 而两边都"没错" —— 这类不一致最难查。
|
|
12
|
+
*
|
|
13
|
+
* ⇒ 这一层只做三件事:
|
|
14
|
+
* ① 让插件按 ns 拿到自己的值(= 装配档那行的 config,补上 schema 默认值)
|
|
15
|
+
* ② 值变了通知它(`watch`)—— 我们改配置本来就会重挂,`watch` 是给
|
|
16
|
+
* 不想被重挂打断的插件用的
|
|
17
|
+
* ③ 记下 ns → schema,供设置界面渲染
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ **`update` / `replace` 会写装配档**,而装配档的写入方是 console 那条路。
|
|
20
|
+
* 这里的实现故意不写盘 —— 插件自己改自己的持久配置,会绕过
|
|
21
|
+
* "改配置 ⇒ 重挂"那条链,变成"进程里变了、文件没变"。
|
|
22
|
+
* 要支持的话得先把写入收口到一处,那是另一件事。
|
|
23
|
+
*/
|
|
24
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
25
|
+
export const SETTINGS = 'sps.settings';
|
|
26
|
+
const NS_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
27
|
+
export function settingsNamespace(ns) {
|
|
28
|
+
if (!NS_PATTERN.test(ns)) {
|
|
29
|
+
throw new TypeError(`settings 命名空间 "${ns}" 必须匹配 ${String(NS_PATTERN)}`);
|
|
30
|
+
}
|
|
31
|
+
return ns;
|
|
32
|
+
}
|
|
33
|
+
export default class SettingsSeam extends Service {
|
|
34
|
+
byNs = new Map();
|
|
35
|
+
/** ns → 当前值。由装配档的 config 灌进来(见 `setSection`)。 */
|
|
36
|
+
values = new Map();
|
|
37
|
+
constructor(ctx) {
|
|
38
|
+
super(ctx, SETTINGS);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 注册一个命名空间。**重复注册当场抛** —— 两个插件抢同一个 ns,
|
|
42
|
+
* 静默后来者赢会让"没生效的那个"完全无法解释。
|
|
43
|
+
*/
|
|
44
|
+
register(ns, schema, options) {
|
|
45
|
+
settingsNamespace(ns);
|
|
46
|
+
if (this.byNs.has(ns))
|
|
47
|
+
throw new Error(`settings 命名空间已被注册:${ns}`);
|
|
48
|
+
const reg = { schema, base: options?.base ?? {}, watchers: new Set() };
|
|
49
|
+
this.byNs.set(ns, reg);
|
|
50
|
+
// 注册是调用方 fiber 上的 effect:插件卸载时这个 ns 跟着消失
|
|
51
|
+
this.ctx.effect(() => () => {
|
|
52
|
+
this.byNs.delete(ns);
|
|
53
|
+
this.values.delete(ns);
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
get: () => this.get(ns),
|
|
57
|
+
watch: (cb) => {
|
|
58
|
+
const w = cb;
|
|
59
|
+
reg.watchers.add(w);
|
|
60
|
+
return () => reg.watchers.delete(w);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** 解析值:注册时的 base 叠上当前分区值。 */
|
|
65
|
+
get(ns) {
|
|
66
|
+
const reg = this.byNs.get(ns);
|
|
67
|
+
const base = reg?.base;
|
|
68
|
+
const cur = this.values.get(ns);
|
|
69
|
+
if (base && typeof base === 'object' && cur && typeof cur === 'object') {
|
|
70
|
+
return { ...base, ...cur };
|
|
71
|
+
}
|
|
72
|
+
return cur ?? base ?? {};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 灌入一个分区的值(装配档的 config → 这里)。变了才通知 watcher。
|
|
76
|
+
* 🔴 通知失败不能连累其它 watcher —— 一个插件的回调抛了,
|
|
77
|
+
* 不该让同一次变更的其他订阅者收不到。
|
|
78
|
+
*/
|
|
79
|
+
setSection(ns, value) {
|
|
80
|
+
const prev = this.get(ns);
|
|
81
|
+
this.values.set(ns, value);
|
|
82
|
+
const next = this.get(ns);
|
|
83
|
+
if (JSON.stringify(prev) === JSON.stringify(next))
|
|
84
|
+
return;
|
|
85
|
+
for (const w of this.byNs.get(ns)?.watchers ?? []) {
|
|
86
|
+
try {
|
|
87
|
+
w(next, prev);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
console.error(`settings watcher(${ns})抛了:${e instanceof Error ? e.message : e}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** 已注册的命名空间及其 schema —— 设置界面据此渲染。 */
|
|
95
|
+
describe() {
|
|
96
|
+
return [...this.byNs.entries()].map(([ns, r]) => ({ ns, schema: r.schema ?? null }));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/seams/settings/index.ts"],"names":[],"mappings":"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"}
|