@jsbot-tellus/core 2.4.0 → 2.5.1

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 (183) hide show
  1. package/README.md +8 -5
  2. package/dist/app/cli.d.ts +10 -0
  3. package/dist/app/cli.d.ts.map +1 -0
  4. package/dist/app/cli.js +37 -0
  5. package/dist/app/cli.js.map +1 -0
  6. package/dist/app/runtime.d.ts +121 -0
  7. package/dist/app/runtime.d.ts.map +1 -0
  8. package/dist/app/runtime.js +296 -0
  9. package/dist/app/runtime.js.map +1 -0
  10. package/dist/app.js +63 -273
  11. package/dist/app.js.map +1 -1
  12. package/dist/core/dispatch/command.d.ts.map +1 -1
  13. package/dist/core/dispatch/command.js +5 -1
  14. package/dist/core/dispatch/command.js.map +1 -1
  15. package/dist/core/dispatch/router.d.ts.map +1 -1
  16. package/dist/core/dispatch/router.js +1 -1
  17. package/dist/core/dispatch/router.js.map +1 -1
  18. package/dist/core/plugin/command-params.d.ts +3 -36
  19. package/dist/core/plugin/command-params.d.ts.map +1 -1
  20. package/dist/core/plugin/command-params.js +2 -461
  21. package/dist/core/plugin/command-params.js.map +1 -1
  22. package/dist/core/plugin/install/paths.d.ts +7 -0
  23. package/dist/core/plugin/install/paths.d.ts.map +1 -0
  24. package/dist/core/plugin/install/paths.js +49 -0
  25. package/dist/core/plugin/install/paths.js.map +1 -0
  26. package/dist/core/plugin/install/state.d.ts +23 -0
  27. package/dist/core/plugin/install/state.d.ts.map +1 -0
  28. package/dist/core/plugin/install/state.js +129 -0
  29. package/dist/core/plugin/install/state.js.map +1 -0
  30. package/dist/core/plugin/install/validate-script.d.ts +3 -0
  31. package/dist/core/plugin/install/validate-script.d.ts.map +1 -0
  32. package/dist/core/plugin/install/validate-script.js +154 -0
  33. package/dist/core/plugin/install/validate-script.js.map +1 -0
  34. package/dist/core/plugin/install-dir.d.ts +3 -28
  35. package/dist/core/plugin/install-dir.d.ts.map +1 -1
  36. package/dist/core/plugin/install-dir.js +3 -326
  37. package/dist/core/plugin/install-dir.js.map +1 -1
  38. package/dist/core/plugin/installer/checks.d.ts +6 -0
  39. package/dist/core/plugin/installer/checks.d.ts.map +1 -0
  40. package/dist/core/plugin/installer/checks.js +99 -0
  41. package/dist/core/plugin/installer/checks.js.map +1 -0
  42. package/dist/core/plugin/installer/support.d.ts +37 -0
  43. package/dist/core/plugin/installer/support.d.ts.map +1 -0
  44. package/dist/core/plugin/installer/support.js +67 -0
  45. package/dist/core/plugin/installer/support.js.map +1 -0
  46. package/dist/core/plugin/installer/warnings.d.ts +5 -0
  47. package/dist/core/plugin/installer/warnings.d.ts.map +1 -0
  48. package/dist/core/plugin/installer/warnings.js +28 -0
  49. package/dist/core/plugin/installer/warnings.js.map +1 -0
  50. package/dist/core/plugin/installer.d.ts +4 -30
  51. package/dist/core/plugin/installer.d.ts.map +1 -1
  52. package/dist/core/plugin/installer.js +21 -202
  53. package/dist/core/plugin/installer.js.map +1 -1
  54. package/dist/core/plugin/params/compile.d.ts +3 -0
  55. package/dist/core/plugin/params/compile.d.ts.map +1 -0
  56. package/dist/core/plugin/params/compile.js +23 -0
  57. package/dist/core/plugin/params/compile.js.map +1 -0
  58. package/dist/core/plugin/params/declaration.d.ts +9 -0
  59. package/dist/core/plugin/params/declaration.d.ts.map +1 -0
  60. package/dist/core/plugin/params/declaration.js +223 -0
  61. package/dist/core/plugin/params/declaration.js.map +1 -0
  62. package/dist/core/plugin/params/input.d.ts +5 -0
  63. package/dist/core/plugin/params/input.d.ts.map +1 -0
  64. package/dist/core/plugin/params/input.js +181 -0
  65. package/dist/core/plugin/params/input.js.map +1 -0
  66. package/dist/core/plugin/params/reply.d.ts +3 -0
  67. package/dist/core/plugin/params/reply.d.ts.map +1 -0
  68. package/dist/core/plugin/params/reply.js +49 -0
  69. package/dist/core/plugin/params/reply.js.map +1 -0
  70. package/dist/core/plugin/params/type-level.d.ts +23 -0
  71. package/dist/core/plugin/params/type-level.d.ts.map +1 -0
  72. package/dist/core/plugin/params/type-level.js +2 -0
  73. package/dist/core/plugin/params/type-level.js.map +1 -0
  74. package/dist/core/plugin/params/types.d.ts +28 -0
  75. package/dist/core/plugin/params/types.d.ts.map +1 -0
  76. package/dist/core/plugin/params/types.js +12 -0
  77. package/dist/core/plugin/params/types.js.map +1 -0
  78. package/dist/core/plugin/params/values.d.ts +6 -0
  79. package/dist/core/plugin/params/values.d.ts.map +1 -0
  80. package/dist/core/plugin/params/values.js +108 -0
  81. package/dist/core/plugin/params/values.js.map +1 -0
  82. package/dist/core/web/api.d.ts +2 -14
  83. package/dist/core/web/api.d.ts.map +1 -1
  84. package/dist/core/web/api.js +8 -500
  85. package/dist/core/web/api.js.map +1 -1
  86. package/dist/core/web/routes/actions.d.ts +4 -0
  87. package/dist/core/web/routes/actions.d.ts.map +1 -0
  88. package/dist/core/web/routes/actions.js +33 -0
  89. package/dist/core/web/routes/actions.js.map +1 -0
  90. package/dist/core/web/routes/config.d.ts +5 -0
  91. package/dist/core/web/routes/config.d.ts.map +1 -0
  92. package/dist/core/web/routes/config.js +30 -0
  93. package/dist/core/web/routes/config.js.map +1 -0
  94. package/dist/core/web/routes/kv.d.ts +6 -0
  95. package/dist/core/web/routes/kv.d.ts.map +1 -0
  96. package/dist/core/web/routes/kv.js +80 -0
  97. package/dist/core/web/routes/kv.js.map +1 -0
  98. package/dist/core/web/routes/plugins.d.ts +5 -0
  99. package/dist/core/web/routes/plugins.d.ts.map +1 -0
  100. package/dist/core/web/routes/plugins.js +98 -0
  101. package/dist/core/web/routes/plugins.js.map +1 -0
  102. package/dist/core/web/routes/sessions.d.ts +8 -0
  103. package/dist/core/web/routes/sessions.d.ts.map +1 -0
  104. package/dist/core/web/routes/sessions.js +130 -0
  105. package/dist/core/web/routes/sessions.js.map +1 -0
  106. package/dist/core/web/routes/shared.d.ts +18 -0
  107. package/dist/core/web/routes/shared.d.ts.map +1 -0
  108. package/dist/core/web/routes/shared.js +19 -0
  109. package/dist/core/web/routes/shared.js.map +1 -0
  110. package/dist/core/web/routes/status.d.ts +6 -0
  111. package/dist/core/web/routes/status.d.ts.map +1 -0
  112. package/dist/core/web/routes/status.js +132 -0
  113. package/dist/core/web/routes/status.js.map +1 -0
  114. package/dist/core/web/server/auth.d.ts +17 -0
  115. package/dist/core/web/server/auth.d.ts.map +1 -0
  116. package/dist/core/web/server/auth.js +68 -0
  117. package/dist/core/web/server/auth.js.map +1 -0
  118. package/dist/core/web/server/csp.d.ts +11 -0
  119. package/dist/core/web/server/csp.d.ts.map +1 -0
  120. package/dist/core/web/server/csp.js +31 -0
  121. package/dist/core/web/server/csp.js.map +1 -0
  122. package/dist/core/web/server/request.d.ts +6 -0
  123. package/dist/core/web/server/request.d.ts.map +1 -0
  124. package/dist/core/web/server/request.js +33 -0
  125. package/dist/core/web/server/request.js.map +1 -0
  126. package/dist/core/web/server/security.d.ts +4 -0
  127. package/dist/core/web/server/security.d.ts.map +1 -0
  128. package/dist/core/web/server/security.js +12 -0
  129. package/dist/core/web/server/security.js.map +1 -0
  130. package/dist/core/web/server/sse.d.ts +18 -0
  131. package/dist/core/web/server/sse.d.ts.map +1 -0
  132. package/dist/core/web/server/sse.js +49 -0
  133. package/dist/core/web/server/sse.js.map +1 -0
  134. package/dist/core/web/server/static.d.ts +16 -0
  135. package/dist/core/web/server/static.d.ts.map +1 -0
  136. package/dist/core/web/server/static.js +80 -0
  137. package/dist/core/web/server/static.js.map +1 -0
  138. package/dist/core/web/server.d.ts +0 -7
  139. package/dist/core/web/server.d.ts.map +1 -1
  140. package/dist/core/web/server.js +41 -263
  141. package/dist/core/web/server.js.map +1 -1
  142. package/docs/architecture.md +28 -11
  143. package/docs/configuration.md +1 -1
  144. package/docs/migration.md +2 -2
  145. package/docs/plugin-api.md +3 -1
  146. package/docs/plugin-development.md +1 -1
  147. package/package.json +19 -17
  148. package/src/app/cli.ts +47 -0
  149. package/src/app/runtime.ts +522 -0
  150. package/src/app.ts +87 -395
  151. package/src/core/dispatch/command.ts +7 -1
  152. package/src/core/dispatch/router.ts +2 -1
  153. package/src/core/plugin/command-params.ts +8 -713
  154. package/src/core/plugin/install/paths.ts +72 -0
  155. package/src/core/plugin/install/state.ts +196 -0
  156. package/src/core/plugin/install/validate-script.ts +154 -0
  157. package/src/core/plugin/install-dir.ts +19 -427
  158. package/src/core/plugin/installer/checks.ts +137 -0
  159. package/src/core/plugin/installer/support.ts +120 -0
  160. package/src/core/plugin/installer/warnings.ts +52 -0
  161. package/src/core/plugin/installer.ts +52 -301
  162. package/src/core/plugin/params/compile.ts +41 -0
  163. package/src/core/plugin/params/declaration.ts +286 -0
  164. package/src/core/plugin/params/input.ts +254 -0
  165. package/src/core/plugin/params/reply.ts +59 -0
  166. package/src/core/plugin/params/type-level.ts +71 -0
  167. package/src/core/plugin/params/types.ts +49 -0
  168. package/src/core/plugin/params/values.ts +146 -0
  169. package/src/core/web/api.ts +33 -759
  170. package/src/core/web/routes/actions.ts +43 -0
  171. package/src/core/web/routes/config.ts +42 -0
  172. package/src/core/web/routes/kv.ts +122 -0
  173. package/src/core/web/routes/plugins.ts +151 -0
  174. package/src/core/web/routes/sessions.ts +188 -0
  175. package/src/core/web/routes/shared.ts +42 -0
  176. package/src/core/web/routes/status.ts +191 -0
  177. package/src/core/web/server/auth.ts +126 -0
  178. package/src/core/web/server/csp.ts +33 -0
  179. package/src/core/web/server/request.ts +38 -0
  180. package/src/core/web/server/security.ts +14 -0
  181. package/src/core/web/server/sse.ts +74 -0
  182. package/src/core/web/server/static.ts +112 -0
  183. package/src/core/web/server.ts +41 -383
