@zhin.js/plugin-group-suite 1.1.25 → 1.1.26

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -1
  3. package/commands/checkin/index.js +3 -3
  4. package/commands/checkin/index.ts +3 -3
  5. package/commands/forget/index.js +1 -1
  6. package/commands/forget/index.ts +1 -1
  7. package/commands/keyword-add/[keyword]/index.js +1 -1
  8. package/commands/keyword-add/[keyword]/index.ts +1 -1
  9. package/commands/keyword-remove/[keyword]/index.js +1 -1
  10. package/commands/keyword-remove/[keyword]/index.ts +1 -1
  11. package/commands/rank/index.js +3 -3
  12. package/commands/rank/index.ts +3 -3
  13. package/commands/stats/index.js +3 -3
  14. package/commands/stats/index.ts +3 -3
  15. package/commands/stats-card/index.js +2 -2
  16. package/commands/stats-card/index.ts +2 -2
  17. package/commands/stats-rank/index.js +3 -3
  18. package/commands/stats-rank/index.ts +3 -3
  19. package/commands/stats-week/index.js +3 -3
  20. package/commands/stats-week/index.ts +3 -3
  21. package/commands/teach/index.js +4 -4
  22. package/commands/teach/index.ts +4 -4
  23. package/commands/teach-list/[[page]]/index.js +3 -3
  24. package/commands/teach-list/[[page]]/index.ts +3 -3
  25. package/commands/teach-regex/index.js +4 -4
  26. package/commands/teach-regex/index.ts +4 -4
  27. package/handlers/welcome/index.js +2 -2
  28. package/handlers/welcome/index.ts +2 -2
  29. package/lib/config.d.ts +15 -1
  30. package/lib/config.d.ts.map +1 -1
  31. package/lib/config.js +11 -1
  32. package/lib/config.js.map +1 -1
  33. package/lib/teach-lib.d.ts +12 -0
  34. package/lib/teach-lib.d.ts.map +1 -1
  35. package/lib/teach-lib.js +104 -29
  36. package/lib/teach-lib.js.map +1 -1
  37. package/middlewares/keyword-reply/index.js +2 -2
  38. package/middlewares/keyword-reply/index.ts +2 -2
  39. package/middlewares/teach-reply/index.js +2 -2
  40. package/middlewares/teach-reply/index.ts +2 -2
  41. package/package.json +16 -21
  42. package/plugin.js +5 -1
  43. package/schema.json +97 -14
  44. package/src/config.ts +22 -2
  45. package/src/teach-lib.ts +86 -23
package/lib/teach-lib.js CHANGED
@@ -2,19 +2,100 @@ import { messages as t } from './i18n.js';
2
2
  import { getTeachModel } from './db-store.js';
3
3
  import { resolveContextKey, resolveSender, ts, } from './shared-runtime.js';
4
4
  export const TEACH_USAGE_HINT = '格式:关键词 回答,或 问题|答案';
