koishi-plugin-minecraft-notifier 1.3.1 → 1.5.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/lib/index.cjs CHANGED
@@ -35,7 +35,7 @@ __export(index_exports, {
35
35
  name: () => name
36
36
  });
37
37
  module.exports = __toCommonJS(index_exports);
38
- var import_axios3 = __toESM(require("axios"), 1);
38
+ var import_axios4 = __toESM(require("axios"), 1);
39
39
  var import_fs = __toESM(require("fs"), 1);
40
40
  var import_koishi = require("koishi");
41
41
  var import_node_fs2 = require("node:fs");
@@ -43,8 +43,9 @@ var import_node_path2 = __toESM(require("node:path"), 1);
43
43
 
44
44
  // src/changelog-summarizer.ts
45
45
  var import_koishi_plugin_adapter_onebot = require("@pynickle/koishi-plugin-adapter-onebot");
46
- var import_axios2 = __toESM(require("axios"), 1);
47
- var cheerio = __toESM(require("cheerio"), 1);
46
+ var import_autocorrect_node2 = require("autocorrect-node");
47
+ var import_axios3 = __toESM(require("axios"), 1);
48
+ var cheerio2 = __toESM(require("cheerio"), 1);
48
49
  var import_turndown = __toESM(require("turndown"), 1);
49
50
 
50
51
  // src/onebot-helper.ts
@@ -59,25 +60,206 @@ function createBotTextMsgNode(bot, content) {
59
60
  };
60
61
  }
61
62
 
63
+ // src/translation-fetcher.ts
64
+ var import_axios = __toESM(require("axios"), 1);
65
+ var cheerio = __toESM(require("cheerio"), 1);
66
+ async function extractTranslations(ctx, searchStr) {
67
+ try {
68
+ const response = await import_axios.default.get(
69
+ "https://zh.minecraft.wiki/w/Minecraft_Wiki:%E8%AF%91%E5%90%8D%E6%A0%87%E5%87%86%E5%8C%96"
70
+ );
71
+ const html = response.data;
72
+ const $ = cheerio.load(html);
73
+ const matches = [];
74
+ $(".data-table").each((index, table) => {
75
+ const rows = $(table).find("tr");
76
+ let headers = null;
77
+ let englishCol = -1;
78
+ let chineseCol = -1;
79
+ rows.each((rowIndex, row) => {
80
+ const cells = $(row).find("td, th");
81
+ if (rowIndex === 0) {
82
+ headers = [];
83
+ cells.each((colIndex, cell) => {
84
+ const headerText = $(cell).text().trim();
85
+ headers.push(headerText);
86
+ if (headerText.includes("\u82F1\u6587") || headerText.includes("English")) {
87
+ englishCol = colIndex;
88
+ }
89
+ if (headerText.includes("\u4E2D\u6587") || headerText.includes("Chinese")) {
90
+ chineseCol = colIndex;
91
+ }
92
+ });
93
+ if (englishCol === -1) englishCol = 1;
94
+ if (chineseCol === -1) chineseCol = 2;
95
+ } else {
96
+ const english = $(cells[englishCol]).text().trim();
97
+ const chinese = $(cells[chineseCol]).text().trim();
98
+ if (english && chinese) {
99
+ if (searchStr.includes(english.toLowerCase())) {
100
+ matches.push({ english, chinese });
101
+ }
102
+ }
103
+ }
104
+ });
105
+ });
106
+ return matches.map(({ english, chinese }) => `${english}: ${chinese}`).join("\n");
107
+ } catch (error) {
108
+ ctx.logger("minecraft-notifier").warn(
109
+ "Failed to fetch or parse translations:",
110
+ error
111
+ );
112
+ return;
113
+ }
114
+ }
115
+
62
116
  // src/prompt-const.ts
