luckytri 1.0.0 → 1.0.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.
Files changed (139) hide show
  1. package/.github/SECURITY.md +4 -4
  2. package/README.en.md +252 -250
  3. package/README.md +252 -250
  4. package/bin/luckytri.js +5 -1
  5. package/docs/en/CHANGELOG.md +8 -0
  6. package/docs/en/connect.md +18 -18
  7. package/docs/en/guide.md +202 -216
  8. package/docs/en/npm-release.md +25 -25
  9. package/docs/zh/CHANGELOG.md +8 -0
  10. package/docs/zh/connect.md +17 -17
  11. package/docs/zh/guide.md +202 -216
  12. package/docs/zh/npm-release.md +33 -33
  13. package/package.json +110 -108
  14. package/plugins/sdk/index.d.ts +155 -155
  15. package/plugins/sdk/testing.js +58 -58
  16. package/plugins/weather/index.js +82 -82
  17. package/plugins/weather/luckytri-plugin.json +29 -29
  18. package/public/app/assets/ChatsPage-BhlJHseG.js +3 -0
  19. package/public/app/assets/Empty-DP6WMGHi.js +2 -0
  20. package/public/app/assets/Field-CtbdqaiB.js +1 -0
  21. package/public/app/assets/HeartPage-32BeTPn2.js +1 -0
  22. package/public/app/assets/LifePage-CxSm0XKI.js +1 -0
  23. package/public/app/assets/MemoryPage-BeKBcPCY.js +1 -0
  24. package/public/app/assets/NaturePage-NEPYl2HS.js +3 -0
  25. package/public/app/assets/PeoplePage-DxtpekwM.js +1 -0
  26. package/public/app/assets/PluginsPage-CVVQwEBI.css +1 -0
  27. package/public/app/assets/PluginsPage-DksEZbUU.js +2 -0
  28. package/public/app/assets/{SystemPage-CAMPoYqM.css → SystemPage-BkRu0Rvx.css} +1 -1
  29. package/public/app/assets/SystemPage-BvzJlHuY.js +1 -0
  30. package/public/app/assets/TimePage-7-awH5XL.js +3 -0
  31. package/public/app/assets/index-4rItIkD-.js +4 -0
  32. package/public/app/assets/{index-YDz1ree1.css → index-DY4e15Kh.css} +1 -1
  33. package/public/app/assets/{knowledge-DG0e0uKw.js → knowledge-C6_HvoyB.js} +1 -1
  34. package/public/app/assets/media-SMfTT-yc.js +1 -0
  35. package/public/app/index.html +3 -3
  36. package/public/guide.en.html +72 -99
  37. package/public/guide.html +44 -86
  38. package/public/tutorial.en.md +25 -39
  39. package/public/tutorial.md +25 -39
  40. package/scripts/backup.js +311 -311
  41. package/scripts/browser.js +41 -41
  42. package/scripts/import-data.js +128 -0
  43. package/scripts/launch.js +101 -94
  44. package/scripts/plugin.js +150 -150
  45. package/scripts/reset-password.js +22 -0
  46. package/scripts/runtime.js +25 -25
  47. package/scripts/service.js +56 -47
  48. package/scripts/setup.js +50 -50
  49. package/scripts/start-server.js +41 -41
  50. package/scripts/stop.js +36 -36
  51. package/server/app.js +112 -96
  52. package/server/auth.js +217 -0
  53. package/server/channels/contract.js +57 -57
  54. package/server/channels/hub.js +165 -165
  55. package/server/channels/index.js +28 -25
  56. package/server/channels/onebot/index.js +335 -336
  57. package/server/channels/onebot/token.js +22 -3
  58. package/server/core/capabilities.js +208 -208
  59. package/server/core/events.js +64 -60
  60. package/server/core/image-preprocessor.js +208 -208
  61. package/server/core/model-manager.js +1213 -1213
  62. package/server/core/net-guard.js +49 -49
  63. package/server/core/orchestrator.js +569 -569
  64. package/server/core/perceivers.js +91 -91
  65. package/server/core/persona-manager.js +243 -243
  66. package/server/core/repository.js +293 -293
  67. package/server/core/response-validator.js +508 -508
  68. package/server/core/turn-processor.js +630 -630
  69. package/server/core/turn.js +236 -236
  70. package/server/core/vision-manager.js +633 -633
  71. package/server/i18n/errors.js +548 -497
  72. package/server/i18n/labels.js +649 -653
  73. package/server/index.js +151 -102
  74. package/server/knowledge/manager.js +386 -386
  75. package/server/knowledge/schema.js +12 -8
  76. package/server/local-access.js +32 -0
  77. package/server/mind/anticipations.js +507 -507
  78. package/server/mind/api.js +703 -703
  79. package/server/mind/budget.js +152 -152
  80. package/server/mind/context-selection.js +61 -61
  81. package/server/mind/day-planner.js +324 -324
  82. package/server/mind/evidence.js +148 -148
  83. package/server/mind/index.js +445 -445
  84. package/server/mind/life/diary.js +786 -786
  85. package/server/mind/life/index.js +1049 -1049
  86. package/server/mind/observations.js +84 -84
  87. package/server/mind/own-day.js +324 -324
  88. package/server/mind/own-voice.js +318 -318
  89. package/server/mind/senses.js +53 -53
  90. package/server/mind/time/activity-clock.js +196 -196
  91. package/server/mind/time/availability.js +69 -69
  92. package/server/mind/time/commitment-review.js +198 -198
  93. package/server/mind/time/executor.js +512 -512
  94. package/server/mind/time/experiences.js +128 -128
  95. package/server/mind/time/games.js +562 -562
  96. package/server/mind/time/index.js +739 -739
  97. package/server/mind/time/intent.js +166 -166
  98. package/server/mind/time/kinds.js +171 -171
  99. package/server/mind/time/plugin-activity.js +207 -207
  100. package/server/mind/time/tasks.js +587 -587
  101. package/server/mind/util.js +110 -110
  102. package/server/mind/view.js +273 -273
  103. package/server/paths.js +102 -102
  104. package/server/plugins/api.js +204 -204
  105. package/server/plugins/host.js +967 -967
  106. package/server/plugins/install.js +295 -295
  107. package/server/plugins/manifest.js +201 -201
  108. package/server/plugins/permissions.js +42 -42
  109. package/server/plugins/runner/guard.mjs +36 -36
  110. package/server/plugins/runner/worker.mjs +250 -250
  111. package/server/plugins/schema.js +91 -91
  112. package/server/plugins/zip.js +112 -112
  113. package/server/startup-lock.js +118 -118
  114. package/server/storage/archive.js +242 -241
  115. package/server/storage/backup-cleanup-worker.js +8 -8
  116. package/server/storage/backup-cleanup.js +415 -414
  117. package/server/storage/backup-lock.js +76 -76
  118. package/server/storage/backup-scheduler.js +131 -131
  119. package/server/storage/data-package.js +298 -0
  120. package/server/storage/data-transfer-api.js +50 -0
  121. package/server/storage/data-transfer-worker.js +18 -0
  122. package/server/storage/data-transfer.js +415 -0
  123. package/server/storage/store.js +202 -199
  124. package/server/studio/readiness.js +181 -190
  125. package/server/studio/settings.js +236 -236
  126. package/public/app/assets/ChatsPage-C-FcRapR.js +0 -3
  127. package/public/app/assets/Empty-CpP5kQHH.js +0 -2
  128. package/public/app/assets/Field-D4gY-INU.js +0 -1
  129. package/public/app/assets/HeartPage-CPy_thQd.js +0 -1
  130. package/public/app/assets/LifePage-CxWvwmSf.js +0 -1
  131. package/public/app/assets/MemoryPage-DC4rhQ68.js +0 -1
  132. package/public/app/assets/NaturePage-IvYw04Zq.js +0 -3
  133. package/public/app/assets/PeoplePage-Cqefm9-q.js +0 -1
  134. package/public/app/assets/PluginsPage-DKSaKvXb.js +0 -2
  135. package/public/app/assets/PluginsPage-HyBe5D8w.css +0 -1
  136. package/public/app/assets/SystemPage-CJmtJkrK.js +0 -1
  137. package/public/app/assets/TimePage-Cw44inM4.js +0 -3
  138. package/public/app/assets/index-BheRW-1t.js +0 -4
  139. package/public/app/assets/media-BzPDBm7e.js +0 -1