5
- function isSafeRegex(pattern) {
5
+ /** Regex rules are only tried against messages up to this length. */
6
+ export const TEACH_REGEX_MAX_CONTENT = 200;
7
+ /** `*`, `+` and `{n,m}` quantifiers allowed in one pattern (bounds polynomial backtracking). */
8
+ const TEACH_REGEX_MAX_QUANTIFIERS = 3;
9
+ /**
10
+ * Conservative structural check for user-taught patterns, which run against every inbound
11
+ * message. It refuses the shapes that backtrack super-linearly:
12
+ * - a repeated group whose body contains a quantifier or an alternation
13
+ * (`(\w+\s?)+`, `(a|aa)+`, `(.*a){10}`);
14
+ * - backreferences and lookarounds;
15
+ * - more than a few repeat operators in one pattern (`.*.*.*.*x`).
16
+ * A character class (`[ab]+`) is the accepted way to repeat a set of alternatives.
17
+ */
18
+ export function isSafeRegex(pattern) {
6
19
  if (pattern.length > 200)
7
20
  return false;
8
- if (/(\+|\*|\{)\)?(\+|\*|\{)/.test(pattern))
9
- return false;
10
- if (/\([^)]*(\+|\*)[^)]*(\+|\*)[^)]*\)[+*]/.test(pattern))
11
- return false;
12
- const altGroups = pattern.match(/\([^)]*\|[^)]*\)/g) || [];
13
- for (const g of altGroups) {
14
- if ((g.match(/\|/g) || []).length > 10)
15
- return false;
21
+ /** One entry per open group: true once its body holds a quantifier or an alternation. */
22
+ const open = [];
23
+ /** Set right after `)`: whether the group that just closed is "complex". */
24
+ let closed;
25
+ let repeats = 0;
26
+ for (let i = 0; i < pattern.length; i += 1) {
27
+ const ch = pattern[i];
28
+ const group = closed;
29
+ closed = undefined;
30
+ if (ch === '\\') {
31
+ const next = pattern[i + 1] ?? '';
32
+ if (/[1-9k]/.test(next))
33
+ return false;
34
+ i += 1;
35
+ }
36
+ else if (ch === '[') {
37
+ // Skip the class body; quantifier characters inside it are literals.
38
+ for (i += 1; i < pattern.length && pattern[i] !== ']'; i += 1)
39
+ if (pattern[i] === '\\')
40
+ i += 1;
41
+ }
42
+ else if (ch === '(') {
43
+ if (/^\(\?<?[=!]/.test(pattern.slice(i, i + 4)))
44
+ return false;
45
+ open.push(false);
46
+ }
47
+ else if (ch === ')') {
48
+ const complex = open.pop();
49
+ if (complex === undefined)
50
+ return false;
51
+ // A complex group makes its parent complex too: `((a+))+`.
52
+ if (complex && open.length > 0)
53
+ open[open.length - 1] = true;
54
+ closed = complex;
55
+ }
56
+ else if (ch === '|') {
57
+ if (open.length > 0)
58
+ open[open.length - 1] = true;
59
+ }
60
+ else if (ch === '*' || ch === '+' || ch === '?' || (ch === '{' && /^\{\d+(?:,\d*)?\}/.test(pattern.slice(i)))) {
61
+ if (ch !== '?') {
62
+ if (group)
63
+ return false;
64
+ repeats += 1;
65
+ if (repeats > TEACH_REGEX_MAX_QUANTIFIERS)
66
+ return false;
67
+ }
68
+ if (open.length > 0)
69
+ open[open.length - 1] = true;
70
+ if (ch === '{')
71
+ i = pattern.indexOf('}', i);
72
+ // A following `?` only makes the quantifier lazy.
73
+ if (pattern[i + 1] === '?')
74
+ i += 1;
75
+ }
76
+ }
77
+ return open.length === 0;
78
+ }
79
+ /** Compiled teach patterns, keyed by source. `null` marks a pattern that must not run. */
80
+ const compiledTeachRegex = new Map();
81
+ function teachRegex(source) {
82
+ const cached = compiledTeachRegex.get(source);
83
+ if (cached !== undefined)
84
+ return cached;
85
+ let compiled = null;
86
+ // Rules stored before the stricter check are re-validated here, not only when they are taught.
87
+ if (isSafeRegex(source)) {
88
+ try {
89
+ compiled = new RegExp(source, 'i');
90
+ }
91
+ catch {
92
+ compiled = null;
93
+ }
16
94
  }
17
- return true;
95
+ if (compiledTeachRegex.size >= 1000)
96
+ compiledTeachRegex.clear();
97
+ compiledTeachRegex.set(source, compiled);
98
+ return compiled;
18
99
  }
19
100
  export function parseTeachPair(raw) {
20
101
  if (!raw)
@@ -61,24 +142,23 @@ async function findMatch(content, ctxType, ctxId, cfg, runtime) {
61
142
  const QA = getTeachModel(runtime.db);
62
143
  if (!QA)
63
144
  return null;
64
- const candidates = (await QA.select().where({
65
- context_type: ctxType, context_id: ctxId,
145
+ // Exact rules are a point lookup; the full rule list is only loaded when regex rules can apply.
146
+ const exact = (await QA.select().where({
147
+ question: content, context_type: ctxType, context_id: ctxId,
66
148
  }));
67
- for (const item of candidates) {
68
- if (!item.is_regex && item.question === content)
149
+ for (const item of exact) {
150
+ if (!item.is_regex)
69
151
  return item;
70
152
  }
71
- if (cfg.teachAllowRegex) {
153
+ if (cfg.teachAllowRegex && content.length <= TEACH_REGEX_MAX_CONTENT) {
154
+ const candidates = (await QA.select().where({
155
+ context_type: ctxType, context_id: ctxId,
156
+ }));
72
157
  for (const item of candidates) {
73
158
  if (!item.is_regex)
74
159
  continue;
75
- try {
76
- if (new RegExp(String(item.question), 'i').test(content))
77
- return item;
78
- }
79
- catch {
80
- continue;
81
- }
160
+ if (teachRegex(String(item.question))?.test(content))
161
+ return item;
82
162
  }
83
163
  }
84
164
  return null;
@@ -211,13 +291,8 @@ export async function tryTeachReply(input, cfg, runtime) {
211
291
  const sender = resolveSender(input);
212
292
  let answer = String(matched.answer ?? '');
213
293
  if (matched.is_regex) {
214
- try {
215
- const m = content.match(new RegExp(String(matched.question), 'i'));
216
- answer = processAnswer(answer, sender, m || undefined, input.locale);
217
- }
218
- catch {
219
- /* ignore */
220
- }
294
+ const m = teachRegex(String(matched.question))?.exec(content);
295
+ answer = processAnswer(answer, sender, m || undefined, input.locale);
221
296
  }
222
297
  else {
223
298
  answer = processAnswer(answer, sender, undefined, input.locale);
@@ -1 +1 @@
1
- {"version":3,"file":"teach-lib.js","sourceRoot":"","sources":["../src/teach-lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"teach-lib.js","sourceRoot":"","sources":["../src/teach-lib.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { defineMiddleware } from 'zhin.js/middleware';
3
- import { resolveGroupSuiteConfig } from "../../lib/config.js";
3
+ import { groupSuiteConfigFor } from "../../lib/config.js";
4
4
  import { matchKeyword } from "../../lib/keyword-store.js";
5
5
  import { keywords } from "../../lib/keywords.js";
6
6
  /**
@@ -10,7 +10,7 @@ import { keywords } from "../../lib/keywords.js";
10
10
  export default defineMiddleware({
11
11
  target: 'inbound',
12
12
  async handle(context, next) {
13
- const config = resolveGroupSuiteConfig(context.config);
13
+ const config = groupSuiteConfigFor(context, context.input);
14
14
  if (!config.keywordReply) {
15
15
  await next();
16
16
  return;
@@ -1,6 +1,6 @@
1
1
  import { defineMiddleware } from 'zhin.js/middleware';
2
2
  import type { Message } from '@zhin.js/core/runtime';
3
- import { resolveGroupSuiteConfig, type GroupSuiteConfig } from '../../src/config.js';
3
+ import { groupSuiteConfigFor, type GroupSuiteConfig } from '../../src/config.js';
4
4
  import { matchKeyword } from '../../src/keyword-store.js';
5
5
  import { keywords } from '../../src/keywords.js';
6
6
 
@@ -11,7 +11,7 @@ import { keywords } from '../../src/keywords.js';
11
11
  export default defineMiddleware<Message, GroupSuiteConfig>({
12
12
  target: 'inbound',
13
13
  async handle(context, next) {
14
- const config = resolveGroupSuiteConfig(context.config);
14
+ const config = groupSuiteConfigFor(context, context.input);
15
15
  if (!config.keywordReply) {
16
16
  await next();
17
17
  return;
@@ -1,6 +1,6 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { defineMiddleware } from 'zhin.js/middleware';
3
- import { resolveGroupSuiteConfig } from "../../lib/config.js";
3
+ import { groupSuiteConfigFor } from "../../lib/config.js";
4
4
  import { tryTeachReply } from "../../lib/teach-lib.js";
5
5
  import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
6
6
  /**
@@ -10,7 +10,7 @@ import { resolveGroupSuiteRuntime } from "../../lib/runtime-state.js";
10
10
  export default defineMiddleware({
11
11
  target: 'inbound',
12
12
  async handle(context, next) {
13
- const config = resolveGroupSuiteConfig(context.config);
13
+ const config = groupSuiteConfigFor(context, context.input);
14
14
  const reply = await tryTeachReply(context.input, config, resolveGroupSuiteRuntime(context));
15
15
  if (reply) {
16
16
  await context.input.$reply(reply);
@@ -1,6 +1,6 @@
1
1
  import { defineMiddleware } from 'zhin.js/middleware';
2
2
  import type { Message } from '@zhin.js/core/runtime';
3
- import { resolveGroupSuiteConfig, type GroupSuiteConfig } from '../../src/config.js';
3
+ import { groupSuiteConfigFor, type GroupSuiteConfig } from '../../src/config.js';
4
4
  import { tryTeachReply } from '../../src/teach-lib.js';
5
5
  import { resolveGroupSuiteRuntime } from '../../src/runtime-state.js';
6
6
 
@@ -11,7 +11,7 @@ import { resolveGroupSuiteRuntime } from '../../src/runtime-state.js';
11
11
  export default defineMiddleware<Message, GroupSuiteConfig>({
12
12
  target: 'inbound',
13
13
  async handle(context, next) {
14
- const config = resolveGroupSuiteConfig(context.config);
14
+ const config = groupSuiteConfigFor(context, context.input);
15
15
  const reply = await tryTeachReply(context.input, config, resolveGroupSuiteRuntime(context));
16
16
  if (reply) {
17
17
  await context.input.$reply(reply);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-group-suite",
3
- "version": "1.1.25",
3
+ "version": "1.1.26",
4
4
  "description": "Zhin.js 群运营套件:签到、教学、统计、持久词库与群欢迎",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -42,28 +42,26 @@
42
42
  },
43
43
  "license": "MIT",
44
44
  "dependencies": {
45
- "@zhin.js/components": "1.1.13",
46
- "@zhin.js/console-contract": "1.1.5",
47
- "@zhin.js/core": "1.1.60",
48
- "@zhin.js/jsx": "1.1.12",
49
- "@zhin.js/page": "1.1.17",
50
- "@zhin.js/skill": "1.1.16",
51
- "@zhin.js/tool": "1.1.18"
45
+ "@zhin.js/components": "1.1.14",
46
+ "@zhin.js/console-contract": "1.1.6",
47
+ "@zhin.js/core": "1.2.0",
48
+ "@zhin.js/jsx": "1.1.13",
49
+ "@zhin.js/page": "1.1.18",
50
+ "@zhin.js/skill": "1.1.17",
51
+ "@zhin.js/tool": "1.1.19"
52
52
  },
53
53
  "devDependencies": {
54
54
  "typescript": "^6.0.3",
55
55
  "vitest": "^4.1.10",
56
- "zod": "^4.4.3",
57
- "zhin.js": "1.1.25"
56
+ "zhin.js": "1.1.26"
58
57
  },
59
58
  "peerDependencies": {
60
- "zod": "^4.0.0",
61
- "@zhin.js/command": "^1.1.17",
62
- "@zhin.js/middleware": "^1.1.16",
63
- "@zhin.js/page": "^1.1.17",
64
- "zhin.js": "^1.1.25",
65
- "@zhin.js/handler": "^1.1.15",
66
- "@zhin.js/schedule-feature": "^1.1.15"
59
+ "@zhin.js/command": "^1.2.0",
60
+ "@zhin.js/middleware": "^1.1.17",
61
+ "@zhin.js/page": "^1.1.18",
62
+ "zhin.js": "^1.1.26",
63
+ "@zhin.js/handler": "^1.1.16",
64
+ "@zhin.js/schedule-feature": "^1.1.16"
67
65
  },
68
66
  "peerDependenciesMeta": {
69
67
  "@zhin.js/command": {
@@ -75,9 +73,6 @@
75
73
  "@zhin.js/page": {
76
74
  "optional": true
77
75
  },
78
- "zod": {
79
- "optional": true
80
- },
81
76
  "@zhin.js/handler": {
82
77
  "optional": true
83
78
  },
@@ -138,6 +133,6 @@
138
133
  "scripts": {
139
134
  "build": "tsc",
140
135
  "clean": "rimraf lib",
141
- "test": "NODE_OPTIONS=--experimental-strip-types vitest run --root ../../.. plugins/utils/group-suite/tests"
136
+ "test": "vitest run --root ../../.. plugins/utils/group-suite/tests"
142
137
  }
143
138
  }
package/plugin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
2
  import { definePlugin, definePluginCapabilityGraph, databaseHostToken, pluginConsoleRpcToken, } from 'zhin.js';
3
3
  import { memberWelcomeOwnerToken, outboundMessageToken } from '@zhin.js/core/runtime';
4
- import { resolveGroupSuiteConfig } from "./lib/config.js";
4
+ import { groupSuiteConfigStore, resolveGroupSuiteConfig } from "./lib/config.js";
5
5
  import { createGroupSuiteConsoleRpc } from "./lib/console.js";
6
6
  import { createInMemoryGroupSuiteDb } from "./lib/memory-store.js";
7
7
  import { createGroupSuiteRuntime, groupSuiteRuntimeStore } from "./lib/runtime-state.js";
@@ -70,6 +70,10 @@ export default definePlugin({
70
70
  void context.resources.use(databaseHostToken).state;
71
71
  }
72
72
  const runtime = groupSuiteRuntimeStore.provide(context, createGroupSuiteRuntime(db));
73
+ // ADR 0050 / 0055: points, teach limits and the welcome text may differ per adapter / account / group.
74
+ groupSuiteConfigStore.provide(context, {
75
+ configFor: target => context.configFor(target),
76
+ });
73
77
  return {
74
78
  consoleRpc: createGroupSuiteConsoleRpc(runtime),
75
79
  };
package/schema.json CHANGED
@@ -2,10 +2,40 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "type": "object",
4
4
  "additionalProperties": false,
5
+ "x-zhin-config": {
6
+ "levels": [
7
+ "global",
8
+ "adapter",
9
+ "endpoint",
10
+ "conversation"
11
+ ],
12
+ "conversationFields": [
13
+ "welcomeMessage",
14
+ "basePointsMin",
15
+ "basePointsMax",
16
+ "streakBonus",
17
+ "streakCap",
18
+ "rankSize",
19
+ "teachMaxPerGroup",
20
+ "teachCooldownMs",
21
+ "teachPageSize"
22
+ ],
23
+ "selfServiceFields": [
24
+ "welcomeMessage",
25
+ "rankSize",
26
+ "teachCooldownMs",
27
+ "teachPageSize"
28
+ ]
29
+ },
5
30
  "properties": {
6
31
  "keywordReply": {
7
32
  "type": "boolean",
8
- "default": false
33
+ "default": false,
34
+ "x-zhin-config": {
35
+ "levels": [
36
+ "global"
37
+ ]
38
+ }
9
39
  },
10
40
  "basePointsMin": {
11
41
  "type": "number",
@@ -37,7 +67,13 @@
37
67
  },
38
68
  "teachAllowRegex": {
39
69
  "type": "boolean",
40
- "default": true
70
+ "default": false,
71
+ "description": "Allow members to teach regular-expression rules. Off by default: patterns run against every inbound message. Only structurally safe patterns are accepted and they are tried on messages of at most 200 characters.",
72
+ "x-zhin-config": {
73
+ "levels": [
74
+ "global"
75
+ ]
76
+ }
41
77
  },
42
78
  "teachPageSize": {
43
79
  "type": "number",
@@ -53,40 +89,87 @@
53
89
  "type": "array",
54
90
  "maxItems": 100,
55
91
  "description": "Exact welcome conversations. Omitted welcomes all groups; [] welcomes none. Missing parent/thread requires their absence; no wildcards.",
56
- "x-zhin-config": { "component": "conversation-scope" },
92
+ "x-zhin-config": {
93
+ "component": "conversation-scope",
94
+ "levels": [
95
+ "global"
96
+ ]
97
+ },
57
98
  "items": {
58
99
  "type": "object",
59
100
  "additionalProperties": false,
60
- "required": ["endpoint", "kind", "id"],
101
+ "required": [
102
+ "endpoint",
103
+ "kind",
104
+ "id"
105
+ ],
61
106
  "properties": {
62
107
  "endpoint": {
63
108
  "type": "object",
64
109
  "additionalProperties": false,
65
- "required": ["adapter", "id"],
110
+ "required": [
111
+ "adapter",
112
+ "id"
113
+ ],
66
114
  "properties": {
67
- "adapter": { "type": "string", "minLength": 1 },
68
- "id": { "type": "string", "minLength": 1 }
115
+ "adapter": {
116
+ "type": "string",
117
+ "minLength": 1
118
+ },
119
+ "id": {
120
+ "type": "string",
121
+ "minLength": 1
122
+ }
69
123
  }
70
124
  },
71
- "kind": { "type": "string", "enum": ["group"] },
72
- "id": { "type": "string", "minLength": 1 },
125
+ "kind": {
126
+ "type": "string",
127
+ "enum": [
128
+ "group"
129
+ ]
130
+ },
131
+ "id": {
132
+ "type": "string",
133
+ "minLength": 1
134
+ },
73
135
  "parent": {
74
136
  "type": "object",
75
137
  "additionalProperties": false,
76
- "required": ["kind", "id"],
138
+ "required": [
139
+ "kind",
140
+ "id"
141
+ ],
77
142
  "properties": {
78
- "kind": { "type": "string", "enum": ["private", "group", "channel"] },
79
- "id": { "type": "string", "minLength": 1 }
143
+ "kind": {
144
+ "type": "string",
145
+ "enum": [
146
+ "private",
147
+ "group",
148
+ "channel"
149
+ ]
150
+ },
151
+ "id": {
152
+ "type": "string",
153
+ "minLength": 1
154
+ }
80
155
  }
81
156
  },
82
- "threadId": { "type": "string", "minLength": 1 }
157
+ "threadId": {
158
+ "type": "string",
159
+ "minLength": 1
160
+ }
83
161
  }
84
162
  }
85
163
  },
86
164
  "ephemeralKeywords": {
87
165
  "type": "boolean",
88
166
  "default": false,
89
- "description": "Explicit volatile keywords. With false, automatic replies require Database Host at startup and keyword management requires its persistent state service when invoked."
167
+ "description": "Explicit volatile keywords. With false, automatic replies require Database Host at startup and keyword management requires its persistent state service when invoked.",
168
+ "x-zhin-config": {
169
+ "levels": [
170
+ "global"
171
+ ]
172
+ }
90
173
  }
91
174
  }
92
175
  }
package/src/config.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { DeliveryTarget } from 'zhin.js';
1
+ import { definePluginStore, type DeliveryTarget } from 'zhin.js';
2
2
  import { normalizeWelcomeConversations } from './welcome-scope.js';
3
3
 
4
4
  export interface GroupSuiteConfig {
@@ -31,7 +31,7 @@ export const DEFAULT_GROUP_SUITE_CONFIG: GroupSuiteConfig = {
31
31
  rankSize: 10,
32
32
  teachMaxPerGroup: 200,
33
33
  teachCooldownMs: 3000,
34
- teachAllowRegex: true,
34
+ teachAllowRegex: false,
35
35
  teachPageSize: 10,
36
36
  };
37
37
 
@@ -46,3 +46,23 @@ export function resolveGroupSuiteConfig(
46
46
  }),
47
47
  };
48
48
  }
49
+
50
+ /** Effective configuration per message / notice (ADR 0050 / 0055): global < adapter < endpoint < conversation. */
51
+ export interface GroupSuiteConfigResolver {
52
+ configFor(target: unknown): Readonly<Partial<GroupSuiteConfig>>;
53
+ }
54
+ export const groupSuiteConfigStore = definePluginStore<GroupSuiteConfigResolver>(
55
+ 'zhin.group-suite.config', 'Layered group-suite configuration for one conversation');
56
+
57
+ /**
58
+ * Settings for one capability call: the conversation's effective config when the resolver is
59
+ * provided (Plugin setup), else the global view. `target` is the message or notice being handled.
60
+ */
61
+ export function groupSuiteConfigFor(context: {
62
+ readonly config?: Partial<GroupSuiteConfig>;
63
+ readonly has?: (token: typeof groupSuiteConfigStore) => boolean;
64
+ readonly use: (token: typeof groupSuiteConfigStore) => GroupSuiteConfigResolver;
65
+ }, target: unknown): GroupSuiteConfig {
66
+ const resolver = target !== undefined && context.has?.(groupSuiteConfigStore) ? context.use(groupSuiteConfigStore) : undefined;
67
+ return resolveGroupSuiteConfig({ ...(context.config ?? {}), ...(resolver?.configFor(target) ?? {}) });
68
+ }