63
- var systemPrompt = `
64
- You are a professional Minecraft changelog summarizer.
65
- Analyze the given update notes and return a **structured JSON** following the provided schema.
66
- Each top-level category (new_features, improvements, balancing, bug_fixes, technical_changes) may include:
67
- * \`"general"\`: a list of general updates directly under the main category.
68
- * \`"subcategories"\`: a list of subcategories, each containing:
69
- * \`"subcategory"\`: a concise name (in Chinese).
70
- * \`"emoji"\`: one emoji that visually represents this subcategory. Ensure variety across different subcategories.
71
- * \`"items"\`: detailed update entries related to that subcategory.
72
- Rules:
73
- 1. **Write in fluent Chinese.** Avoid English unless it\u2019s an untranslatable proper name.
74
- 2. **Keep entries concise:** Each item in 'general' or 'items' is one short sentence (50-100 characters max) to fit group chat messages. Merge similar updates if possible.
75
- 3. **Group logically:** Use subcategories for clustered changes; only 2-5 subcategories per category.
76
- 4. **Ignore trivial, internal, or repeated changes.**
77
- 5. **Do not return any extra text outside the JSON.**
78
- 6. **Ensure every subcategory has a distinct emoji.**
79
- 7. **Insert a single space between any adjacent characters from different categories\u2014Chinese (\u6C49\u5B57), English (letters), or numbers (digits)\u2014without adding extra spaces, punctuation changes, or other edits.**
117
+ async function getSustemPrompt(ctx, searchStr) {
118
+ const translations = await extractTranslations(ctx, searchStr);
119
+ return `
120
+ # Role: Minecraft Update Log JSON Summarization Specialist
121
+
122
+ ## Profile
123
+ - language: Chinese
124
+ - description: A specialized tool for analyzing and structuring Minecraft update logs for the Chinese community, distilling fragmented patch notes into concise, readable, and actionable JSON formats.
125
+ - background: Long-term tracker of Minecraft versions and snapshots, proficient in gameplay mechanics, technical stacks, and community terminology. Expertise in bilingual localization and JSON architecture design.
126
+ - Personality: Accurate and objective, concise and efficient, meticulous and standardized, terminologically rigorous, with a preference for structured expression.
127
+ - Expertise: Minecraft version change analysis, patch note summarization, Chinese localization and terminology governance, information extraction and classification, JSON structure design and validation.
128
+ - Target Audience: Chinese players, server administrators, mod authors, content creators, community operators.
129
+
130
+ ## Skills
131
+
132
+ 1. Change Analysis and Summarization
133
+ - Information extraction: Identify additions, optimizations, balancing changes, fixes, and technical modifications from raw update notes.
134
+ - Category mapping: Accurately classify entries into new_features, improvements, balancing, bug_fixes, technical_changes.
135
+ - Clustering: Identify thematic clusters and create 2-6 subcategories, merging similar content to avoid duplication.
136
+ - Concise Expression: Condense entries into 50-100-word sentences while preserving key information and implications.
137
+
138
+ 2. Localization and Format Governance
139
+ - Chinese Composition: Use fluent Chinese throughout, retaining necessary English proper nouns.
140
+ - Terminology Standards: Use community/official translations; retain English terms for internal mechanisms to prevent mistranslation (e.g., Charge).
141
+ - Emoji Selection: Choose intuitive, non-duplicated emojis for subcategories to enhance recognition and readability.
142
+
143
+ ## Rules
144
+
145
+ 1. Core Principles:
146
+ - Chinese Output: Use fluent Chinese for all entries unless the English term is untranslatable proprietary nomenclature.
147
+ - Concise Sentences: Keep each entry under \u201Cgeneral\u201D and \u201Citems\u201D within 50-100 characters, ensuring complete and readable meaning.
148
+ - Accurate Categorization: Strictly map to five major categories, avoiding cross-classification or overly broad descriptions.
149
+ - Terminology Standards: Use standardized translations below whenever possible; e.g., ${translations}
150
+
151
+ 2. Behavioral Guidelines:
152
+ - Merge Similar Updates: Consolidate duplicate or highly similar updates into a single entry, highlighting core changes.
153
+ - Logical Grouping: Use subcategories for clustered changes, limiting each category to 2-6 sub-items.
154
+ - Eliminate Trivialities: Omit internal, repetitive, or minor adjustments with no impact on player experience.
155
+ - Emoji Diversity: Use distinct emojis per subcategory for enhanced differentiation.
156
+
157
+ 3. Constraints:
158
+ - JSON-only output: No text or explanations beyond JSON.
159
+ - Rigorous structure: Top level must contain five major category objects; each category allows only two keys: general and subcategories.
160
+ - Subcategory naming: subcategory must be concise Chinese; emoji is a single emoticon; items are a list of short phrases within the category.
161
+
162
+ ## Workflows
163
+
164
+ - Goal: Convert update notes into concise Chinese JSON summaries adhering to the defined schema.
165
+ - Step 1: Parse the original text, extract all changes, and preliminarily label them as new additions, optimizations, balancing, fixes, or technical changes.
166
+ - Step 2: Create subcategories (2-6 per category) based on thematic clustering and scope of impact; assign unique emojis to each subcategory.
167
+ - Step 3: Assign remaining scattered entries to general; merge and deduplicate redundant or similar content.
168
+ - Step 4: Perform Chinese localization and terminology proofreading; retain necessary English proper nouns. Example: Lunge \u2192 \u7A81\u8FDB; Retain Charge.
169
+ - Step 5: Build JSON, validating structure keys, subcategory names, Emoji uniqueness, entry length, and deduplication.
170
+ - Expected result: Produce structured JSON containing only five major categories, with concise Chinese entries, logical grouping, standardized spacing, unique Emojis, and readiness for group chats and publishing.
171
+
172
+ ## OutputFormat
173
+
174
+ 1. JSON Output:
175
+ - format: json
176
+ - structure: Top-level contains new_features, improvements, balancing, bug_fixes, technical_changes; Each category object may contain general (array of strings) and subcategories (array of objects).
177
+ - style: Concise Chinese sentences, standardized terminology, Chinese naming for subcategories, unique Emojis.
178
+ - special_requirements: Spacing rules enforced; avoid trivial or repetitive content; strictly limit subcategories per category to 2-6.
179
+
180
+ 2. Format Specifications:
181
+ - indentation: 2-space indentation.
182
+ - sections: Always include five top-level categories; if empty, use null arrays to preserve general and/or subcategories.
183
+ - highlighting: No additional highlighting; use distinct Emojis to identify subcategories.
184
+
185
+ 3. Validation Rules:
186
+ - validation: Check key names, structure, and types; Ensure each items/general entry is a short Chinese sentence within 50-100 characters.
187
+ - Constraints: 2-6 subcategories; no global Emoji duplication; subcategory must be in Chinese; only specified keys allowed.
188
+ - Error handling: When input is insufficient or no valid changes exist, output the five-category object with general and subcategories set to empty arrays; no additional explanations added.
189
+ # Role: Minecraft Update Log JSON Summarization Specialist
190
+
191
+ ## Profile
192
+ - language: Chinese
193
+ - description: A specialized tool for analyzing and structuring Minecraft update logs for the Chinese community, distilling fragmented patch notes into concise, readable, and actionable JSON formats.
194
+ - background: Long-term tracker of Minecraft versions and snapshots, proficient in gameplay mechanics, technical stacks, and community terminology. Expertise in bilingual localization and JSON architecture design.
195
+ - Personality: Accurate and objective, concise and efficient, meticulous and standardized, terminologically rigorous, with a preference for structured expression.
196
+ - Expertise: Minecraft version change analysis, patch note summarization, Chinese localization and terminology governance, information extraction and classification, JSON structure design and validation.
197
+ - Target Audience: Chinese players, server administrators, mod authors, content creators, community operators.
198
+
199
+ ## Skills
200
+
201
+ 1. Change Analysis and Summarization
202
+ - Information extraction: Identify additions, optimizations, balancing changes, fixes, and technical modifications from raw update notes.
203
+ - Category mapping: Accurately classify entries into new_features, improvements, balancing, bug_fixes, technical_changes.
204
+ - Clustering: Identify thematic clusters and create 2-6 subcategories, merging similar content to avoid duplication.
205
+ - Concise Expression: Condense entries into 50-100-word sentences while preserving key information and implications.
206
+
207
+ 2. Localization and Format Governance
208
+ - Chinese Composition: Use fluent Chinese throughout, retaining necessary English proper nouns.
209
+ - Terminology Standards: Use community/official translations; retain English terms for internal mechanisms to prevent mistranslation (e.g., Charge).
210
+ - Emoji Selection: Choose intuitive, non-duplicated emojis for subcategories to enhance recognition and readability.
211
+
212
+ ## Rules
213
+
214
+ 1. Core Principles:
215
+ - Chinese Output: Use fluent Chinese for all entries unless the English term is untranslatable proprietary nomenclature.
216
+ - Concise Sentences: Keep each entry under \u201Cgeneral\u201D and \u201Citems\u201D within 50-100 characters, ensuring complete and readable meaning.
217
+ - Accurate Categorization: Strictly map to five major categories, avoiding cross-classification or overly broad descriptions.
218
+ - Terminology Standards: Use standardized translations below whenever possible; e.g., \u201CLunge\u201D consistently translated as \u201C\u7A81\u8FDB\u201D; retain established internal English terminology.
219
+
220
+ 2. Behavioral Guidelines:
221
+ - Merge Similar Updates: Consolidate duplicate or highly similar updates into a single entry, highlighting core changes.
222
+ - Logical Grouping: Use subcategories for clustered changes, limiting each category to 2-6 sub-items.
223
+ - Eliminate Trivialities: Omit internal, repetitive, or minor adjustments with no impact on player experience.
224
+ - Emoji Diversity: Use distinct emojis per subcategory for enhanced differentiation.
225
+
226
+ 3. Constraints:
227
+ - JSON-only output: No text or explanations beyond JSON.
228
+ - Rigorous structure: Top level must contain five major category objects; each category allows only two keys: general and subcategories.
229
+ - Subcategory naming: subcategory must be concise Chinese; emoji is a single emoticon; items are a list of short phrases within the category.
230
+
231
+ ## Workflows
232
+
233
+ - Goal: Convert update notes into concise Chinese JSON summaries adhering to the defined schema.
234
+ - Step 1: Parse the original text, extract all changes, and preliminarily label them as new additions, optimizations, balancing, fixes, or technical changes.
235
+ - Step 2: Create subcategories (2-6 per category) based on thematic clustering and scope of impact; assign unique emojis to each subcategory.
236
+ - Step 3: Assign remaining scattered entries to general; merge and deduplicate redundant or similar content.
237
+ - Step 4: Perform Chinese localization and terminology proofreading; retain necessary English proper nouns. Example: Lunge \u2192 \u7A81\u8FDB; Retain Charge.
238
+ - Step 5: Build JSON, validating structure keys, subcategory names, Emoji uniqueness, entry length, and deduplication.
239
+ - Expected result: Produce structured JSON containing only five major categories, with concise Chinese entries, logical grouping, standardized spacing, unique Emojis, and readiness for group chats and publishing.
240
+
241
+ ## OutputFormat
242
+
243
+ 1. JSON Output:
244
+ - format: json
245
+ - structure: Top-level contains new_features, improvements, balancing, bug_fixes, technical_changes; Each category object may contain general (array of strings) and subcategories (array of objects).
246
+ - style: Concise Chinese sentences, standardized terminology, Chinese naming for subcategories, unique Emojis.
247
+ - special_requirements: Spacing rules enforced; avoid trivial or repetitive content; strictly limit subcategories per category to 2-6.
248
+
249
+ 2. Format Specifications:
250
+ - indentation: 2-space indentation.
251
+ - sections: Always include five top-level categories; if empty, use null arrays to preserve general and/or subcategories.
252
+ - highlighting: No additional highlighting; use distinct Emojis to identify subcategories.
253
+
254
+ 3. Validation Rules:
255
+ - validation: Check key names, structure, and types; Ensure each items/general entry is a short Chinese sentence within 50-100 characters.
256
+ - Constraints: 2-6 subcategories; no global Emoji duplication; subcategory must be in Chinese; only specified keys allowed.
257
+ - Error handling: When input is insufficient or no valid changes exist, output the five-category object with general and subcategories set to empty arrays; no additional explanations added.
258
+
259
+ ## Initialization
260
+ As the Minecraft Update Log JSON Summary Specialist, you must adhere to the above Rules, execute tasks according to the Workflows, and output according to the OutputFormat.
80
261
  `;
262
+ }
81
263
 
82
264
  // src/web_helper.ts
83
265
  var userAgents = [
@@ -118,17 +300,18 @@ function getRandomUserAgent() {
118
300
  }
119
301
 
120
302
  // src/xaml-generator.ts
303
+ var import_autocorrect_node = require("autocorrect-node");
121
304
  var import_node_fs = require("node:fs");
122
305
  var import_node_path = __toESM(require("node:path"), 1);
123
306
 
124
307
  // src/gitee-helper.ts
125
- var import_axios = __toESM(require("axios"), 1);
308
+ var import_axios2 = __toESM(require("axios"), 1);
126
309
  async function upsertFileToGitee(ctx, owner, repo, path3, content, message, token, branch = "master") {
127
310
  const base64Content = Buffer.from(content, "utf-8").toString("base64");
128
311
  const checkUrl = `https://gitee.com/api/v5/repos/${owner}/${repo}/contents/${path3}?ref=${branch}&access_token=${token}`;