@@ -1,62 +1,15 @@
1
1
  import { createServer, } from 'node:http';
2
- import { createReadStream, readFileSync } from 'node:fs';
3
- import { stat } from 'node:fs/promises';
4
- import { extname, join, resolve, sep } from 'node:path';
5
- import { createHash } from 'node:crypto';
6
- import { AuthManager } from './auth.js';
7
2
  import { handleApiRoute } from './api.js';
8
- import { assertCsrf, assertSameOrigin, clearCookie, clientIp, isImmutableAsset, mimeType, parseCookies, readJsonBody, respondWithError, safeStringify, sendError, sendData, serializeCookie, withTimeout, } from './http.js';
3
+ import { AuthManager } from './auth.js';
4
+ import { assertCsrf, assertSameOrigin, respondWithError, sendData, } from './http.js';
9
5
  import { HttpError } from './http.js';
10
- const SESSION_COOKIE = 'jsbot_webui';
6
+ import { authenticate, handleAuth } from './server/auth.js';
7
+ import { buildCsp, cspForStaticDir } from './server/csp.js';
8
+ import { parseSearch, pathnameOf, segmentsOf } from './server/request.js';
9
+ import { applySecurityHeaders } from './server/security.js';
10
+ import { DEFAULT_MAX_SSE_CLIENTS, openSse, } from './server/sse.js';
11
+ import { FALLBACK_BODY, serveStatic } from './server/static.js';
11
12
  const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
