chattercatcher 0.1.21 → 0.1.22

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/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import fs14 from "fs/promises";
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "chattercatcher",
11
- version: "0.1.21",
11
+ version: "0.1.22",
12
12
  description: "\u672C\u5730\u4F18\u5148\u7684\u98DE\u4E66/Lark \u5BB6\u5EAD\u7FA4\u77E5\u8BC6\u5E93\u673A\u5668\u4EBA",
13
13
  type: "module",
14
14
  main: "dist/index.js",
@@ -5360,6 +5360,7 @@ function buildHtml() {
5360
5360
  const gatewayClass = status.gateway.configured ? "status-ok" : "status-warn";
5361
5361
  metrics.innerHTML = [
5362
5362
  ["Gateway", formatGatewayValue(status.gateway), formatGatewayNote(status.gateway), gatewayClass],
5363
+ ["\u7248\u672C", status.version || "unknown", "\u5F53\u524D\u8FD0\u884C\u7248\u672C", ""],
5363
5364
  ["\u7FA4\u804A", status.data.chats, "\u672C\u5730\u7FA4\u804A\u6570", ""],
5364
5365
  ["\u6D88\u606F", status.data.messages, "\u5DF2\u5165\u5E93\u6D88\u606F", ""],
5365
5366
  ["\u4F1A\u8BDD\u8BB0\u5FC6", status.data.episodes, "\u5DF2\u751F\u6210\u6458\u8981", ""],
@@ -5553,31 +5554,41 @@ function buildHtml() {
5553
5554
  ");
5554
5555
  }
5555
5556
 
5556
- async function load() {
5557
+ async function fetchJson(path) {
5558
+ const response = await fetch(path);
5559
+ if (!response.ok) {
5560
+ const body = await response.text();
5561
+ throw new Error(path + " " + response.status + " " + body);
5562
+ }
5563
+ return response.json();
5564
+ }
5565
+
5566
+ function renderLoadError(element, error) {
5567
+ element.className = "empty";
5568
+ element.textContent = "\u52A0\u8F7D\u5931\u8D25\uFF1A" + (error instanceof Error ? error.message : String(error));
5569
+ }
5570
+
5571
+ async function loadSection(path, element, render) {
5557
5572
  try {
5558
- const [status, recent, episodeList, chatList, fileList, jobList, qaLogList, cronJobList] = await Promise.all([
5559
- fetch("/api/status").then((response) => response.json()),
5560
- fetch("/api/messages/recent?limit=20").then((response) => response.json()),
5561
- fetch("/api/episodes?limit=10").then((response) => response.json()),
5562
- fetch("/api/chats").then((response) => response.json()),
5563
- fetch("/api/files").then((response) => response.json()),
5564
- fetch("/api/file-jobs").then((response) => response.json()),
5565
- fetch("/api/qa-logs?limit=10").then((response) => response.json()),
5566
- fetch("/api/cron-jobs").then((response) => response.json()),
5567
- ]);
5568
- renderMetrics(status);
5569
- renderMessages(recent.items);
5570
- renderEpisodes(episodeList.items);
5571
- renderChats(chatList.items);
5572
- renderFiles(fileList.items);
5573
- renderFileJobs(jobList.items);
5574
- renderQaLogs(qaLogList.items);
5575
- renderCronJobs(cronJobList.items);
5573
+ render(await fetchJson(path));
5576
5574
  } catch (error) {
5577
- metrics.innerHTML = '<div class="empty">\u6570\u636E\u52A0\u8F7D\u5931\u8D25\uFF1A' + escapeHtml(error instanceof Error ? error.message : String(error)) + '</div>';
5575
+ renderLoadError(element, error);
5578
5576
  }
5579
5577
  }
5580
5578
 
5579
+ async function load() {
5580
+ await Promise.all([
5581
+ loadSection("/api/status", metrics, renderMetrics),
5582
+ loadSection("/api/messages/recent?limit=20", messages, (data) => renderMessages(data.items)),
5583
+ loadSection("/api/episodes?limit=10", episodes, (data) => renderEpisodes(data.items)),
5584
+ loadSection("/api/chats", chats, (data) => renderChats(data.items)),
5585
+ loadSection("/api/files", files, (data) => renderFiles(data.items)),
5586
+ loadSection("/api/file-jobs", fileJobs, (data) => renderFileJobs(data.items)),
5587
+ loadSection("/api/qa-logs?limit=10", qaLogs, (data) => renderQaLogs(data.items)),
5588
+ loadSection("/api/cron-jobs", cronJobs, (data) => renderCronJobs(data.items)),
5589
+ ]);
5590
+ }
5591
+
5581
5592
  async function processNow() {
5582
5593
  processMessages.disabled = true;
5583
5594
  actionStatus.textContent = "\u6B63\u5728\u5904\u7406\u6D88\u606F\u7D22\u5F15...";
@@ -5652,9 +5663,10 @@ function isAuthorizedWebAction(request, token) {
5652
5663
  const provided = readHeader(request.headers["x-chattercatcher-web-token"]);
5653
5664
  return provided === token;
5654
5665
  }
5655
- function createWebApp(config) {
5666
+ function createWebApp(config, options = {}) {
5656
5667
  const app = Fastify({ logger: false });
5657
5668
  const database = openDatabase(config);
5669
+ const version = options.version ?? "unknown";
5658
5670
  const messages = new MessageRepository(database);
5659
5671
  const episodes = new EpisodeRepository(database);
5660
5672
  const fileJobs = new FileJobRepository(database);
@@ -5676,6 +5688,7 @@ function createWebApp(config) {
5676
5688
  await tokenReady;
5677
5689
  return {
5678
5690
  app: "ChatterCatcher",
5691
+ version,
5679
5692
  gateway: getGatewayStatus(config),
5680
5693
  data: {
5681
5694
  chats: messages.getChatCount(),
@@ -5780,12 +5793,13 @@ function createWebApp(config) {
5780
5793
  });
5781
5794
  return app;
5782
5795
  }
5783
- async function startWebServer(config) {
5784
- const app = createWebApp(config);
5796
+ async function startWebServer(config, options = {}) {
5797
+ const app = createWebApp(config, options);
5785
5798
  await app.listen({ host: config.web.host, port: config.web.port });
5786
5799
  const address = app.server.address();
5787
5800
  const url = typeof address === "string" ? address : `http://${config.web.host}:${address?.port ?? config.web.port}`;
5788
- console.log(`ChatterCatcher Web UI: ${url}`);
5801
+ const versionText = options.version ? ` ${options.version}` : "";
5802
+ console.log(`ChatterCatcher Web UI${versionText}: ${url}`);
5789
5803
  }
5790
5804
 
5791
5805
  // src/cli.ts
@@ -5964,7 +5978,7 @@ async function startGatewayForegroundCommand() {
5964
5978
  });
5965
5979
  console.log(status.message);
5966
5980
  console.log("\u672C\u5730 Web UI \u4ECD\u4F1A\u542F\u52A8\uFF0C\u65B9\u4FBF\u7EE7\u7EED\u914D\u7F6E\u3002");
5967
- await startWebServer(config);
5981
+ await startWebServer(config, { version: package_default.version });
5968
5982
  return;
5969
5983
  }
5970
5984
  await tryEnsureFeishuBotOpenId(config, secrets);
@@ -6027,7 +6041,7 @@ async function startGatewayForegroundCommand() {
6027
6041
  console.log(status.message);
6028
6042
  try {
6029
6043
  await gatewayRuntime.start();
6030
- await startWebServer(config);
6044
+ await startWebServer(config, { version: package_default.version });
6031
6045
  } catch (error) {
6032
6046
  cleanup();
6033
6047
  throw error;
@@ -6066,7 +6080,7 @@ gateway.command("restart").description("\u91CD\u542F Gateway").action(async () =
6066
6080
  var web = program.command("web").description("\u7BA1\u7406\u672C\u5730 Web UI");
6067
6081
  web.command("start").description("\u542F\u52A8\u672C\u5730 Web UI").action(async () => {
6068
6082
  const config = await loadConfig();
6069
- await startWebServer(config);
6083
+ await startWebServer(config, { version: package_default.version });
6070
6084
  });
6071
6085
  var data = program.command("data").description("\u7BA1\u7406\u672C\u5730\u77E5\u8BC6\u5E93\u6570\u636E");
6072
6086
  async function deleteDataCommand(targetType, targetId, options) {