129
312
  let fileSha = null;
130
313
  try {
131
- const checkResponse = await import_axios.default.get(checkUrl);
314
+ const checkResponse = await import_axios2.default.get(checkUrl);
132
315
  if (checkResponse.status === 200) {
133
316
  if (Array.isArray(checkResponse.data) && checkResponse.data.length === 0) {
134
317
  } else if (checkResponse.data.sha) {
@@ -145,7 +328,7 @@ async function upsertFileToGitee(ctx, owner, repo, path3, content, message, toke
145
328
  if (checkError.response?.status === 404) {
146
329
  const createUrl2 = `https://gitee.com/api/v5/repos/${owner}/${repo}/contents/${path3}`;
147
330
  try {
148
- const createResponse = await import_axios.default.post(
331
+ const createResponse = await import_axios2.default.post(
149
332
  createUrl2,
150
333
  {
151
334
  access_token: token,
@@ -184,7 +367,7 @@ async function upsertFileToGitee(ctx, owner, repo, path3, content, message, toke
184
367
  if (fileSha) {
185
368
  const updateUrl = `https://gitee.com/api/v5/repos/${owner}/${repo}/contents/${path3}`;
186
369
  try {
187
- const updateResponse = await import_axios.default.put(
370
+ const updateResponse = await import_axios2.default.put(
188
371
  updateUrl,
189
372
  {
190
373
  access_token: token,
@@ -213,7 +396,7 @@ async function upsertFileToGitee(ctx, owner, repo, path3, content, message, toke
213
396
  }
214
397
  const createUrl = `https://gitee.com/api/v5/repos/${owner}/${repo}/contents/${path3}`;
215
398
  try {
216
- const createResponse = await import_axios.default.post(
399
+ const createResponse = await import_axios2.default.post(
217
400
  createUrl,
218
401
  {
219
402
  access_token: token,
@@ -264,7 +447,7 @@ function generateXaml(summary, version) {
264
447
  <TextBlock
265
448
  Margin="${margin}"
266
449
  Foreground="{DynamicResource ColorBrush1}"
267
- Text="- ${msg}" />`;
450
+ Text="- ${(0, import_autocorrect_node.format)(msg)}" />`;
268
451
  }
269
452
  for (let j = 0; j < subcategories.length; j++) {
270
453
  const sub = subcategories[j];
@@ -281,7 +464,7 @@ function generateXaml(summary, version) {
281
464
  <TextBlock
282
465
  ${margin}
283
466
  Foreground="{DynamicResource ColorBrush1}"
284
- Text=" - ${msg}" />`;
467
+ Text=" - ${(0, import_autocorrect_node.format)(msg)}" />`;
285
468
  }
286
469
  if (j < subcategories.length - 1) {
287
470
  contentXaml += `
@@ -389,10 +572,7 @@ async function exportXaml(ctx, cfg, summary, version) {
389
572
  "master"
390
573
  ).then((result) => {
391
574
  if (result.success) {
392
- ctx.logger("minecraft-notifier").info(
393
- "Upsert successful:",
394
- result.data?.data
395
- );
575
+ ctx.logger("minecraft-notifier").info("Upsert successful");
396
576
  } else {
397
577
  ctx.logger("minecraft-notifier").warn(
398
578
  "Upsert failed:",
@@ -462,7 +642,8 @@ async function checkVersionUpdate(ctx, cfg, articleRecord, notifierRecord, versi
462
642
  if (success) {
463
643
  await updateArticleRecord(ctx, {
464
644
  [versionKey]: newVersion,
465
- [tryTimeKey]: 0
645
+ [tryTimeKey]: 0,
646
+ latestVersion: newVersion
466
647
  });
467
648
  return true;
468
649
  }
@@ -470,7 +651,8 @@ async function checkVersionUpdate(ctx, cfg, articleRecord, notifierRecord, versi
470
651
  if (newTryTime >= 5) {
471
652
  await updateArticleRecord(ctx, {
472
653
  [versionKey]: newVersion,
473
- [tryTimeKey]: 0
654
+ [tryTimeKey]: 0,
655
+ latestVersion: newVersion
474
656
  });
475
657
  } else {
476
658
  await updateArticleRecord(ctx, {
@@ -509,7 +691,7 @@ ${updateContent}
509
691
  `;
510
692
  let response;
511
693
  try {
512
- response = await import_axios2.default.post(
694
+ response = await import_axios3.default.post(
513
695
  url,
514
696
  {
515
697
  model: cfg.model,
@@ -518,7 +700,10 @@ ${updateContent}
518
700
  messages: [
519
701
  {
520
702
  role: "system",
521
- content: systemPrompt
703
+ content: await getSustemPrompt(
704
+ ctx,
705
+ updateContent.toLowerCase()
706
+ )
522
707
  },
523
708
  {
524
709
  role: "user",
@@ -634,7 +819,7 @@ ${updateContent}
634
819
  if (general.length === 0 && subcategories.length === 0) continue;
635
820
  const categoryTitle = `\u3010${minecraftSummaryTypeMap[category]}\u3011`;
636
821
  if (general.length > 0) {
637
- const generalList = general.map((msg) => `- ${msg}`).join("\n");
822
+ const generalList = general.map((msg) => `- ${(0, import_autocorrect_node2.format)(msg)}`).join("\n");
638
823
  messages.push(
639
824
  createBotTextMsgNode(
640
825
  ctx.bots[0],
@@ -647,7 +832,7 @@ ${generalList}`
647
832
  }
648
833
  for (const sub of subcategories) {
649
834
  const subHeader = `${sub.emoji} ${sub.subcategory}`;
650
- const subList = sub.items.map((msg) => `- ${msg}`).join("\n");
835
+ const subList = sub.items.map((msg) => `- ${(0, import_autocorrect_node2.format)(msg)}`).join("\n");
651
836
  messages.push(
652
837
  createBotTextMsgNode(ctx.bots[0], `${subHeader}
653
838
  ${subList}`)
@@ -693,14 +878,14 @@ var turndownService = new import_turndown.default({});
693
878
  async function fetchArticleContent(ctx, version, isSnapshot) {
694
879
  const url = generateArticleUrl(version, isSnapshot);
695
880
  try {
696
- const response = await import_axios2.default.get(url, {
881
+ const response = await import_axios3.default.get(url, {
697
882
  timeout: 1e4,
698
883
  headers: {
699
884
  "User-Agent": getRandomUserAgent()
700
885
  }
701
886
  });
702
887
  const html = response.data;
703
- const $ = cheerio.load(html);
888
+ const $ = cheerio2.load(html);
704
889
  const content = $("div.article-text").html().trim();
705
890
  return turndownService.turndown(content.trim());
706
891
  } catch (error) {
@@ -746,7 +931,8 @@ function apply(ctx, cfg) {
746
931
  lastRelease: "string",
747
932
  lastSnapshot: "string",
748
933
  releaseTryTime: "integer",
749
- snapshotTryTime: "integer"
934
+ snapshotTryTime: "integer",
935
+ latestVersion: "string"
750
936
  },
751
937
  { primary: "id" }
752
938
  );
@@ -779,7 +965,7 @@ function apply(ctx, cfg) {
779
965
  let retries = 0;
780
966
  while (retries <= 3) {
781
967
  try {
782
- const response = await import_axios3.default.get(
968
+ const response = await import_axios4.default.get(
783
969
  "https://launchermeta.mojang.com/mc/game/version_manifest.json",
784
970
  {
785
971
  timeout: 1e4
@@ -818,18 +1004,16 @@ function apply(ctx, cfg) {
818
1004
  let fullHomePagePath = import_node_path2.default.join(xamlPath, "PCL.HomePage.xaml");
819
1005
  koaCtx.response.body = await import_node_fs2.promises.readFile(fullHomePagePath);
820
1006
  });
821
- ctx.command("test").action(async ({ session }) => {
822
- await upsertFileToGitee(
823
- ctx,
824
- "pynickle",
825
- "PCL-AI-Summary-HomePage",
826
- "Custom.xaml",
827
- "111",
828
- `feat: update PCL HomePage XAML for version 111`,
829
- "c8629ca06822133e7d8b497c6e71cc7a",
830
- "master"
831
- );
1007
+ ctx.server.get("/Custom.xaml.ini", async (koaCtx) => {
1008
+ koaCtx.set("charset=utf-8");
1009
+ const articleRecord = (await ctx.database.get("minecraft_article_version", 1))[0];
1010
+ koaCtx.response.body = articleRecord.latestVersion;
832
1011
  });
1012
+ ctx.command("mc.trigger", "\u624B\u52A8\u89E6\u53D1 AI \u66F4\u65B0\u65E5\u5FD7\u603B\u7ED3\u751F\u6210").action(
1013
+ async () => {
1014
+ await checkNewVersionArticle(ctx, cfg);
1015
+ }
1016
+ );
833
1017
  ctx.setInterval(async () => {
834
1018
  try {
835
1019
  await loadData();
package/lib/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export interface ArticleLatestVersion {
12
12
  lastSnapshot: string;
13
13
  releaseTryTime: number;
14
14
  snapshotTryTime: number;
15
+ latestVersion: string;
15
16
  }
16
17
  export interface ArticleRecord {
17
18
  id: number;
@@ -1 +1,2 @@
1
- export declare const systemPrompt = "\nYou are a professional Minecraft changelog summarizer.\nAnalyze the given update notes and return a **structured JSON** following the provided schema.\nEach top-level category (new_features, improvements, balancing, bug_fixes, technical_changes) may include:\n* `\"general\"`: a list of general updates directly under the main category.\n* `\"subcategories\"`: a list of subcategories, each containing:\n * `\"subcategory\"`: a concise name (in Chinese).\n * `\"emoji\"`: one emoji that visually represents this subcategory. Ensure variety across different subcategories.\n * `\"items\"`: detailed update entries related to that subcategory.\nRules:\n1. **Write in fluent Chinese.** Avoid English unless it\u2019s an untranslatable proper name.\n2. **Keep entries concise:** Each item in 'general' or 'items' is one short sentence (50-100 characters max) to fit group chat messages. Merge similar updates if possible.\n3. **Group logically:** Use subcategories for clustered changes; only 2-5 subcategories per category.\n4. **Ignore trivial, internal, or repeated changes.**\n5. **Do not return any extra text outside the JSON.**\n6. **Ensure every subcategory has a distinct emoji.**\n7. **Insert a single space between any adjacent characters from different categories\u2014Chinese (\u6C49\u5B57), English (letters), or numbers (digits)\u2014without adding extra spaces, punctuation changes, or other edits.**\n";
1
+ import { Context } from 'koishi';
2
+ export declare function getSustemPrompt(ctx: Context, searchStr: string): Promise<string>;
@@ -0,0 +1,2 @@
1
+ import { Context } from 'koishi';
2
+ export declare function extractTranslations(ctx: Context, searchStr: string): Promise<string>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-minecraft-notifier",
3
3
  "description": "A Minecraft new version notification plugin, also featuring a PCL homepage.",
4
- "version": "1.3.1",
4
+ "version": "1.5.0",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",
@@ -45,6 +45,7 @@
45
45
  "typescript-eslint": "^8.46.2"
46
46
  },
47
47
  "dependencies": {
48
+ "autocorrect-node": "^2.14.0",
48
49
  "axios": "^1.12.2",
49
50
  "cheerio": "^1.1.2",
50
51
  "turndown": "^7.2.2"