@@ -1,57 +1,57 @@
1
- // A channel is the only part of LuckyTri that knows how a platform connects.
2
- // Everything above it (sessions, attention, memory, time, her inner life) sees
3
- // the same neutral message and talks back through the same few calls, so a
4
- // new platform is one folder that fulfils this contract and one line in the
5
- // registry (see channels/index.js).
6
- //
7
- // type stable id, also the first part of every session key
8
- // capabilities what the platform can express: mention, quote,
9
- // image, thread, sticker
10
- // attach(server, chat) one-time wiring to the HTTP server and the ChatSystem
11
- // start() begin accepting or opening the connection for the
12
- // current settings; safe to call again after a change
13
- // stop() drop the connection and stop timers; safe to repeat
14
- // send(message, text) deliver one bubble; resolves { message_id }
15
- // fetchQuoted(message) the message that `message.replyId` points to, or null
16
- // fetchImage(file) a fresh URL or bytes for an expired image, or null
17
- // fetchMedia(file, type) optional: a voice or file the same way, or null
18
- // refreshDirectory() learn real group and friend names; resolves a count
19
- // canReach(sessionId) whether she may start a conversation there now
20
- // status() { online, ... } for the connection panel
21
- // close() final shutdown
22
- //
23
- // The message every channel hands to `ChatSystem.receive` is neutral. Besides
24
- // the fields the core already uses, an adapter fills platformId, accountId,
25
- // time, mentions, replyId and attachments itself, so nothing above the
26
- // channel ever has to parse a platform's wire format.
27
-
28
- const REQUIRED = [
29
- "start",
30
- "stop",
31
- "attach",
32
- "send",
33
- "fetchQuoted",
34
- "fetchImage",
35
- "refreshDirectory",
36
- "canReach",
37
- "status",
38
- "close",
39
- ];
40
-
41
- export function defineChannel(channel) {
42
- if (!channel || typeof channel.type !== "string" || !channel.type)
43
- throw new TypeError("channel needs a type");
44
- for (const name of REQUIRED)
45
- if (typeof channel[name] !== "function")
46
- throw new TypeError(`channel ${channel.type} is missing ${name}()`);
47
- return Object.freeze({
48
- capabilities: {
49
- mention: false,
50
- quote: false,
51
- image: false,
52
- thread: false,
53
- sticker: false,
54
- },
55
- ...channel,
56
- });
57
- }
1
+ // A channel is the only part of LuckyTri that knows how a platform connects.
2
+ // Everything above it (sessions, attention, memory, time, her inner life) sees
3
+ // the same neutral message and talks back through the same few calls, so a
4
+ // new platform is one folder that fulfils this contract and one line in the
5
+ // registry (see channels/index.js).
6
+ //
7
+ // type stable id, also the first part of every session key
8
+ // capabilities what the platform can express: mention, quote,
9
+ // image, thread, sticker
10
+ // attach(server, chat) one-time wiring to the HTTP server and the ChatSystem
11
+ // start() begin accepting or opening the connection for the
12
+ // current settings; safe to call again after a change
13
+ // stop() drop the connection and stop timers; safe to repeat
14
+ // send(message, text) deliver one bubble; resolves { message_id }
15
+ // fetchQuoted(message) the message that `message.replyId` points to, or null
16
+ // fetchImage(file) a fresh URL or bytes for an expired image, or null
17
+ // fetchMedia(file, type) optional: a voice or file the same way, or null
18
+ // refreshDirectory() learn real group and friend names; resolves a count
19
+ // canReach(sessionId) whether she may start a conversation there now
20
+ // status() { online, ... } for the connection panel
21
+ // close() final shutdown
22
+ //
23
+ // The message every channel hands to `ChatSystem.receive` is neutral. Besides
24
+ // the fields the core already uses, an adapter fills platformId, accountId,
25
+ // time, mentions, replyId and attachments itself, so nothing above the
26
+ // channel ever has to parse a platform's wire format.
27
+
28
+ const REQUIRED = [
29
+ "start",
30
+ "stop",
31
+ "attach",
32
+ "send",
33
+ "fetchQuoted",
34
+ "fetchImage",
35
+ "refreshDirectory",
36
+ "canReach",
37
+ "status",
38
+ "close",
39
+ ];
40
+
41
+ export function defineChannel(channel) {
42
+ if (!channel || typeof channel.type !== "string" || !channel.type)
43
+ throw new TypeError("channel needs a type");
44
+ for (const name of REQUIRED)
45
+ if (typeof channel[name] !== "function")
46
+ throw new TypeError(`channel ${channel.type} is missing ${name}()`);
47
+ return Object.freeze({
48
+ capabilities: {
49
+ mention: false,
50
+ quote: false,
51
+ image: false,
52
+ thread: false,
53
+ sticker: false,
54
+ },
55
+ ...channel,
56
+ });
57
+ }
@@ -1,165 +1,165 @@
1
- import { parseSessionKey } from "./session-key.js";
2
-
3
- export const CHANNEL_TYPES = ["onebot", "qqbot"];
4
-
5
- // Which channel is wanted: the environment wins over the saved setting, the
6
- // same way LLM_API_KEY wins over a key saved in the studio.
7
- export function selectedChannel(store, env = process.env) {
8
- const forced = String(env.LUCKYTRI_CHANNEL || "")
9
- .trim()
10
- .toLowerCase();
11
- if (CHANNEL_TYPES.includes(forced)) return { type: forced, locked: true };
12
- const saved = String(store.settings().channel || "");
13
- return {
14
- type: CHANNEL_TYPES.includes(saved) ? saved : "onebot",
15
- locked: false,
16
- };
17
- }
18
-
19
- // Exactly one channel is connected at a time. Everything above the hub talks
20
- // to it as if it were the channel itself, so the core, her mind and her life
21
- // are the same whichever platform she is on; switching is a setting, not a
22
- // restart.
23
- const QQ = new Set(CHANNEL_TYPES);
24
-
25
- export function createChannelHub(store, channels, { env = process.env } = {}) {
26
- const registry = new Map(channels.map((channel) => [channel.type, channel]));
27
- if (!registry.size) throw new Error("channel hub needs at least one channel");
28
- let active = null;
29
- let locked = false;
30
- let attached = null;
31
- // Plugin channels stay connected beside the one QQ channel in use.
32
- const started = new Set();
33
-
34
- const current = () => registry.get(active) || registry.values().next().value;
35
-
36
- function resolve(sessionId) {
37
- let type = active;
38
- if (sessionId) {
39
- try {
40
- type = parseSessionKey(sessionId).channel;
41
- } catch {
42
- /* A session without a channel key is spoken to over the active one. */
43
- }
44
- }
45
- if (QQ.has(type) && type !== active)
46
- throw new Error("这个会话属于另一种 QQ 接入方式,当前不能向它发送");
47
- const channel = registry.get(type);
48
- if (!channel || (!QQ.has(type) && !started.has(type)))
49
- throw new Error("这个会话的通道没有接上");
50
- return channel;
51
- }
52
-
53
- // Bring the connected channel in line with the settings. Cheap when nothing
54
- // changed, so it is also what runs after the credentials are edited.
55
- function sync() {
56
- const wanted = selectedChannel(store, env);
57
- const type = registry.has(wanted.type)
58
- ? wanted.type
59
- : registry.keys().next().value;
60
- locked = wanted.locked;
61
- if (active && active !== type) registry.get(active).stop();
62
- const switched = active !== type;
63
- active = type;
64
- registry.get(type).start();
65
- if (switched)
66
- registry
67
- .get(type)
68
- .refreshDirectory()
69
- .catch(() => {});
70
- return type;
71
- }
72
-
73
- function attach(server, chat) {
74
- attached = { server, chat };
75
- for (const channel of registry.values()) channel.attach(server, chat);
76
- for (const type of started) registry.get(type)?.start();
77
- sync();
78
- }
79
-
80
- function register(channel) {
81
- if (!channel?.type || QQ.has(channel.type) || registry.has(channel.type))
82
- throw new Error("这个通道不能接上");
83
- registry.set(channel.type, channel);
84
- started.add(channel.type);
85
- if (attached) {
86
- channel.attach(attached.server, attached.chat);
87
- channel.start();
88
- }
89
- return channel.type;
90
- }
91
-
92
- function unregister(type) {
93
- if (QQ.has(type) || !registry.has(type)) return false;
94
- started.delete(type);
95
- const channel = registry.get(type);
96
- try {
97
- channel.stop();
98
- channel.close();
99
- } catch {
100
- /* A plugin channel that already died should still leave the hub. */
101
- }
102
- registry.delete(type);
103
- return true;
104
- }
105
-
106
- const send = async (message, text) => {
107
- if (message?.simulated) return { message_id: "sim" };
108
- return resolve(message.sessionId).send(message, text);
109
- };
110
-
111
- function canReach(sessionId) {
112
- try {
113
- return resolve(sessionId).canReach(sessionId);
114
- } catch {
115
- return false;
116
- }
117
- }
118
-
119
- function status() {
120
- const channel = current();
121
- const own = channel.status();
122
- const all = {};
123
- for (const item of registry.values()) all[item.type] = item.status();
124
- return {
125
- channel: channel.type,
126
- locked,
127
- online: !!own.online,
128
- connectedAt: own.connectedAt ?? null,
129
- lastEventAt: own.lastEventAt ?? null,
130
- lastDisconnectAt: own.lastDisconnectAt ?? null,
131
- adminProtected: !!env.ADMIN_TOKEN,
132
- port: Number(env.PORT || 3210),
133
- capabilities: channel.capabilities,
134
- ...all,
135
- };
136
- }
137
-
138
- return {
139
- attach,
140
- sync,
141
- register,
142
- unregister,
143
- send,
144
- canReach,
145
- status,
146
- type: () => current().type,
147
- online: () =>
148
- !!current().status().online ||
149
- [...started].some((type) => registry.get(type)?.status().online),
150
- fetchQuoted: (message) =>
151
- (message?.sessionId ? resolve(message.sessionId) : current()).fetchQuoted(
152
- message,
153
- ),
154
- fetchImage: (file, sessionId) =>
155
- (sessionId ? resolve(sessionId) : current()).fetchImage(file),
156
- fetchMedia: (file, sessionId, type) => {
157
- const channel = sessionId ? resolve(sessionId) : current();
158
- return channel.fetchMedia ? channel.fetchMedia(file, type) : null;
159
- },
160
- refreshDirectory: () => current().refreshDirectory(),
161
- close() {
162
- for (const channel of registry.values()) channel.close();
163
- },
164
- };
165
- }
1
+ import { parseSessionKey } from "./session-key.js";
2
+
3
+ export const CHANNEL_TYPES = ["onebot", "qqbot"];
4
+
5
+ // Which channel is wanted: the environment wins over the saved setting, the
6
+ // same way LLM_API_KEY wins over a key saved in the studio.
7
+ export function selectedChannel(store, env = process.env) {
8
+ const forced = String(env.LUCKYTRI_CHANNEL || "")
9
+ .trim()
10
+ .toLowerCase();
11
+ if (CHANNEL_TYPES.includes(forced)) return { type: forced, locked: true };
12
+ const saved = String(store.settings().channel || "");
13
+ return {
14
+ type: CHANNEL_TYPES.includes(saved) ? saved : "onebot",
15
+ locked: false,
16
+ };
17
+ }
18
+
19
+ // Exactly one channel is connected at a time. Everything above the hub talks
20
+ // to it as if it were the channel itself, so the core, her mind and her life
21
+ // are the same whichever platform she is on; switching is a setting, not a
22
+ // restart.
23
+ const QQ = new Set(CHANNEL_TYPES);
24
+
25
+ export function createChannelHub(store, channels, { env = process.env } = {}) {
26
+ const registry = new Map(channels.map((channel) => [channel.type, channel]));
27
+ if (!registry.size) throw new Error("channel hub needs at least one channel");
28
+ let active = null;
29
+ let locked = false;
30
+ let attached = null;
31
+ // Plugin channels stay connected beside the one QQ channel in use.
32
+ const started = new Set();
33
+
34
+ const current = () => registry.get(active) || registry.values().next().value;
35
+
36
+ function resolve(sessionId) {
37
+ let type = active;
38
+ if (sessionId) {
39
+ try {
40
+ type = parseSessionKey(sessionId).channel;
41
+ } catch {
42
+ /* A session without a channel key is spoken to over the active one. */
43
+ }
44
+ }
45
+ if (QQ.has(type) && type !== active)
46
+ throw new Error("这个会话属于另一种 QQ 接入方式,当前不能向它发送");
47
+ const channel = registry.get(type);
48
+ if (!channel || (!QQ.has(type) && !started.has(type)))
49
+ throw new Error("这个会话的通道没有接上");
50
+ return channel;
51
+ }
52
+
53
+ // Bring the connected channel in line with the settings. Cheap when nothing
54
+ // changed, so it is also what runs after the credentials are edited.
55
+ function sync() {
56
+ const wanted = selectedChannel(store, env);
57
+ const type = registry.has(wanted.type)
58
+ ? wanted.type
59
+ : registry.keys().next().value;
60
+ locked = wanted.locked;
61
+ if (active && active !== type) registry.get(active).stop();
62
+ const switched = active !== type;
63
+ active = type;
64
+ registry.get(type).start();
65
+ if (switched)
66
+ registry
67
+ .get(type)
68
+ .refreshDirectory()
69
+ .catch(() => {});
70
+ return type;
71
+ }
72
+
73
+ function attach(server, chat) {
74
+ attached = { server, chat };
75
+ for (const channel of registry.values()) channel.attach(server, chat);
76
+ for (const type of started) registry.get(type)?.start();
77
+ sync();
78
+ }
79
+
80
+ function register(channel) {
81
+ if (!channel?.type || QQ.has(channel.type) || registry.has(channel.type))
82
+ throw new Error("这个通道不能接上");
83
+ registry.set(channel.type, channel);
84
+ started.add(channel.type);
85
+ if (attached) {
86
+ channel.attach(attached.server, attached.chat);
87
+ channel.start();
88
+ }
89
+ return channel.type;
90
+ }
91
+
92
+ function unregister(type) {
93
+ if (QQ.has(type) || !registry.has(type)) return false;
94
+ started.delete(type);
95
+ const channel = registry.get(type);
96
+ try {
97
+ channel.stop();
98
+ channel.close();
99
+ } catch {
100
+ /* A plugin channel that already died should still leave the hub. */
101
+ }
102
+ registry.delete(type);
103
+ return true;
104
+ }
105
+
106
+ const send = async (message, text) => {
107
+ if (message?.simulated) return { message_id: "sim" };
108
+ return resolve(message.sessionId).send(message, text);
109
+ };
110
+
111
+ function canReach(sessionId) {
112
+ try {
113
+ return resolve(sessionId).canReach(sessionId);
114
+ } catch {
115
+ return false;
116
+ }
117
+ }
118
+
119
+ function status() {
120
+ const channel = current();
121
+ const own = channel.status();
122
+ const all = {};
123
+ for (const item of registry.values()) all[item.type] = item.status();
124
+ return {
125
+ channel: channel.type,
126
+ locked,
127
+ online: !!own.online,
128
+ connectedAt: own.connectedAt ?? null,
129
+ lastEventAt: own.lastEventAt ?? null,
130
+ lastDisconnectAt: own.lastDisconnectAt ?? null,
131
+ adminProtected: !!env.ADMIN_TOKEN,
132
+ port: Number(env.PORT || 3210),
133
+ capabilities: channel.capabilities,
134
+ ...all,
135
+ };
136
+ }
137
+
138
+ return {
139
+ attach,
140
+ sync,
141
+ register,
142
+ unregister,
143
+ send,
144
+ canReach,
145
+ status,
146
+ type: () => current().type,
147
+ online: () =>
148
+ !!current().status().online ||
149
+ [...started].some((type) => registry.get(type)?.status().online),
150
+ fetchQuoted: (message) =>
151
+ (message?.sessionId ? resolve(message.sessionId) : current()).fetchQuoted(
152
+ message,
153
+ ),
154
+ fetchImage: (file, sessionId) =>
155
+ (sessionId ? resolve(sessionId) : current()).fetchImage(file),
156
+ fetchMedia: (file, sessionId, type) => {
157
+ const channel = sessionId ? resolve(sessionId) : current();
158
+ return channel.fetchMedia ? channel.fetchMedia(file, type) : null;
159
+ },
160
+ refreshDirectory: () => current().refreshDirectory(),
161
+ close() {
162
+ for (const channel of registry.values()) channel.close();
163
+ },
164
+ };
165
+ }
@@ -1,25 +1,28 @@
1
- import { createOneBotChannel } from "./onebot/index.js";
2
- import { createQqBotChannel } from "./qqbot/index.js";
3
-
4
- // Adding a platform: write a folder that fulfils channels/contract.js, give its
5
- // adapter an entry in adapters.js (so the core can ask what its media links
6
- // look like) and its factory a line in createChannels. Nothing above the hub
7
- // changes.
8
- export function createChannels(store, options = {}) {
9
- return [createOneBotChannel(store), createQqBotChannel(store, options.qqbot)];
10
- }
11
-
12
- export { createChannelHub, selectedChannel, CHANNEL_TYPES } from "./hub.js";
13
- export { defineChannel } from "./contract.js";
14
- export { adapterFor, registerChannel, onebot, qqbot } from "./adapters.js";
15
- export {
16
- bindSessionId,
17
- formatSessionKey,
18
- isGroupSession,
19
- parseSessionKey,
20
- publicSession,
21
- sessionAliases,
22
- sessionKind,
23
- sessionNativeId,
24
- } from "./session-key.js";
25
- export { normalize } from "./onebot/adapter.js";
1
+ import { createOneBotChannel } from "./onebot/index.js";
2
+ import { createQqBotChannel } from "./qqbot/index.js";
3
+
4
+ // Adding a platform: write a folder that fulfils channels/contract.js, give its
5
+ // adapter an entry in adapters.js (so the core can ask what its media links
6
+ // look like) and its factory a line in createChannels. Nothing above the hub
7
+ // changes.
8
+ export function createChannels(store, options = {}) {
9
+ return [
10
+ createOneBotChannel(store, options.onebot),
11
+ createQqBotChannel(store, options.qqbot),
12
+ ];
13
+ }
14
+
15
+ export { createChannelHub, selectedChannel, CHANNEL_TYPES } from "./hub.js";
16
+ export { defineChannel } from "./contract.js";
17
+ export { adapterFor, registerChannel, onebot, qqbot } from "./adapters.js";
18
+ export {
19
+ bindSessionId,
20
+ formatSessionKey,
21
+ isGroupSession,
22
+ parseSessionKey,
23
+ publicSession,
24
+ sessionAliases,
25
+ sessionKind,
26
+ sessionNativeId,
27
+ } from "./session-key.js";
28
+ export { normalize } from "./onebot/adapter.js";