12
- const SECURITY_HEADERS = {
13
- 'x-content-type-options': 'nosniff',
14
- 'x-frame-options': 'DENY',
15
- 'referrer-policy': 'no-referrer',
16
- 'cross-origin-opener-policy': 'same-origin',
17
- };
18
- /**
19
- * CSP for the WebUI. webui/index.html ships a single authorized inline
20
- * script (the no-flash appearance bootstrap for the first paint); its exact
21
- * hash is derived from the built index.html on disk so editing the bootstrap
22
- * only needs a rebuild, never a source edit. Every other inline script
23
- * stays blocked.
24
- */
25
- function buildCsp(scriptSrc) {
26
- return `default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src ${scriptSrc}; connect-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'`;
27
- }
28
- /** Extracts the bootstrap script's sha256 from a built index.html. */
29
- function cspForStaticDir(staticDir) {
30
- try {
31
- const html = readFileSync(join(staticDir, 'index.html'), 'utf8');
32
- const match = /<script>([\s\S]*?)<\/script>/.exec(html);
33
- const bootstrap = match?.[1];
34
- if (bootstrap === undefined)
35
- return null;
36
- const hash = createHash('sha256')
37
- .update(bootstrap, 'utf8')
38
- .digest('base64');
39
- return buildCsp(`'self' 'sha256-${hash}'`);
40
- }
41
- catch {
42
- return null;
43
- }
44
- }
45
- const SSE_HEARTBEAT_MS = 15_000;
46
- const DEFAULT_MAX_SSE_CLIENTS = 20;
47
- const SSE_TIMEOUT_MS = 60_000;
48
- const FALLBACK_BODY = (options) => `<!doctype html>
49
- <html lang="zh-CN"><head><meta charset="utf-8">
50
- <title>JsBot WebUI</title>
51
- <style>body{font-family:system-ui,sans-serif;max-width:36em;margin:4rem auto;padding:0 1rem;color:#333}</style>
52
- </head><body>
53
- <h1>WebUI 前端未构建</h1>
54
- <p>管理 API 正常运行,但静态资源缺失。请在项目根目录执行:</p>
55
- <pre><code>npm run build:webui</code></pre>
56
- <p>然后重启进程,访问 <code>${options.listening}</code>。</p>
57
- <p>API 仍可通过 <code>/api/health</code>、登录和各接口访问。</p>
58
- </body></html>
59
- `;
60
13
  function errorPayload(error) {
61
14
  if (error instanceof HttpError) {
62
15
  return {
@@ -71,38 +24,6 @@ function errorPayload(error) {
71
24
  details: undefined,
72
25
  };
73
26
  }
74
- function parseSearch(req) {
75
- const index = (req.url ?? '').indexOf('?');
76
- const query = index >= 0 ? (req.url ?? '').slice(index + 1) : '';
77
- return new URLSearchParams(query);
78
- }
79
- function segmentsOf(pathname) {
80
- return pathname
81
- .split('/')
82
- .filter((segment) => segment.length > 0)
83
- .map((segment) => {
84
- try {
85
- return decodeURIComponent(segment);
86
- }
87
- catch {
88
- return segment;
89
- }
90
- });
91
- }
92
- function pathnameOf(req) {
93
- const url = req.url ?? '/';
94
- const index = url.indexOf('?');
95
- const raw = index >= 0 ? url.slice(0, index) : url;
96
- if (raw.includes('%')) {
97
- try {
98
- return decodeURIComponent(raw);
99
- }
100
- catch {
101
- return raw;
102
- }
103
- }
104
- return raw;
105
- }
106
27
  export class WebUiServer {
107
28
  deps;
108
29
  maxSseClients;
@@ -197,9 +118,7 @@ export class WebUiServer {
197
118
  this.auth.invalidateAll();
198
119
  }
199
120
  applySecurityHeaders(res) {
200
- for (const [key, value] of Object.entries(SECURITY_HEADERS)) {
201
- res.setHeader(key, value);
202
- }
121
+ applySecurityHeaders(res);
203
122
  if (this.cspCache === null) {
204
123
  // Derived once per server instance from the built index.html.
205
124
  const staticDir = this.deps.paths.staticDir;
@@ -220,7 +139,13 @@ export class WebUiServer {
220
139
  return;
221
140
  }
222
141
  if (!pathname.startsWith('/api/') && pathname !== '/api') {
223
- await this.serveStatic(req, res, pathname);
142
+ await serveStatic({
143
+ req,
144
+ res,
145
+ pathname,
146
+ staticDir: this.deps.paths.staticDir,
147
+ fallbackBody: this.fallbackBody,
148
+ });
224
149
  return;
225
150
  }
226
151
  if (!WRITE_METHODS.has(req.method ?? 'GET')) {
@@ -232,19 +157,40 @@ export class WebUiServer {
232
157
  }
233
158
  const segments = segmentsOf(pathname);
234
159
  if (segments[1] === 'auth') {
235
- await this.handleAuth(req, res, segments[2]);
160
+ await handleAuth({
161
+ req,
162
+ res,
163
+ action: segments[2],
164
+ auth: this.auth,
165
+ deps: this.deps,
166
+ bodyLimit: this.bodyLimit,
167
+ });
236
168
  return;
237
169
  }
238
- const session = this.authenticate(req);
170
+ const session = authenticate(this.auth, req);
239
171
  if (session === null) {
240
172
  throw new HttpError(401, '未登录或会话已过期');
241
173
  }
242
174
  if (segments[1] === 'logs' && segments[2] === 'stream') {
243
- this.openSse(req, res, (listener) => this.deps.logs.subscribe(listener), Date.now());
175
+ openSse({
176
+ req,
177
+ res,
178
+ subscribe: (listener) => this.deps.logs.subscribe(listener),
179
+ openedAt: Date.now(),
180
+ maxClients: this.maxSseClients,
181
+ connections: this.sse,
182
+ });
244
183
  return;
245
184
  }
246
185
  if (segments[1] === 'events' && segments[2] === 'stream') {
247
- this.openSse(req, res, (listener) => this.deps.events.subscribe(listener), Date.now());
186
+ openSse({
187
+ req,
188
+ res,
189
+ subscribe: (listener) => this.deps.events.subscribe(listener),
190
+ openedAt: Date.now(),
191
+ maxClients: this.maxSseClients,
192
+ connections: this.sse,
193
+ });
248
194
  return;
249
195
  }
250
196
  const handled = await handleApiRoute({
@@ -265,173 +211,5 @@ export class WebUiServer {
265
211
  respondWithError(res, error);
266
212
  }
267
213
  }
268
- authenticate(req) {
269
- const cookies = parseCookies(req.headers.cookie);
270
- return this.auth.authenticate(cookies[SESSION_COOKIE]);
271
- }
272
- async handleAuth(req, res, action) {
273
- const method = req.method ?? 'GET';
274
- if (action === 'login' && method === 'POST') {
275
- const body = await readJsonBody(req, this.bodyLimit);
276
- const value = typeof body === 'object' && body !== null
277
- ? body
278
- : {};
279
- const ip = clientIp(req, this.deps.getWebUiConfig().trustProxy);
280
- const result = await this.auth.login(value['username'], value['password'], ip);
281
- if (!result.ok || !result.session) {
282
- const headers = {};
283
- if (result.retryAfterSeconds !== undefined) {
284
- headers['retry-after'] = String(result.retryAfterSeconds);
285
- }
286
- sendError(res, result.status, result.message ?? 'login failed', undefined, headers);
287
- return;
288
- }
289
- res.setHeader('set-cookie', serializeCookie(SESSION_COOKIE, result.session.token, {
290
- maxAgeSeconds: this.deps.getWebUiConfig().sessionTtlHours * 3600,
291
- secure: this.isSecure(req),
292
- }));
293
- sendData(res, result.status, {
294
- username: result.session.username,
295
- expiresAt: result.session.expiresAt,
296
- });
297
- return;
298
- }
299
- if (action === 'logout' && method === 'POST') {
300
- const session = this.authenticate(req);
301
- this.auth.logout(this.tokenOf(req));
302
- this.deps.logger.info(`webui logout: ${session?.username ?? 'unknown'}`);
303
- res.setHeader('set-cookie', clearCookie(SESSION_COOKIE));
304
- sendData(res, 200, { ok: true });
305
- return;
306
- }
307
- if (action === 'me' && method === 'GET') {
308
- const session = this.authenticate(req);
309
- if (session === null) {
310
- throw new HttpError(401, '未登录或会话已过期');
311
- }
312
- sendData(res, 200, {
313
- username: session.username,
314
- expiresAt: session.expiresAt,
315
- });
316
- return;
317
- }
318
- throw new HttpError(404, `not found: ${method} /api/auth/${action ?? ''}`);
319
- }
320
- tokenOf(req) {
321
- const cookies = parseCookies(req.headers.cookie);
322
- return cookies[SESSION_COOKIE];
323
- }
324
- isSecure(req) {
325
- if (!this.deps.getWebUiConfig().trustProxy)
326
- return false;
327
- const proto = req.headers['x-forwarded-proto'];
328
- return (typeof proto === 'string' && proto.split(',')[0]?.trim() === 'https');
329
- }
330
- openSse(req, res, subscribe, openedAt) {
331
- if (this.sse.size >= this.maxSseClients) {
332
- throw new HttpError(503, '实时连接数量已达上限');
333
- }
334
- res.writeHead(200, {
335
- 'content-type': 'text/event-stream; charset=utf-8',
336
- 'cache-control': 'no-store, no-transform',
337
- connection: 'keep-alive',
338
- });
339
- res.write(':ok\n\n');
340
- const connection = {
341
- res,
342
- close: () => {
343
- unsubscribe();
344
- clearInterval(heartbeat);
345
- this.sse.delete(connection);
346
- try {
347
- res.end();
348
- }
349
- catch {
350
- // Already closed.
351
- }
352
- },
353
- };
354
- let closing = false;
355
- const unsubscribe = subscribe((entry) => {
356
- if (closing)
357
- return;
358
- res.write(`data: ${safeStringify(entry)}\n\n`);
359
- });
360
- const heartbeat = setInterval(() => {
361
- res.write(`:keepalive ${Date.now() - openedAt}\n\n`);
362
- }, SSE_HEARTBEAT_MS);
363
- req.on('close', () => {
364
- if (closing)
365
- return;
366
- closing = true;
367
- unsubscribe();
368
- clearInterval(heartbeat);
369
- this.sse.delete(connection);
370
- });
371
- this.sse.add(connection);
372
- }
373
- async serveStatic(req, res, pathname) {
374
- if (req.method !== 'GET' && req.method !== 'HEAD') {
375
- throw new HttpError(405, `method not allowed: ${req.method}`);
376
- }
377
- const staticDir = this.deps.paths.staticDir;
378
- if (staticDir === null) {
379
- res.setHeader('content-type', 'text/html; charset=utf-8');
380
- res.setHeader('cache-control', 'no-store');
381
- res.writeHead(503);
382
- res.end(this.fallbackBody);
383
- return;
384
- }
385
- const cleaned = pathname.replace(/\/+$/, '') || '/';
386
- let filePath = cleaned === '/'
387
- ? join(staticDir, 'index.html')
388
- : resolve(staticDir, `.${cleaned}`);
389
- if (!filePath.startsWith(staticDir + sep) && filePath !== staticDir) {
390
- throw new HttpError(403, 'forbidden');
391
- }
392
- let fileStat = await this.statOrNull(filePath);
393
- if (fileStat?.isDirectory()) {
394
- filePath = join(filePath, 'index.html');
395
- fileStat = await this.statOrNull(filePath);
396
- }
397
- if (fileStat === null) {
398
- // SPA fallback: only routes without a file extension.
399
- if (extname(cleaned) === '') {
400
- filePath = join(staticDir, 'index.html');
401
- fileStat = await this.statOrNull(filePath);
402
- }
403
- if (fileStat === null)
404
- throw new HttpError(404, 'not found');
405
- }
406
- const cacheControl = isImmutableAsset(cleaned)
407
- ? 'public, max-age=31536000, immutable'
408
- : 'no-cache';
409
- res.setHeader('content-type', mimeType(filePath));
410
- res.setHeader('cache-control', cacheControl);
411
- res.setHeader('content-length', String(fileStat.size));
412
- res.writeHead(200);
413
- if (req.method === 'HEAD') {
414
- res.end();
415
- return;
416
- }
417
- const stream = createReadStream(filePath);
418
- stream.on('error', () => {
419
- try {
420
- res.end();
421
- }
422
- catch {
423
- // Already closed.
424
- }
425
- });
426
- stream.pipe(res);
427
- }
428
- async statOrNull(filePath) {
429
- try {
430
- return await withTimeout(stat(filePath), 1_000);
431
- }
432
- catch {
433
- return null;
434
- }
435
- }
436
214
  }
437
215
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/core/web/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/core/web/server.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ src/core/* -X-> src/plugins/*
16
16
  - 插件只能通过 `PluginContext`、`EventContext` 和 `BotApi` 使用能力。
17
17
  - `core` 不 import 任何插件;`core`、`admin` 在 `src/plugins/index.ts` 显式注册。
18
18
  - 内置插件是普通源码,随内核一起编译;没有独立依赖,不单独建包。
19
- - 本地插件由 `src/app.ts` 在启动前扫描 `plugins/<id>/dist` 并追加到内置插件之后;缺少 `dist` 时加载器会尝试执行插件的 `build` 脚本。
19
+ - 本地插件由 `src/app/runtime.ts` 在启动前扫描 `plugins/<id>/dist` 并追加到内置插件之后;缺少 `dist` 时加载器会尝试执行插件的 `build` 脚本。
20
20
  - 本地插件放在不跟踪的 `plugins/`,每个插件是独立包,构建后自动加载。
21
21
 
22
22
  ## 运行时主链路
@@ -41,17 +41,15 @@ SDK WebSocket
41
41
  ```text
42
42
  src/
43
43
  app.ts CLI 入口
44
+ app/
45
+ cli.ts 参数解析和 usage
46
+ runtime.ts 运行时构建、重启/关闭协调、WebUI deps
44
47
  core/
45
48
  kernel.ts 运行时组装和生命周期
46
49
  client.ts BotClient 接口和 SDK adapter
47
50
  api.ts BotApi
48
51
  config/ 配置 schema 和加载
49
- dispatch/
50
- router.ts 唯一 SDK middleware
51
- command.ts 命令索引、组注册、多级匹配和冲突检测
52
- handler.ts 事件 handler 注册表
53
- middleware.ts 插件中间件注册表
54
- task-queue.ts 按 key 串行任务队列
52
+ dispatch/ router / command / handler / middleware / task-queue
55
53
  plugin/
56
54
  types.ts 插件契约和公共类型
57
55
  context.ts PluginContext 工厂
@@ -59,17 +57,36 @@ src/
59
57
  gating.ts enabled/private/groups
60
58
  kv.ts SQLite KV
61
59
  loader.ts 本地插件目录加载(缺 dist 时自动构建)
60
+ command-params.ts 命令参数解析入口(barrel)
61
+ params/ 声明、默认值/at/time、输入解析、类型级解析
62
+ install-dir.ts 安装状态/路径入口(barrel)
63
+ install/ 状态读写、路径与 core link、校验脚本
64
+ installer.ts 插件包安装器
65
+ installer/ support / checks / warnings
66
+ install-validate.ts 子进程校验
67
+ npm-runner.ts npm 调用封装
68
+ spec.ts npm 包名/版本解析
62
69
  security/ 角色、权限、拒绝提示
63
70
  messaging/ reply/forward 发送和回复分段
64
71
  storage/ SQLite 和 Session
65
72
  lifecycle/ 启动/停止状态机
73
+ web/
74
+ server.ts WebUiServer
75
+ server/ request / csp / security / sse / static / auth
76
+ api.ts API 路由入口
77
+ routes/ status / sessions / plugins / config / kv / actions
78
+ auth.ts AuthManager
79
+ config-store.ts 配置校验、应用与回滚
80
+ event-feed.ts 实时事件缓冲
81
+ http.ts HTTP 辅助
82
+ types.ts WebUI 类型
83
+ index.ts WebUI 公共导出
66
84
  plugins/
67
85
  core/index.ts /help、/status、/role
68
86
  admin/index.ts /utter、/utter raw
69
87
  index.ts 内置插件清单
70
88
  plugins/ 本地插件根目录,整个目录不跟踪
71
- poke/
72
- llm/
89
+ <id>/
73
90
  ```
74
91
 
75
92
  ## 启动顺序
@@ -127,11 +144,11 @@ npm run smoke # node dist/app.js --help
127
144
  ```bash
128
145
  npm install --prefix plugins/poke
129
146
  npm install --prefix plugins/llm
130
- npm run build:local
147
+ npm run build:plugin
131
148
  node dist/app.js
132
149
  ```
133
150
 
134
- 应用会固定扫描 `plugins/<id>/dist`,并跳过与内置插件同 ID 的本地插件,避免重复注册。没有 `dist` 的本地插件如果带有 `build` 脚本且依赖已安装,会先自动构建再加载;没有 `build` 脚本、缺少 `node_modules` 或构建失败时会记录警告并跳过。
151
+ 应用会固定扫描 `plugins/<id>/dist`,并跳过与内置插件同 ID 的本地插件,避免重复注册。没有 `dist` 的本地插件如果带有 `build` 脚本且依赖已安装,会先自动构建再加载;没有 `build` 脚本、缺少 `node_modules` 或构建失败时会记录警告并跳过。`npm run build:plugin` / `npm run check:plugin` 会自动发现 `plugins/*` 下的本地源码插件,新增插件不需要改根 `package.json`。
135
152
 
136
153
  ## 在线安装插件
137
154
 
@@ -174,7 +174,7 @@ node dist/app.js
174
174
  ```bash
175
175
  npm install --prefix plugins/poke
176
176
  npm install --prefix plugins/llm
177
- npm run build:local
177
+ npm run build:plugin
178
178
 
179
179
  npm run dev
180
180
  ```
package/docs/migration.md CHANGED
@@ -7,7 +7,7 @@
7
7
  内置插件 `core`、`admin` 位于 `src/plugins/`,是普通源码。`poke`、`llm` 等其它插件放在 `plugins/`,该目录整体不进入 git,每个插件有自己的 `package.json`:
8
8
 
9
9
  - 安装本地依赖:`npm install --prefix plugins/poke`、`npm install --prefix plugins/llm`
10
- - 构建本地插件:`npm run build:local`
10
+ - 构建本地插件:`npm run build:plugin`
11
11
  - 启动时加载:应用会自动扫描 `plugins/<id>/dist`,不需要路径参数
12
12
 
13
13
  应用会跳过与内置插件同 ID 的本地插件。没有加载的插件不能出现在 `plugins` 配置中,否则会因未知插件 ID 启动失败。
@@ -64,7 +64,7 @@
64
64
  npm run build
65
65
  npm install --prefix plugins/poke
66
66
  npm install --prefix plugins/llm
67
- npm run build:local
67
+ npm run build:plugin
68
68
  node dist/app.js
69
69
  ```
70
70
 
@@ -256,7 +256,9 @@ ctx.commands.register(
256
256
  - `number`:有限数字,包括小数。
257
257
  - `integer`:整数。
258
258
  - `boolean`:`true/false`、`1/0`、`yes/no`、`y/n`、`on/off`,大小写不敏感。
259
+ - `time`:时间长度,解析为秒数。支持纯数字(秒)和单位 `s/m/h/d/w` 或中文 `秒/分/分钟/时/小时/天/周`,可以组合,例如 `60`、`10s`、`5m`、`1h30m`、`1d`、`1小时30分钟`;支持 `1.5h` 这类小数单位,但总秒数必须是整数。可以声明默认值。
259
260
  - `at`:@ 提及或 QQ 号,解析为数字。支持 `[CQ:at,qq=123456]`(可带 `name` 等附加参数)和纯数字 `123456`;`@全体成员` 和普通文本会报类型错误,且不能声明默认值。
261
+ - `reply`:当前消息引用(回复)的消息 ID,解析为数字。该参数不消费命令文本,而是从事件中的 `reply` 分段读取;未引用消息时必填参数会报错,且不能声明默认值。引用消息发送命令时,`raw_message` 开头的 `[CQ:reply,...]` 会被忽略,命令仍能正常匹配。
260
262
  - `[...rest]`:把剩余 token 依次收集为字符串;只能放在最后,且没有必填形式。
261
263
 
262
264
  固定参数可以用双引号或单引号包裹,例如 `/ask "hello world" 2` 会把 `hello world` 作为一个 token;引号内的反斜杠用于转义。
@@ -514,7 +516,7 @@ TypeScript 插件必须在生产运行前编译为 JavaScript。本地插件和
514
516
  ```bash
515
517
  npm install --prefix plugins/poke
516
518
  npm install --prefix plugins/llm
517
- npm run build:local
519
+ npm run build:plugin
518
520
 
519
521
  node dist/app.js
520
522
  ```
@@ -232,7 +232,7 @@ npm run build
232
232
 
233
233
  根目录的 `npm run build` 构建内核。插件自身的构建在启动时缺少 `dist` 会自动执行;需要提前校验时也可以手动运行 `npm run build --prefix plugins/my-plugin`。
234
234
 
235
- 根目录的 `npm run build:local` / `npm run check:local` 目前只覆盖 `plugins/poke` 和 `plugins/llm`。新增插件请使用 `npm run build --prefix plugins/<id>` 和 `npm run check --prefix plugins/<id>`,或者把新目录加入根 `package.json` 的对应脚本。
235
+ 根目录的 `npm run build:plugin` / `npm run check:plugin` 会自动发现 `plugins/*` 中包含 `src/`、`tsconfig.json` 且声明了对应 npm script 的目录;没有安装 `node_modules` 的目录会跳过。新增插件不需要修改根 `package.json`,也可以单独运行 `npm run build --prefix plugins/<id>` 和 `npm run check --prefix plugins/<id>`。
236
236
 
237
237
  开发时可以单独开一个终端监听:
238
238
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsbot-tellus/core",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "engines": {
5
5
  "node": "^24.22.1 || >=26.12.1"
6
6
  },
@@ -44,27 +44,29 @@
44
44
  "jsbot": "dist/app.js"
45
45
  },
46
46
  "scripts": {
47
- "test": "vitest run",
48
- "check": "tsc --noEmit",
49
- "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
50
- "build": "npm run clean && npm run build:webui && tsc -p tsconfig.build.json && node -e \"require('node:fs').chmodSync('dist/app.js', 0o755)\"",
51
- "prepack": "npm run build",
52
- "prepublishOnly": "npm run check && npm test",
53
- "build:local": "npm run build --prefix plugins/poke && npm run build --prefix plugins/llm",
54
- "check:local": "npm run check --prefix plugins/poke && npm run check --prefix plugins/llm",
55
- "plugin:gen": "tsx scripts/plugin-gen.ts",
47
+ "dev": "tsx watch src/app.ts",
56
48
  "dev:webui": "vite --config webui/vite.config.ts",
57
- "check:webui": "node scripts/webui-check.cjs",
58
- "build:webui": "vite build --config webui/vite.config.ts",
59
49
  "start": "node dist/app.js",
60
- "start:build": "npm run build && node dist/app.js",
50
+ "start:build": "npm run build && npm start",
61
51
  "start:source": "tsx src/app.ts",
62
- "dev": "tsx watch src/app.ts",
63
52
  "smoke": "node dist/app.js --help",
53
+ "build": "npm run clean && npm run build:webui && tsc -p tsconfig.build.json && node -e \"require('node:fs').chmodSync('dist/app.js', 0o755)\"",
54
+ "build:webui": "vite build --config webui/vite.config.ts",
55
+ "build:plugin": "node scripts/plugins.mjs build",
56
+ "check": "tsc --noEmit",
57
+ "check:webui": "node scripts/webui-check.cjs",
58
+ "check:plugin": "node scripts/plugins.mjs check",
59
+ "check:all": "npm run check && npm run check:webui && npm run check:plugin",
60
+ "test": "vitest run",
61
+ "test:watch": "vitest",
64
62
  "format": "prettier --write .",
65
- "format:plugin": "prettier --write plugins --ignore-path ''",
66
- "format:plugin:check": "prettier --check plugins --ignore-path ''",
67
- "format:check": "prettier --check ."
63
+ "format:check": "prettier --check .",
64
+ "format:plugin": "prettier --write \"plugins/*/src/**/*.{ts,js,vue,css,json,md}\" \"plugins/*/*.{json,md}\" --ignore-path ''",
65
+ "format:plugin:check": "prettier --check \"plugins/*/src/**/*.{ts,js,vue,css,json,md}\" \"plugins/*/*.{json,md}\" --ignore-path ''",
66
+ "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
67
+ "plugin:gen": "tsx scripts/plugin-gen.ts",
68
+ "prepack": "npm run build",
69
+ "prepublishOnly": "npm run check && npm run check:webui && npm test"
68
70
  },
69
71
  "dependencies": {
70
72
  "@snowluma/sdk": "^2.2.0",
package/src/app/cli.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { parseArgs } from 'node:util'
2
+ import { LOCAL_PLUGIN_DIR } from './runtime.js'
3
+
4
+ export const USAGE = `Usage: jsbot [options]
5
+
6
+ Options:
7
+ --config <path> Config file path (env: BOT_CONFIG)
8
+ --data-dir <path> Data directory (env: BOT_DATA_DIR)
9
+ --log-level <level> debug, info, warn or error (env: BOT_LOG_LEVEL)
10
+ --help Show this help
11
+
12
+ Config precedence: CLI > environment > ./bot.config.json.
13
+ Data precedence: CLI > environment > ./data.
14
+ Local plugins: ./${LOCAL_PLUGIN_DIR}/<id>/dist (auto-built when missing).
15
+ `
16
+
17
+ export function pick(value: unknown): string | undefined {
18
+ return typeof value === 'string' && value.trim().length > 0
19
+ ? value
20
+ : undefined
21
+ }
22
+
23
+ export interface CliOptions {
24
+ help: boolean
25
+ config: string | undefined
26
+ dataDir: string | undefined
27
+ logLevel: string | undefined
28
+ }
29
+
30
+ export function parseCli(): CliOptions {
31
+ const { values } = parseArgs({
32
+ options: {
33
+ config: { type: 'string' },
34
+ 'data-dir': { type: 'string' },
35
+ 'log-level': { type: 'string' },
36
+ help: { type: 'boolean', short: 'h' },
37
+ },
38
+ allowPositionals: false,
39
+ })
40
+
41
+ return {
42
+ help: values.help === true,
43
+ config: values.config,
44
+ dataDir: values['data-dir'],
45
+ logLevel: values['log-level'],
46
+ }
47
+ }