openclaw-github-trending 1.0.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +480 -0
  3. package/dist/channels/email.d.ts +61 -0
  4. package/dist/channels/email.d.ts.map +1 -0
  5. package/dist/channels/email.js +599 -0
  6. package/dist/channels/email.js.map +1 -0
  7. package/dist/channels/feishu.d.ts +50 -0
  8. package/dist/channels/feishu.d.ts.map +1 -0
  9. package/dist/channels/feishu.js +322 -0
  10. package/dist/channels/feishu.js.map +1 -0
  11. package/dist/channels/types.d.ts +66 -0
  12. package/dist/channels/types.d.ts.map +1 -0
  13. package/dist/channels/types.js +12 -0
  14. package/dist/channels/types.js.map +1 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/core/config.d.ts +83 -0
  19. package/dist/core/config.d.ts.map +1 -0
  20. package/dist/core/config.js +145 -0
  21. package/dist/core/config.js.map +1 -0
  22. package/dist/core/fetcher.d.ts +43 -0
  23. package/dist/core/fetcher.d.ts.map +1 -0
  24. package/dist/core/fetcher.js +306 -0
  25. package/dist/core/fetcher.js.map +1 -0
  26. package/dist/core/file-storage.d.ts +62 -0
  27. package/dist/core/file-storage.d.ts.map +1 -0
  28. package/dist/core/file-storage.js +253 -0
  29. package/dist/core/file-storage.js.map +1 -0
  30. package/dist/core/history.d.ts +71 -0
  31. package/dist/core/history.d.ts.map +1 -0
  32. package/dist/core/history.js +133 -0
  33. package/dist/core/history.js.map +1 -0
  34. package/dist/core/summarizer.d.ts +64 -0
  35. package/dist/core/summarizer.d.ts.map +1 -0
  36. package/dist/core/summarizer.js +324 -0
  37. package/dist/core/summarizer.js.map +1 -0
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +668 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/models/config.d.ts +93 -0
  43. package/dist/models/config.d.ts.map +1 -0
  44. package/dist/models/config.js +3 -0
  45. package/dist/models/config.js.map +1 -0
  46. package/dist/models/history.d.ts +6 -0
  47. package/dist/models/history.d.ts.map +1 -0
  48. package/dist/models/history.js +7 -0
  49. package/dist/models/history.js.map +1 -0
  50. package/dist/models/repository.d.ts +28 -0
  51. package/dist/models/repository.d.ts.map +1 -0
  52. package/dist/models/repository.js +3 -0
  53. package/dist/models/repository.js.map +1 -0
  54. package/dist/models/service.types.d.ts +87 -0
  55. package/dist/models/service.types.d.ts.map +1 -0
  56. package/dist/models/service.types.js +3 -0
  57. package/dist/models/service.types.js.map +1 -0
  58. package/dist/services/trending.service.d.ts +29 -0
  59. package/dist/services/trending.service.d.ts.map +1 -0
  60. package/dist/services/trending.service.js +306 -0
  61. package/dist/services/trending.service.js.map +1 -0
  62. package/dist/tool.d.ts +47 -0
  63. package/dist/tool.d.ts.map +1 -0
  64. package/dist/tool.js +314 -0
  65. package/dist/tool.js.map +1 -0
  66. package/dist/utils/logger.d.ts +77 -0
  67. package/dist/utils/logger.d.ts.map +1 -0
  68. package/dist/utils/logger.js +214 -0
  69. package/dist/utils/logger.js.map +1 -0
  70. package/dist/utils/markdown.d.ts +9 -0
  71. package/dist/utils/markdown.d.ts.map +1 -0
  72. package/dist/utils/markdown.js +40 -0
  73. package/dist/utils/markdown.js.map +1 -0
  74. package/openclaw.plugin.json +152 -0
  75. package/package.json +78 -0
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FeishuChannel = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const logger_1 = require("../utils/logger");
9
+ const logger = logger_1.Logger.get('FeishuChannel');
10
+ /**
11
+ * Feishu Channel for pushing GitHub trending repositories
12
+ */
13
+ class FeishuChannel {
14
+ /**
15
+ * Build Feishu card message
16
+ * @param newRepositories Array of new repositories to display
17
+ * @param seenRepositories Array of seen repositories to display
18
+ * @param since Time period for trending
19
+ * @returns Feishu card object
20
+ */
21
+ static buildCard(newRepositories, seenRepositories, since = 'monthly') {
22
+ const currentDate = new Date();
23
+ const dateStr = currentDate.toLocaleDateString('zh-CN', {
24
+ year: 'numeric',
25
+ month: 'long',
26
+ day: 'numeric',
27
+ weekday: 'long'
28
+ });
29
+ const sinceTextMap = {
30
+ daily: '今日',
31
+ weekly: '本周',
32
+ monthly: '本月'
33
+ };
34
+ const sinceText = sinceTextMap[since];
35
+ const elements = [];
36
+ // 新上榜项目
37
+ if (newRepositories.length > 0) {
38
+ elements.push({
39
+ tag: 'div',
40
+ text: {
41
+ content: '**🔥 新上榜项目**',
42
+ tag: 'lark_md'
43
+ }
44
+ });
45
+ elements.push({
46
+ tag: 'hr'
47
+ });
48
+ newRepositories.forEach((repo, index) => {
49
+ const repoElements = FeishuChannel.buildRepoElement(repo, index, true);
50
+ // 如果是最后一个项目,移除分割线
51
+ if (index === newRepositories.length - 1) {
52
+ repoElements.pop();
53
+ }
54
+ elements.push(...repoElements);
55
+ });
56
+ }
57
+ // 持续霸榜项目
58
+ if (seenRepositories.length > 0) {
59
+ if (newRepositories.length > 0) {
60
+ elements.push({
61
+ tag: 'div',
62
+ text: {
63
+ content: ' ',
64
+ tag: 'lark_md'
65
+ }
66
+ });
67
+ }
68
+ elements.push({
69
+ tag: 'div',
70
+ text: {
71
+ content: '**⭐ 持续霸榜项目**',
72
+ tag: 'lark_md'
73
+ }
74
+ });
75
+ elements.push({
76
+ tag: 'hr'
77
+ });
78
+ seenRepositories.forEach((repo, index) => {
79
+ const repoElements = FeishuChannel.buildRepoElement(repo, index, false);
80
+ // 如果是最后一个项目,移除分割线
81
+ if (index === seenRepositories.length - 1) {
82
+ repoElements.pop();
83
+ }
84
+ elements.push(...repoElements);
85
+ });
86
+ }
87
+ // 如果没有项目
88
+ if (newRepositories.length === 0 && seenRepositories.length === 0) {
89
+ elements.push({
90
+ tag: 'div',
91
+ text: {
92
+ content: '📌 暂无 trending 项目',
93
+ tag: 'lark_md'
94
+ }
95
+ });
96
+ }
97
+ return {
98
+ config: {
99
+ wide_screen_mode: true
100
+ },
101
+ header: {
102
+ title: {
103
+ tag: 'plain_text',
104
+ content: `GitHub ${sinceText}热榜推送`
105
+ },
106
+ template: 'blue'
107
+ },
108
+ elements: elements
109
+ };
110
+ }
111
+ /**
112
+ * Build a single repository card element
113
+ * @param repo Repository information
114
+ * @param index Index of repository
115
+ * @param isNew Whether this is a new repository
116
+ * @returns Feishu card element array
117
+ */
118
+ static buildRepoElement(repo, index, isNew) {
119
+ const formattedStars = FeishuChannel.formatNumberWithK(repo.stars);
120
+ const formattedForks = repo.forks
121
+ ? ` ⚡${FeishuChannel.formatNumberWithK(repo.forks)}`
122
+ : '';
123
+ // 语言显示:emoji + 语言名
124
+ const languageText = repo.language
125
+ ? ` ${FeishuChannel.getLanguageEmoji(repo.language)} ${repo.language}`
126
+ : '';
127
+ // 项目基本信息
128
+ const repoInfo = `**${index + 1}. [${repo.full_name}](${repo.url})**\n★${formattedStars}${formattedForks}${languageText}`;
129
+ // 新上榜项目:显示完整项目介绍
130
+ // 持续霸榜项目:显示简化介绍
131
+ const summaryText = isNew
132
+ ? (repo.ai_summary
133
+ ? `\n\n**🤖 项目介绍:**\n${repo.ai_summary}`
134
+ : '')
135
+ : (repo.ai_summary
136
+ ? `\n\n${repo.ai_summary.split('。')[0]}。`
137
+ : '');
138
+ const elements = [];
139
+ // 项目内容
140
+ elements.push({
141
+ tag: 'div',
142
+ text: {
143
+ content: `${repoInfo}${summaryText}`,
144
+ tag: 'lark_md'
145
+ }
146
+ });
147
+ // 项目分割线(最后一个项目不加)
148
+ elements.push({
149
+ tag: 'hr'
150
+ });
151
+ return elements;
152
+ }
153
+ /**
154
+ * Get emoji icon for programming language
155
+ * @param language Programming language
156
+ * @returns Emoji icon
157
+ */
158
+ static getLanguageEmoji(language) {
159
+ const emojis = {
160
+ JavaScript: '💻',
161
+ TypeScript: '💻',
162
+ Python: '🐍',
163
+ Ruby: '💎',
164
+ Java: '☕',
165
+ Go: '🐹',
166
+ Rust: '🦀',
167
+ Swift: '🍎',
168
+ C: '⚙️',
169
+ 'C++': '⚙️',
170
+ 'C#': '🎮',
171
+ PHP: '🐘',
172
+ HTML: '🌐',
173
+ CSS: '🎨',
174
+ Shell: '🐚',
175
+ SQL: '🗃️',
176
+ Kotlin: '🦾',
177
+ Dart: '🎯',
178
+ Vue: '💚',
179
+ React: '⚛️',
180
+ Angular: '🅰️',
181
+ Node: '💚',
182
+ Scala: '🔴',
183
+ Elixir: '💧',
184
+ Haskell: 'λ',
185
+ Lua: '🌙',
186
+ R: '📊',
187
+ MATLAB: '🔢',
188
+ Julia: '💜'
189
+ };
190
+ return emojis[language] || '📝';
191
+ }
192
+ /**
193
+ * Get background color based on programming language
194
+ * @param language Programming language
195
+ * @returns Color code
196
+ */
197
+ static getLanguageColor(language) {
198
+ const colors = {
199
+ JavaScript: '#f1e05a',
200
+ TypeScript: '#3178c6',
201
+ Python: '#3572A5',
202
+ Ruby: '#701516',
203
+ Java: '#b07219',
204
+ Go: '#00ADD8',
205
+ Rust: '#dea584',
206
+ Swift: '#ffac45',
207
+ C: '#555555',
208
+ 'C++': '#f34b7d',
209
+ 'C#': '#178600',
210
+ PHP: '#8993bd',
211
+ HTML: '#e34c26',
212
+ CSS: '#563d7c',
213
+ Shell: '#89e051',
214
+ SQL: '#e38c00',
215
+ Kotlin: '#A97BFF',
216
+ Dart: '#00B4AB',
217
+ Vue: '#41b883',
218
+ React: '#61dafb',
219
+ Angular: '#dd1b16',
220
+ Node: '#68a063',
221
+ Scala: '#c22d40',
222
+ Elixir: '#6e4a7e',
223
+ Haskell: '#5e5086',
224
+ Lua: '#000080',
225
+ R: '#198ce7',
226
+ MATLAB: '#e16737',
227
+ Julia: '#a270ba'
228
+ };
229
+ return colors[language] || '#666666';
230
+ }
231
+ /**
232
+ * Format number with 'k' suffix for thousands
233
+ * @param num Number to format
234
+ * @returns Formatted string
235
+ */
236
+ static formatNumberWithK(num) {
237
+ if (num >= 1000) {
238
+ return (num / 1000).toFixed(1) + 'k';
239
+ }
240
+ return num.toString();
241
+ }
242
+ /**
243
+ * Push repositories to Feishu webhook
244
+ * @param newRepositories Array of new repositories
245
+ * @param seenRepositories Array of seen repositories
246
+ * @returns Push result
247
+ */
248
+ static async push(webhookUrl, newRepositories, seenRepositories, since = 'monthly') {
249
+ logger.info('Starting push', {
250
+ since,
251
+ newCount: newRepositories.length,
252
+ seenCount: seenRepositories.length,
253
+ webhookUrl: webhookUrl.replace(/\/\/(.*?)(@)/, '//***$2')
254
+ });
255
+ const card = FeishuChannel.buildCard(newRepositories, seenRepositories, since);
256
+ // 飞书卡片消息格式
257
+ const message = {
258
+ msg_type: 'interactive',
259
+ card: card
260
+ };
261
+ try {
262
+ logger.debug('Sending request to webhook...', {
263
+ messageSize: JSON.stringify(message).length
264
+ });
265
+ const startTime = Date.now();
266
+ const response = await axios_1.default.post(webhookUrl, message, {
267
+ headers: {
268
+ 'Content-Type': 'application/json'
269
+ }
270
+ });
271
+ const duration = Date.now() - startTime;
272
+ logger.info('Received response', {
273
+ status: response.status,
274
+ durationMs: duration,
275
+ responseData: response.data
276
+ });
277
+ if (response.status === 200 && response.data.code === 0) {
278
+ logger.success('Push successful', {
279
+ code: response.data.code,
280
+ message: response.data.msg
281
+ });
282
+ return {
283
+ success: true,
284
+ code: response.data.code,
285
+ msg: response.data.msg,
286
+ error: undefined
287
+ };
288
+ }
289
+ else {
290
+ logger.error('Push failed', {
291
+ status: response.status,
292
+ code: response.data.code,
293
+ message: response.data.msg
294
+ });
295
+ return {
296
+ success: false,
297
+ code: response.status,
298
+ error: `HTTP ${response.status}: ${response.statusText}, Code: ${response.data.code}, Message: ${response.data.msg}`
299
+ };
300
+ }
301
+ }
302
+ catch (error) {
303
+ logger.error('Request failed', {
304
+ error: error instanceof Error ? error.message : 'Unknown error',
305
+ stack: error instanceof Error ? error.stack : undefined
306
+ });
307
+ if (axios_1.default.isAxiosError(error)) {
308
+ return {
309
+ success: false,
310
+ error: `Axios error: ${error.message}, status: ${error.response?.status}, data: ${JSON.stringify(error.response?.data)}`
311
+ };
312
+ }
313
+ return {
314
+ success: false,
315
+ error: error instanceof Error ? error.message : 'Unknown error'
316
+ };
317
+ }
318
+ }
319
+ }
320
+ exports.FeishuChannel = FeishuChannel;
321
+ exports.default = FeishuChannel;
322
+ //# sourceMappingURL=feishu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu.js","sourceRoot":"","sources":["../../src/channels/feishu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Feishu card element interface
3
+ */
4
+ export interface FeishuCardElement {
5
+ tag?: string;
6
+ text?: {
7
+ content?: string;
8
+ tag?: string;
9
+ };
10
+ tag_name?: string;
11
+ href?: string;
12
+ img_key?: string;
13
+ elements?: FeishuCardElement[];
14
+ alt?: {
15
+ content?: string;
16
+ };
17
+ optional?: {
18
+ tag?: string;
19
+ text?: {
20
+ content?: string;
21
+ tag?: string;
22
+ };
23
+ };
24
+ required_content?: string;
25
+ multi_lang?: {
26
+ content?: string;
27
+ };
28
+ }
29
+ /**
30
+ * Feishu card header interface
31
+ */
32
+ export interface FeishuCardHeader {
33
+ title: {
34
+ tag: string;
35
+ content: string;
36
+ };
37
+ template?: string;
38
+ }
39
+ /**
40
+ * Feishu card interface
41
+ */
42
+ export interface FeishuCard {
43
+ config?: {
44
+ wide_screen_mode?: boolean;
45
+ };
46
+ header?: FeishuCardHeader;
47
+ elements?: FeishuCardElement[];
48
+ }
49
+ /**
50
+ * Push result interface
51
+ */
52
+ export interface PushResult {
53
+ success: boolean;
54
+ code?: number;
55
+ msg?: string;
56
+ messageId?: string;
57
+ error?: string;
58
+ }
59
+ /**
60
+ * Repository status enum
61
+ */
62
+ export declare enum RepositoryStatus {
63
+ NEW = "new",
64
+ SEEN = "seen"
65
+ }
66
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/channels/types.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE;YACL,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,GAAG,CAAC,EAAE,MAAM,CAAC;SACd,CAAC;KACH,CAAC;IACF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE;QACX,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE;QACP,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,oBAAY,gBAAgB;IAC1B,GAAG,QAAQ;IACX,IAAI,SAAS;CACd"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RepositoryStatus = void 0;
4
+ /**
5
+ * Repository status enum
6
+ */
7
+ var RepositoryStatus;
8
+ (function (RepositoryStatus) {
9
+ RepositoryStatus["NEW"] = "new";
10
+ RepositoryStatus["SEEN"] = "seen";
11
+ })(RepositoryStatus || (exports.RepositoryStatus = RepositoryStatus = {}));
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/channels/types.ts"],"names":[],"mappings":";;;AAgEA;;GAEG;AACH,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,+BAAW,CAAA;IACX,iCAAa,CAAA;AACf,CAAC,EAHW,gBAAgB,gCAAhB,gBAAgB,QAG3B"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { PluginConfig, ResolvedAIConfig } from '../models/config';
2
+ /**
3
+ * Plugin entry configuration
4
+ */
5
+ export interface PluginEntryConfig {
6
+ enabled?: boolean;
7
+ config?: Record<string, unknown>;
8
+ }
9
+ /**
10
+ * Plugins configuration
11
+ */
12
+ export interface PluginsConfig {
13
+ enabled?: boolean;
14
+ allow?: string[];
15
+ deny?: string[];
16
+ entries?: Record<string, PluginEntryConfig>;
17
+ }
18
+ /**
19
+ * OpenClaw global configuration structure
20
+ * Based on OpenClaw's actual config schema
21
+ */
22
+ export interface OpenClawGlobalConfig {
23
+ agents?: {
24
+ defaults?: {
25
+ model?: string | {
26
+ primary?: string;
27
+ secondary?: string;
28
+ };
29
+ workspace?: string;
30
+ };
31
+ };
32
+ models?: {
33
+ providers?: Record<string, {
34
+ baseUrl?: string;
35
+ apiKey?: string;
36
+ api?: string;
37
+ models?: Array<{
38
+ id: string;
39
+ name?: string;
40
+ }>;
41
+ }>;
42
+ };
43
+ plugins?: PluginsConfig;
44
+ }
45
+ export interface SMTPConfig {
46
+ smtp_host: string;
47
+ smtp_port: number;
48
+ use_tls: boolean;
49
+ sender: string;
50
+ password: string;
51
+ from_name: string;
52
+ timeout?: number;
53
+ }
54
+ export declare class ConfigManager {
55
+ /**
56
+ * Parse OpenClaw's model string format "provider/model" (e.g., "openai-codex/gpt-4o")
57
+ * @param modelString Model string in "provider/model" format
58
+ * @returns Object with provider and model, or undefined if invalid
59
+ */
60
+ private static parseModelString;
61
+ /**
62
+ * Get AI configuration with proper fallback logic
63
+ * Priority: plugin config > OpenClaw global config > default values
64
+ *
65
+ * @param pluginConfig Plugin's own configuration
66
+ * @param openclawConfig OpenClaw's global configuration (from api.config)
67
+ * @returns Resolved AI configuration with all required fields
68
+ */
69
+ static getAIConfig(pluginConfig: PluginConfig | undefined, openclawConfig?: OpenClawGlobalConfig): ResolvedAIConfig;
70
+ /**
71
+ * Get max workers configuration
72
+ */
73
+ static getMaxWorkers(pluginConfig: PluginConfig | undefined): number;
74
+ /**
75
+ * Get GitHub token configuration
76
+ */
77
+ static getGitHubToken(pluginConfig: PluginConfig | undefined): string | undefined;
78
+ /**
79
+ * Detect email configuration from email address or use configured SMTP
80
+ */
81
+ static getEmailConfig(email: string, password: string, pluginEmailConfig?: any): SMTPConfig;
82
+ }
83
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE;YACT,KAAK,CAAC,EAAE,MAAM,GAAG;gBAAE,OAAO,CAAC,EAAE,MAAM,CAAC;gBAAC,SAAS,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB,CAAC;KACH,CAAC;IACF,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YACzB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,GAAG,CAAC,EAAE,MAAM,CAAC;YACb,MAAM,CAAC,EAAE,KAAK,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC/C,CAAC,CAAC;KACJ,CAAC;IACF,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAa;IACxB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAc/B;;;;;;;OAOG;IACH,MAAM,CAAC,WAAW,CAChB,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,cAAc,CAAC,EAAE,oBAAoB,GACpC,gBAAgB;IA6DnB;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM;IAIpE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,YAAY,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS;IAIjF;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,GAAG,GACtB,UAAU;CA0Dd"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigManager = void 0;
4
+ class ConfigManager {
5
+ /**
6
+ * Parse OpenClaw's model string format "provider/model" (e.g., "openai-codex/gpt-4o")
7
+ * @param modelString Model string in "provider/model" format
8
+ * @returns Object with provider and model, or undefined if invalid
9
+ */
10
+ static parseModelString(modelString) {
11
+ const trimmed = modelString.trim();
12
+ const slashIndex = trimmed.indexOf('/');
13
+ if (slashIndex === -1) {
14
+ return undefined;
15
+ }
16
+ const provider = trimmed.substring(0, slashIndex).trim();
17
+ const model = trimmed.substring(slashIndex + 1).trim();
18
+ return provider && model ? { provider, model } : undefined;
19
+ }
20
+ /**
21
+ * Get AI configuration with proper fallback logic
22
+ * Priority: plugin config > OpenClaw global config > default values
23
+ *
24
+ * @param pluginConfig Plugin's own configuration
25
+ * @param openclawConfig OpenClaw's global configuration (from api.config)
26
+ * @returns Resolved AI configuration with all required fields
27
+ */
28
+ static getAIConfig(pluginConfig, openclawConfig) {
29
+ // Priority 1: Plugin config (explicit user setting)
30
+ if (pluginConfig?.ai?.api_key) {
31
+ const provider = pluginConfig.ai.provider || 'openai';
32
+ const defaultBaseUrl = provider === 'anthropic'
33
+ ? 'https://api.anthropic.com'
34
+ : 'https://api.openai.com/v1';
35
+ return {
36
+ provider,
37
+ apiKey: pluginConfig.ai.api_key,
38
+ baseUrl: pluginConfig.ai.base_url || defaultBaseUrl,
39
+ model: pluginConfig.ai.model || (provider === 'anthropic' ? 'claude-3-5-sonnet-20241022' : 'gpt-4o-mini')
40
+ };
41
+ }
42
+ // Priority 2: OpenClaw global config (from api.config)
43
+ if (openclawConfig) {
44
+ const defaultsModel = openclawConfig.agents?.defaults?.model;
45
+ const primaryModel = typeof defaultsModel === 'string'
46
+ ? defaultsModel.trim()
47
+ : (defaultsModel?.primary?.trim() ?? undefined);
48
+ if (primaryModel) {
49
+ const parsed = this.parseModelString(primaryModel);
50
+ if (parsed) {
51
+ const { provider, model } = parsed;
52
+ const providerConfig = openclawConfig.models?.providers?.[provider];
53
+ if (providerConfig?.apiKey) {
54
+ // Determine provider type
55
+ const isAnthropic = providerConfig.api === 'anthropic-messages' ||
56
+ provider.toLowerCase().includes('anthropic');
57
+ const defaultBaseUrl = isAnthropic
58
+ ? 'https://api.anthropic.com'
59
+ : 'https://api.openai.com/v1';
60
+ return {
61
+ provider: isAnthropic ? 'anthropic' : 'openai',
62
+ apiKey: providerConfig.apiKey,
63
+ baseUrl: providerConfig.baseUrl || defaultBaseUrl,
64
+ model: model
65
+ };
66
+ }
67
+ }
68
+ }
69
+ }
70
+ // Priority 3: Return default config with empty API key (will cause error later if not configured)
71
+ // This allows the plugin to initialize even without AI config, and the error will be caught at usage time
72
+ const defaultProvider = 'openai';
73
+ return {
74
+ provider: defaultProvider,
75
+ apiKey: '', // Will cause error when actually used
76
+ baseUrl: 'https://api.openai.com/v1',
77
+ model: 'gpt-4o-mini'
78
+ };
79
+ }
80
+ /**
81
+ * Get max workers configuration
82
+ */
83
+ static getMaxWorkers(pluginConfig) {
84
+ return pluginConfig?.max_workers || 5;
85
+ }
86
+ /**
87
+ * Get GitHub token configuration
88
+ */
89
+ static getGitHubToken(pluginConfig) {
90
+ return pluginConfig?.github_token;
91
+ }
92
+ /**
93
+ * Detect email configuration from email address or use configured SMTP
94
+ */
95
+ static getEmailConfig(email, password, pluginEmailConfig) {
96
+ // If full SMTP config is provided, use it
97
+ if (pluginEmailConfig?.smtp_host) {
98
+ return {
99
+ smtp_host: pluginEmailConfig.smtp_host,
100
+ smtp_port: pluginEmailConfig.smtp_port || 587,
101
+ use_tls: pluginEmailConfig.use_tls ?? true,
102
+ sender: pluginEmailConfig.sender || email,
103
+ password: pluginEmailConfig.password || password,
104
+ from_name: pluginEmailConfig.from_name || 'GitHub Trending',
105
+ timeout: pluginEmailConfig.timeout || 30
106
+ };
107
+ }
108
+ // Otherwise, detect from email domain
109
+ const domain = email.split('@')[1];
110
+ const presets = {
111
+ 'qq.com': {
112
+ smtp_host: 'smtp.qq.com',
113
+ smtp_port: 587,
114
+ use_tls: true
115
+ },
116
+ '163.com': {
117
+ smtp_host: 'smtp.163.com',
118
+ smtp_port: 587,
119
+ use_tls: true
120
+ },
121
+ 'gmail.com': {
122
+ smtp_host: 'smtp.gmail.com',
123
+ smtp_port: 587,
124
+ use_tls: true
125
+ },
126
+ 'aliyun.com': {
127
+ smtp_host: 'smtp.aliyun.com',
128
+ smtp_port: 587,
129
+ use_tls: true
130
+ }
131
+ };
132
+ const preset = presets[domain] || presets['qq.com'];
133
+ return {
134
+ smtp_host: preset.smtp_host,
135
+ smtp_port: preset.smtp_port,
136
+ use_tls: preset.use_tls,
137
+ sender: email,
138
+ password: password,
139
+ from_name: 'GitHub Trending',
140
+ timeout: 30
141
+ };
142
+ }
143
+ }
144
+ exports.ConfigManager = ConfigManager;
145
+ //# sourceMappingURL=config.js.map