@aalis/plugin-session-settings 0.0.0-stage → 0.1.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ace Nyan <ace@acenyan.com>
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.md CHANGED
@@ -1,3 +1,20 @@
1
- # Temporary Holding Version
1
+ # @aalis/plugin-session-settings
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 会话设置:插件配置字段按平台档、平台类型档、场所与会话覆盖的存放、解析与修改,以及 /session 系列指令
4
+ ## 角色
5
+
6
+ 运行时插件
7
+
8
+ ## 安装
9
+
10
+ ```bash
11
+ pnpm add @aalis/plugin-session-settings
12
+ ```
13
+
14
+ ## 文档
15
+
16
+ 详见 [docs/plugins/plugin-session-settings.md](../../docs/plugins/plugin-session-settings.md)。
17
+
18
+ ## 许可
19
+
20
+ 见仓库根目录 LICENSE。
package/dist/caps.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { type BoundOf } from '@aalis/core';
2
+ export declare const uses: {
3
+ sessionManager: import("@aalis/core").ServiceDescriptor<import("@aalis/api-session-manager").SessionManagerService, import("@aalis/api-session-manager").SessionManagerService>;
4
+ events: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").Events, import("@aalis/core").Events>;
5
+ logger: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").Logger, import("@aalis/core").Logger>;
6
+ provide: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").Provide, import("@aalis/core").Provide>;
7
+ services: import("@aalis/core").ServiceDescriptor<(identity: symbol) => import("@aalis/core").Services, import("@aalis/core").Services>;
8
+ hostConfig: import("@aalis/core").OptionalUse<import("@aalis/api-host-config").HostConfig, import("@aalis/api-host-config").HostConfig>;
9
+ platform: import("@aalis/core").OptionalUse<import("@aalis/api-platform").PlatformAdapter, import("@aalis/api-platform").PlatformAdapter>;
10
+ authority: import("@aalis/core").OptionalUse<import("@aalis/api-authority").AuthorityService, import("@aalis/api-authority").AuthorityService>;
11
+ commands: import("@aalis/core").OptionalUse<import("@aalis/api-commands").CommandService, import("@aalis/api-commands").BoundCommands>;
12
+ };
13
+ export type Caps = BoundOf<typeof uses>;
14
+ //# sourceMappingURL=caps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caps.d.ts","sourceRoot":"","sources":["../src/caps.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,OAAO,EAA+C,MAAM,aAAa,CAAC;AAKxF,eAAO,MAAM,IAAI;;;;;;;;;;CAUhB,CAAC;AACF,MAAM,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC"}
package/dist/caps.js ADDED
@@ -0,0 +1,21 @@
1
+ import { authority } from '@aalis/api-authority';
2
+ import { commands } from '@aalis/api-commands';
3
+ import { hostConfig } from '@aalis/api-host-config';
4
+ import { platform } from '@aalis/api-platform';
5
+ import { sessionManager } from '@aalis/api-session-manager';
6
+ import { events, logger, optional, provide, services } from '@aalis/core';
7
+ // 会话设置插件用到的能力。值在会话管理的记录上,会话管理缺席时停在 pending。宿主配置文档缺席时平台档、平台类型档为空,
8
+ // 写这两层与全局层被拒;services 写声明了 preference 的字段的本插件偏好。平台列可设的平台与类型;权限服务给指令判门槛,缺席时
9
+ // 指令一律拒绝写;指令服务缺席时 /session 系列不在
10
+ export const uses = {
11
+ sessionManager,
12
+ events,
13
+ logger,
14
+ provide,
15
+ services,
16
+ hostConfig: optional(hostConfig),
17
+ platform: optional(platform),
18
+ authority: optional(authority),
19
+ commands: optional(commands),
20
+ };
21
+ //# sourceMappingURL=caps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caps.js","sourceRoot":"","sources":["../src/caps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAExF,iEAAiE;AACjE,2EAA2E;AAC3E,gCAAgC;AAChC,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,cAAc;IACd,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC;IAChC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAC5B,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC;CAC7B,CAAC"}
@@ -0,0 +1,60 @@
1
+ import type { UserIdentity } from '@aalis/api-authority';
2
+ import { type SessionAt, type SessionLayerName } from '@aalis/api-session-settings';
3
+ import { type TextRef } from '@aalis/schema-i18n';
4
+ import type { Caps } from './caps.js';
5
+ import type { SessionSettingsProvider } from './provider.js';
6
+ /** 发出者的授权身份 */
7
+ type Identity = {
8
+ platform: string;
9
+ userId?: string;
10
+ };
11
+ /** 回执 */
12
+ type Receipt = {
13
+ ok: boolean;
14
+ text: TextRef;
15
+ };
16
+ export declare class SettingsEditor {
17
+ private readonly provider;
18
+ private readonly caps;
19
+ constructor(provider: SessionSettingsProvider, caps: Caps);
20
+ private get sm();
21
+ /** 这个会话里写到 name 这一层的目标;这个会话没有这一层时给出原因 */
22
+ private target;
23
+ /** 一层的称呼:平台档、平台类型档与场所另写这个会话取的是哪一份;平台类型写声明的显示名,没声明时写类型名 */
24
+ private layerText;
25
+ private placeText;
26
+ /** 指令里怎么写这一项:同名的写成 <实例 id>/<键> */
27
+ private nameOf;
28
+ /** 按项名认项:写成 <实例 id>/<键> 的按全名,只写键的要唯一;重名时给出全部同名的 */
29
+ private find;
30
+ /** 项的门槛与层的门槛都过才写:没过时给出原因 */
31
+ private denied;
32
+ /** 这个身份在这一层能改的项 */
33
+ private editable;
34
+ private editableLine;
35
+ /** 认项、判门槛;不成时给出回执 */
36
+ private resolve;
37
+ /** 写一项,回执写这次改成了什么;落盘失败时另写那一句 */
38
+ private write;
39
+ /** 静态可选项另列一行 */
40
+ private withChoices;
41
+ /**
42
+ * 以 identity 的身份在 sessionId 这个会话里把 itemText 写到 layer 这一层(缺省本会话),值是 valueText 的文字读法。
43
+ * 会话管理还没收录的会话写本会话层之前先建档
44
+ */
45
+ set(identity: Identity, sessionId: string, at: SessionAt, layer: SessionLayerName, itemText: string | undefined, valueText: string | undefined): Promise<Receipt>;
46
+ /** 父会话改子会话设置的工具与 /session.set 写本会话层:同一份 */
47
+ setAs(identity: UserIdentity, sessionId: string, item: string, text: string): Promise<Receipt>;
48
+ /**
49
+ * 恢复继承:给了项只清那一项;不给项时清掉这一层里身份能改的全部项,只用于本会话与场所,平台类型档以上必须写明清哪一项
50
+ */
51
+ reset(identity: Identity, sessionId: string, at: SessionAt, layer: SessionLayerName, itemText: string | undefined): Promise<Receipt>;
52
+ /** /session:只列身份在本会话层能改的项(owner 看到全部),每项写生效值与来源 */
53
+ list(identity: Identity, sessionId: string, at: SessionAt): TextRef;
54
+ /** 来源的称呼:作者默认写「默认」,其余同层的称呼 */
55
+ private sourceText;
56
+ }
57
+ /** 登记 /session 系列(指令服务缺席时登记留着,它上线后生效) */
58
+ export declare function registerCommands(caps: Caps, editor: SettingsEditor): void;
59
+ export {};
60
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKzD,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,KAAK,OAAO,EAAqB,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAA+B,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAO1F,eAAe;AACf,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAUtD,SAAS;AACT,KAAK,OAAO,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAO9C,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBADJ,QAAQ,EAAE,uBAAuB,EACjC,IAAI,EAAE,IAAI;IAG7B,OAAO,KAAK,EAAE,GAEb;IAED,yCAAyC;IACzC,OAAO,CAAC,MAAM;IA0Bd,0DAA0D;IAC1D,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,SAAS;IAKjB,kCAAkC;IAClC,OAAO,CAAC,MAAM;IAId,mDAAmD;IACnD,OAAO,CAAC,IAAI;IAQZ,4BAA4B;IAC5B,OAAO,CAAC,MAAM;IAmBd,mBAAmB;IACnB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,YAAY;IAOpB,qBAAqB;IACrB,OAAO,CAAC,OAAO;IAUf,gCAAgC;YAClB,KAAK;IAoBnB,gBAAgB;IAChB,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACG,GAAG,CACP,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,OAAO,CAAC;IAuBnB,2CAA2C;IAC3C,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9F;;OAEG;IACG,KAAK,CACT,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,MAAM,GAAG,SAAS;IAmC9B,mDAAmD;IACnD,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO;IAyBnE,8BAA8B;IAC9B,OAAO,CAAC,UAAU;CAGnB;AAMD,yCAAyC;AACzC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CA2DzE"}
@@ -0,0 +1,308 @@
1
+ // ════════════════════════════════════════════════════════════
2
+ // 在聊天里看与改设置:/session、/session.set、/session.reset,以及父会话改子会话设置的 setAs(就是 /session.set 写本会话层的
3
+ // 那一段)。
4
+ //
5
+ // 门槛取「项的门槛」与「写在哪一层的门槛」两者中较高的。项的门槛是能力 setting:<实例 id>/<键>,默认按声明的 minLevel(没写即只有
6
+ // owner),交给权限服务的 authorize 裁决,owner 在「操作门槛」里改过的按改过的;层的门槛固定、经 meetsLevel 裁决:本会话不另设,
7
+ // 群与私聊的场所 2 级,工作区场所与平台类型档、平台档、全局只有 owner。所有会话一律判;权限服务不在时一律拒绝。
8
+ // 项与值的写入校验都在提供者的 update 里,这里不做 narrowest 之类的预检,update 拒收时把原因写进回执。
9
+ // ════════════════════════════════════════════════════════════
10
+ import { saveFailureText } from '@aalis/api-host-config';
11
+ import { sessionTypeLabel } from '@aalis/api-platform';
12
+ import { placeLabel, sessionLabel } from '@aalis/api-session-manager';
13
+ import { isSessionSettingsError, layerLabel, SESSION_LAYERS, } from '@aalis/api-session-settings';
14
+ import { readFieldValue } from '@aalis/schema-config';
15
+ import { textLines, textOf } from '@aalis/schema-i18n';
16
+ import { fixedChoices, readText, writeText } from './text-values.js';
17
+ import { itemName, t } from './texts.js';
18
+ /** --at 收的层:层表从窄到宽 */
19
+ const AT_LAYERS = [...SESSION_LAYERS].reverse().map(layer => layer.name);
20
+ const refuse = (text) => ({
21
+ ok: false,
22
+ text: typeof text === 'string' ? textLines([text]) : text,
23
+ });
24
+ export class SettingsEditor {
25
+ provider;
26
+ caps;
27
+ constructor(provider, caps) {
28
+ this.provider = provider;
29
+ this.caps = caps;
30
+ }
31
+ get sm() {
32
+ return this.caps.sessionManager.use;
33
+ }
34
+ /** 这个会话里写到 name 这一层的目标;这个会话没有这一层时给出原因 */
35
+ target(sessionId, at, name) {
36
+ const ctx = this.provider.contextOf(sessionId, at);
37
+ const { platform, type, place } = ctx;
38
+ const owners = Number.POSITIVE_INFINITY;
39
+ const make = (to, minLevel) => ({
40
+ to,
41
+ label: this.layerText(name, ctx),
42
+ minLevel,
43
+ accepts: this.provider.acceptsAt(name, ctx),
44
+ });
45
+ switch (name) {
46
+ case 'session':
47
+ return make({ sessionId }, 0);
48
+ case 'place':
49
+ if (!place)
50
+ return t('notFiled');
51
+ return make({ layer: { scope: 'place', key: place.key } }, place.kind === 'window' ? 2 : owners);
52
+ case 'platformType':
53
+ if (type === undefined || platform === undefined)
54
+ return t('noPlatformType');
55
+ return make({ layer: { scope: 'platformType', platform, type } }, owners);
56
+ case 'platform':
57
+ return make({ layer: { scope: 'platform', platform: platform ?? '' } }, owners);
58
+ case 'global':
59
+ return make({ layer: { scope: 'global' } }, owners);
60
+ }
61
+ }
62
+ /** 一层的称呼:平台档、平台类型档与场所另写这个会话取的是哪一份;平台类型写声明的显示名,没声明时写类型名 */
63
+ layerText(name, { platform = '', type = '', place }) {
64
+ switch (name) {
65
+ case 'platform':
66
+ return t('namedLayer', { layer: layerLabel(name), name: platform });
67
+ case 'platformType':
68
+ return t('platformTypeLayer', {
69
+ layer: layerLabel(name),
70
+ platform,
71
+ type: sessionTypeLabel(this.caps.platform, platform, type) ?? type,
72
+ });
73
+ case 'place':
74
+ return place ? this.placeText(place.key) : layerLabel(name);
75
+ default:
76
+ return layerLabel(name);
77
+ }
78
+ }
79
+ placeText(key) {
80
+ const record = this.sm.getPlace(key);
81
+ return t('placeLayer', { layer: layerLabel('place'), name: record ? placeLabel(record) : key });
82
+ }
83
+ /** 指令里怎么写这一项:同名的写成 <实例 id>/<键> */
84
+ nameOf({ plugin, key }) {
85
+ return this.provider.items().filter(other => other.key === key).length > 1 ? `${plugin}/${key}` : key;
86
+ }
87
+ /** 按项名认项:写成 <实例 id>/<键> 的按全名,只写键的要唯一;重名时给出全部同名的 */
88
+ find(text) {
89
+ const items = this.provider.items();
90
+ const exact = items.find(item => `${item.plugin}/${item.key}` === text);
91
+ if (exact)
92
+ return exact;
93
+ const named = items.filter(item => item.key === text);
94
+ return named.length === 1 ? named[0] : named.length > 1 ? named : undefined;
95
+ }
96
+ /** 项的门槛与层的门槛都过才写:没过时给出原因 */
97
+ denied(identity, item, target) {
98
+ const authority = this.caps.authority.use;
99
+ const itemDenied = authority.authorize(identity, {
100
+ capability: `setting:${item.plugin}/${item.key}`,
101
+ visibility: 'restricted',
102
+ minLevel: item.field.session.minLevel ?? Number.POSITIVE_INFINITY,
103
+ });
104
+ if (itemDenied)
105
+ return itemDenied;
106
+ // 项的门槛已挡掉封禁的身份,层的门槛为 0 时这里恒过
107
+ if (authority.meetsLevel(identity, target.minLevel))
108
+ return null;
109
+ return target.minLevel === Number.POSITIVE_INFINITY
110
+ ? t('layerOwnerOnly', { layer: target.label })
111
+ : t('layerLevel', { layer: target.label, level: target.minLevel });
112
+ }
113
+ /** 这个身份在这一层能改的项 */
114
+ editable(identity, target) {
115
+ return this.provider.items().filter(item => target.accepts(item.field) && !this.denied(identity, item, target));
116
+ }
117
+ editableLine(identity, target) {
118
+ const items = this.editable(identity, target).map(item => this.nameOf(item));
119
+ return items.length > 0
120
+ ? t('editable', { layer: target.label, items })
121
+ : t('noneEditable', { layer: target.label });
122
+ }
123
+ /** 认项、判门槛;不成时给出回执 */
124
+ resolve(identity, target, text) {
125
+ const found = this.find(text);
126
+ if (Array.isArray(found)) {
127
+ return refuse(t('ambiguous', { item: text, items: found.map(item => `${item.plugin}/${item.key}`) }));
128
+ }
129
+ if (!found)
130
+ return refuse(textLines([t('noSuchItem', { item: text }), this.editableLine(identity, target)]));
131
+ const denied = this.denied(identity, found, target);
132
+ return denied ? refuse(denied) : found;
133
+ }
134
+ /** 写一项,回执写这次改成了什么;落盘失败时另写那一句 */
135
+ async write(identity, target, item, value) {
136
+ let saveError;
137
+ try {
138
+ ({ saveError } = await this.provider.update(target.to, { plugin: item.plugin, key: item.key, value }));
139
+ }
140
+ catch (err) {
141
+ if (!isSessionSettingsError(err))
142
+ throw err;
143
+ return refuse(textLines([textOf(err), this.editableLine(identity, target)]));
144
+ }
145
+ const name = this.nameOf(item);
146
+ const done = value === null
147
+ ? t('resetDone', {
148
+ layer: target.label,
149
+ items: [name],
150
+ global: 'layer' in target.to && target.to.layer.scope === 'global' ? 'yes' : 'no',
151
+ })
152
+ : t('setDone', { layer: target.label, item: name, value: writeText(item.field, value) });
153
+ return { ok: true, text: saveError === undefined ? done : textLines([done, saveFailureText(saveError, 'reload')]) };
154
+ }
155
+ /** 静态可选项另列一行 */
156
+ withChoices(text, field) {
157
+ const choices = fixedChoices(field);
158
+ return choices ? textLines([text, t('choices', { choices })]) : text;
159
+ }
160
+ /**
161
+ * 以 identity 的身份在 sessionId 这个会话里把 itemText 写到 layer 这一层(缺省本会话),值是 valueText 的文字读法。
162
+ * 会话管理还没收录的会话写本会话层之前先建档
163
+ */
164
+ async set(identity, sessionId, at, layer, itemText, valueText) {
165
+ if (!this.caps.authority.present)
166
+ return refuse(t('authorityAbsent'));
167
+ if (layer === 'session' && !this.sm.getSession(sessionId))
168
+ await this.sm.ensureSession(sessionId);
169
+ const target = this.target(sessionId, at, layer);
170
+ if (!('to' in target))
171
+ return refuse(target);
172
+ if (itemText === undefined)
173
+ return refuse(textLines([t('needItem'), this.editableLine(identity, target)]));
174
+ const item = this.resolve(identity, target, itemText);
175
+ if ('ok' in item)
176
+ return item;
177
+ const name = this.nameOf(item);
178
+ // 空串是写出来的空值(聊天里的 `""`),照文字读法读
179
+ if (valueText === undefined)
180
+ return refuse(this.withChoices(t('needValue', { item: name }), item.field));
181
+ const parsed = readText(item.field, valueText);
182
+ const read = 'invalid' in parsed ? parsed : readFieldValue(item.field, parsed.value);
183
+ if ('invalid' in read)
184
+ return refuse(this.withChoices(t('invalidValue', { item: itemName(item.field.label, name), reason: read.invalid }), item.field));
185
+ return this.write(identity, target, item, read.value ?? null);
186
+ }
187
+ /** 父会话改子会话设置的工具与 /session.set 写本会话层:同一份 */
188
+ setAs(identity, sessionId, item, text) {
189
+ return this.set(identity, sessionId, {}, 'session', item, text);
190
+ }
191
+ /**
192
+ * 恢复继承:给了项只清那一项;不给项时清掉这一层里身份能改的全部项,只用于本会话与场所,平台类型档以上必须写明清哪一项
193
+ */
194
+ async reset(identity, sessionId, at, layer, itemText) {
195
+ if (!this.caps.authority.present)
196
+ return refuse(t('authorityAbsent'));
197
+ const target = this.target(sessionId, at, layer);
198
+ if (!('to' in target))
199
+ return refuse(target);
200
+ if (itemText !== undefined) {
201
+ const item = this.resolve(identity, target, itemText);
202
+ return 'ok' in item ? item : this.write(identity, target, item, null);
203
+ }
204
+ const set = this.provider
205
+ .rows(target.to)
206
+ .filter(row => row.value !== undefined)
207
+ .map(row => ({ plugin: row.plugin, key: row.key }));
208
+ if (layer !== 'session' && layer !== 'place') {
209
+ const items = set.map(item => this.nameOf(item));
210
+ return refuse(textLines([
211
+ t('resetNeedsItem', { layer: target.label }),
212
+ ...(items.length > 0 ? [t('setHere', { items })] : []),
213
+ ]));
214
+ }
215
+ const clearable = this.editable(identity, target).filter(item => set.some(own => own.plugin === item.plugin && own.key === item.key));
216
+ if (clearable.length === 0)
217
+ return refuse(t('nothingToReset', { layer: target.label }));
218
+ for (const item of clearable) {
219
+ await this.provider.update(target.to, { plugin: item.plugin, key: item.key, value: null });
220
+ }
221
+ return {
222
+ ok: true,
223
+ text: t('resetDone', { layer: target.label, items: clearable.map(item => this.nameOf(item)), global: 'no' }),
224
+ };
225
+ }
226
+ /** /session:只列身份在本会话层能改的项(owner 看到全部),每项写生效值与来源 */
227
+ list(identity, sessionId, at) {
228
+ if (!this.caps.authority.present)
229
+ return t('authorityAbsent');
230
+ const target = this.target(sessionId, at, 'session');
231
+ const ctx = this.provider.contextOf(sessionId, at);
232
+ const editable = this.editable(identity, target);
233
+ const lines = [];
234
+ const session = this.sm.getSession(sessionId);
235
+ lines.push(t('sessionHeader', { session: session ? sessionLabel(session) : sessionId }));
236
+ for (const row of this.provider.rows({ sessionId, at })) {
237
+ const item = editable.find(e => e.plugin === row.plugin && e.key === row.key);
238
+ if (!item)
239
+ continue;
240
+ const params = { label: item.field.label, item: this.nameOf(item) };
241
+ if (row.effective === undefined) {
242
+ const unset = item.field.session.unset ?? t('unsetValue');
243
+ const now = row.actual && (row.actual.label ?? writeText(item.field, row.actual.value));
244
+ lines.push(t('rowUnset', { ...params, value: now ? t('unsetNow', { unset, now }) : unset }));
245
+ }
246
+ else {
247
+ const value = writeText(item.field, row.effective);
248
+ lines.push(t('row', { ...params, value, source: this.sourceText(row.source, ctx) }));
249
+ }
250
+ }
251
+ if (!this.caps.authority.use.isOwner(identity.platform, identity.userId))
252
+ lines.push(t('onlyYours'));
253
+ return textLines(lines);
254
+ }
255
+ /** 来源的称呼:作者默认写「默认」,其余同层的称呼 */
256
+ sourceText(source, ctx) {
257
+ return source === undefined || source === 'default' ? t('sourceDefault') : this.layerText(source, ctx);
258
+ }
259
+ }
260
+ /** 指令的发出者 */
261
+ const identityOf = (argv) => ({ platform: argv.session.platform, userId: argv.session.userId });
262
+ const layerOf = (argv) => argv.options.at ?? 'session';
263
+ /** 登记 /session 系列(指令服务缺席时登记留着,它上线后生效) */
264
+ export function registerCommands(caps, editor) {
265
+ const commands = caps.commands.use;
266
+ const at = (argv) => ({ platform: argv.session.platform });
267
+ commands
268
+ .command('session', t('sessionDescription'), { risk: 'sensitive' })
269
+ .action(argv => editor.list(identityOf(argv), argv.session.sessionId, at(argv)));
270
+ commands
271
+ .command('session.set [item:string] [value:text]', t('setDescription'), {
272
+ risk: 'sensitive',
273
+ examples: [
274
+ '/session.set persona <name>',
275
+ '/session.set --at place llm <instance>/<model>',
276
+ '/session.set -n <name>',
277
+ ],
278
+ })
279
+ .option('at', '--at <layer:string>', { description: t('atDescription'), choices: AT_LAYERS })
280
+ .option('name', '-n <name:string>', { description: t('nameDescription') })
281
+ .argument('item', t('itemArgument'))
282
+ .argument('value', t('valueArgument'))
283
+ .action(async (argv, item, value) => {
284
+ const lines = [];
285
+ const name = typeof argv.options.name === 'string' ? argv.options.name.trim() : '';
286
+ if (name) {
287
+ await caps.sessionManager.use.ensureSession(argv.session.sessionId, { name });
288
+ lines.push(t('renamed', { name }));
289
+ }
290
+ if (item !== undefined || !name) {
291
+ const receipt = await editor.set(identityOf(argv), argv.session.sessionId, at(argv), layerOf(argv), item === undefined ? undefined : String(item), value === undefined ? undefined : String(value));
292
+ lines.push(receipt.text);
293
+ }
294
+ return textLines(lines);
295
+ });
296
+ commands
297
+ .command('session.reset [item:string]', t('resetDescription'), {
298
+ risk: 'sensitive',
299
+ examples: ['/session.reset', '/session.reset persona', '/session.reset --at platformType persona'],
300
+ })
301
+ .option('at', '--at <layer:string>', { description: t('atDescription'), choices: AT_LAYERS })
302
+ .argument('item', t('itemArgument'))
303
+ .action(async (argv, item) => {
304
+ const receipt = await editor.reset(identityOf(argv), argv.session.sessionId, at(argv), layerOf(argv), item === undefined ? undefined : String(item));
305
+ return receipt.text;
306
+ });
307
+ }
308
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
package/dist/doc.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ /** 一个实例在一处写的值 */
2
+ export type Values = Record<string, unknown>;
3
+ /** 实例 id → 值 */
4
+ type Instances = Map<string, Values>;
5
+ /** 文档里的两层,形状已核过 */
6
+ export interface DocLayers {
7
+ platforms: Map<string, Instances>;
8
+ /** 平台 → 类型名 → 各实例的值 */
9
+ platformTypes: Map<string, Map<string, Instances>>;
10
+ }
11
+ /** 层标识里的平台名与类型名:与窗口键 `平台:类型:目标` 的段同一套写法(非空、不含 `:`、不是 `*`),还要能当配置文档里的对象键 */
12
+ export declare function isLayerName(name: unknown): name is string;
13
+ export declare const isRecord: (value: unknown) => value is Values;
14
+ /** 读文档时的两个依据:这个实例 id 认不认识(已登记或配置文档里有它的配置段),与告警(调用方去重) */
15
+ interface ReadContext {
16
+ known(instance: string): boolean;
17
+ warn(message: string): void;
18
+ }
19
+ /** 读出文档里的两层(交出的是复制品之上的整理结果) */
20
+ export declare function readDoc(doc: unknown, ctx: ReadContext): DocLayers;
21
+ /**
22
+ * 在原样的 sessionConfig 上只改一处(path 是 sessionConfig 之下到实例的各段)的这一项:stored 为 null 即删掉,删空了的对象沿路径
23
+ * 逐级删掉(sessionConfig 自己留着);别的部分(含读不懂的)原样留着。要写的路径上已有的值不是对象时不改,返回那一段的路径;删的
24
+ * 时候路径不在就什么都不改
25
+ */
26
+ export declare function putDocValue(doc: unknown, path: readonly string[], key: string, stored: unknown): {
27
+ doc: unknown;
28
+ } | {
29
+ notObject: string;
30
+ };
31
+ export {};
32
+ //# sourceMappingURL=doc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../src/doc.ts"],"names":[],"mappings":"AASA,iBAAiB;AACjB,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7C,gBAAgB;AAChB,KAAK,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErC,mBAAmB;AACnB,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,uBAAuB;IACvB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;CACpD;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAEzD;AAED,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACmB,CAAC;AAIvE,yDAAyD;AACzD,UAAU,WAAW;IACnB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAiCD,+BAA+B;AAC/B,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,SAAS,CAuBjE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,GACd;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAoB1C"}
package/dist/doc.js ADDED
@@ -0,0 +1,103 @@
1
+ // ════════════════════════════════════════════════════════════
2
+ // 宿主配置文档里的两层:sessionConfig 的平台档(platforms)与平台类型档(platformTypes),每处按插件实例 id 放这个实例的值。
3
+ // 读的时候核形状:不认识的段、名字不合层标识写法的条目、不是对象的实例值告警后忽略;既没登记、配置文档的 plugins 里也没有的
4
+ // 实例 id 告警一次,值留着不生效。值本身在解析时按字段校验。写的时候在原样的文档上只改这一处的这一项,读不懂的部分原样留着。
5
+ // 留空的段(配置文件里只剩键名,读出来是 null)读写都与没有这一段同样处理。
6
+ // ════════════════════════════════════════════════════════════
7
+ import { isUnsafeConfigKey } from '@aalis/schema-config';
8
+ /** 层标识里的平台名与类型名:与窗口键 `平台:类型:目标` 的段同一套写法(非空、不含 `:`、不是 `*`),还要能当配置文档里的对象键 */
9
+ export function isLayerName(name) {
10
+ return typeof name === 'string' && name !== '' && name !== '*' && !name.includes(':') && !isUnsafeConfigKey(name);
11
+ }
12
+ export const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
13
+ const SECTIONS = new Set(['platforms', 'platformTypes']);
14
+ /** 名字 → 对象的一张表:名字不合写法、值不是对象的告警后忽略 */
15
+ function table(value, path, ctx) {
16
+ const out = new Map();
17
+ if (value == null)
18
+ return out;
19
+ if (!isRecord(value)) {
20
+ ctx.warn(`宿主配置 ${path} 不是对象,已忽略`);
21
+ return out;
22
+ }
23
+ for (const [name, entry] of Object.entries(value)) {
24
+ if (!isLayerName(name))
25
+ ctx.warn(`宿主配置 ${path} 里的「${name}」不合法(非空、不含 :、不是 *),已忽略`);
26
+ else if (isRecord(entry))
27
+ out.set(name, entry);
28
+ else if (entry != null)
29
+ ctx.warn(`宿主配置 ${path}.${name} 不是对象,已忽略`);
30
+ }
31
+ return out;
32
+ }
33
+ /** 一处各实例的值:实例值不是对象的告警后忽略,不认识的实例告警一次、照样留着 */
34
+ function instances(value, path, ctx) {
35
+ const out = new Map();
36
+ for (const [instance, values] of Object.entries(value)) {
37
+ if (isUnsafeConfigKey(instance) || values == null)
38
+ continue;
39
+ if (!isRecord(values)) {
40
+ ctx.warn(`宿主配置 ${path}.${instance} 不是对象,已忽略`);
41
+ continue;
42
+ }
43
+ if (!ctx.known(instance))
44
+ ctx.warn(`宿主配置 ${path} 里的 ${instance} 不是已装的插件实例,这一段不生效`);
45
+ out.set(instance, values);
46
+ }
47
+ return out;
48
+ }
49
+ /** 读出文档里的两层(交出的是复制品之上的整理结果) */
50
+ export function readDoc(doc, ctx) {
51
+ const layers = { platforms: new Map(), platformTypes: new Map() };
52
+ if (doc == null)
53
+ return layers;
54
+ if (!isRecord(doc)) {
55
+ ctx.warn('宿主配置 sessionConfig 不是对象,已忽略');
56
+ return layers;
57
+ }
58
+ for (const key of Object.keys(doc)) {
59
+ if (!SECTIONS.has(key)) {
60
+ ctx.warn(`宿主配置 sessionConfig.${key} 不认识(只有 platforms、platformTypes),已忽略`);
61
+ }
62
+ }
63
+ for (const [name, value] of table(doc.platforms, 'sessionConfig.platforms', ctx)) {
64
+ layers.platforms.set(name, instances(value, `sessionConfig.platforms.${name}`, ctx));
65
+ }
66
+ for (const [platform, byType] of table(doc.platformTypes, 'sessionConfig.platformTypes', ctx)) {
67
+ const path = `sessionConfig.platformTypes.${platform}`;
68
+ layers.platformTypes.set(platform, new Map([...table(byType, path, ctx)].map(([type, value]) => [type, instances(value, `${path}.${type}`, ctx)])));
69
+ }
70
+ return layers;
71
+ }
72
+ /**
73
+ * 在原样的 sessionConfig 上只改一处(path 是 sessionConfig 之下到实例的各段)的这一项:stored 为 null 即删掉,删空了的对象沿路径
74
+ * 逐级删掉(sessionConfig 自己留着);别的部分(含读不懂的)原样留着。要写的路径上已有的值不是对象时不改,返回那一段的路径;删的
75
+ * 时候路径不在就什么都不改
76
+ */
77
+ export function putDocValue(doc, path, key, stored) {
78
+ const segments = ['sessionConfig', ...path];
79
+ const holder = { sessionConfig: doc };
80
+ const nodes = [holder];
81
+ for (const [i, name] of segments.entries()) {
82
+ const node = nodes[i];
83
+ const next = Object.hasOwn(node, name) ? node[name] : undefined;
84
+ if (next == null) {
85
+ if (stored === null)
86
+ return { doc };
87
+ node[name] = {};
88
+ }
89
+ else if (!isRecord(next)) {
90
+ return stored === null ? { doc } : { notObject: segments.slice(0, i + 1).join('.') };
91
+ }
92
+ nodes.push(node[name]);
93
+ }
94
+ const target = nodes[segments.length];
95
+ if (stored === null)
96
+ delete target[key];
97
+ else
98
+ target[key] = stored;
99
+ for (let i = segments.length; i > 1 && Object.keys(nodes[i]).length === 0; i--)
100
+ delete nodes[i - 1][segments[i - 1]];
101
+ return { doc: holder.sessionConfig };
102
+ }
103
+ //# sourceMappingURL=doc.js.map