clawflowbang 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.
@@ -0,0 +1,400 @@
1
+ /**
2
+ * Registry - จัดการ package registry
3
+ * ทั้ง built-in, npm registry และ remote registry
4
+ */
5
+
6
+ const path = require('path');
7
+ const axios = require('axios');
8
+ const NPMRegistry = require('./NPMRegistry');
9
+
10
+ class Registry {
11
+ constructor(configManager) {
12
+ this.configManager = configManager;
13
+ this.packages = new Map();
14
+ this.npmRegistry = new NPMRegistry();
15
+ this.npmCacheDir = path.join(configManager.getConfigPath(), 'npm-cache');
16
+ this.loadBuiltinPackages();
17
+ }
18
+
19
+ /**
20
+ * โหลด built-in packages
21
+ */
22
+ loadBuiltinPackages() {
23
+ // Built-in package definitions
24
+ const builtins = {
25
+ 'trading-kit': {
26
+ name: 'trading-kit',
27
+ version: '1.0.0',
28
+ description: 'ชุดเครื่องมือสำหรับเทรดคริปโต รวม skills และ cronjobs',
29
+ author: 'ClawFlow',
30
+ skills: [
31
+ { name: 'binance-pro', version: '^1.0.0', source: 'openclaw' },
32
+ { name: 'crypto-price', version: '^1.0.0', source: 'openclaw' },
33
+ { name: 'trading-research', version: '^1.0.0', source: 'openclaw' },
34
+ ],
35
+ crons: [
36
+ {
37
+ skill: 'crypto-price',
38
+ schedule: '*/5 * * * *',
39
+ params: { symbols: ['BTC', 'ETH', 'SOL'] },
40
+ description: 'เช็คราคาคริปโตทุก 5 นาที',
41
+ },
42
+ {
43
+ skill: 'binance-pro',
44
+ schedule: '0 */1 * * *',
45
+ params: { action: 'sync_balance' },
46
+ description: 'Sync balance ทุกชั่วโมง',
47
+ },
48
+ ],
49
+ config: {
50
+ 'binance-pro': {
51
+ apiKey: { env: 'BINANCE_API_KEY', required: true },
52
+ secretKey: { env: 'BINANCE_SECRET_KEY', required: true },
53
+ },
54
+ 'crypto-price': {
55
+ provider: 'binance',
56
+ defaultCurrency: 'USDT',
57
+ },
58
+ },
59
+ postInstall: 'ทำการตั้งค่า API Key สำหรับ Binance ใน config',
60
+ },
61
+ 'social-media-kit': {
62
+ name: 'social-media-kit',
63
+ version: '1.0.0',
64
+ description: 'จัดการโพสต์ Social Media แบบอัตโนมัติ',
65
+ author: 'ClawFlow',
66
+ skills: [
67
+ { name: 'facebook-poster', version: '^1.0.0', source: 'openclaw' },
68
+ { name: 'twitter-poster', version: '^1.0.0', source: 'openclaw' },
69
+ { name: 'content-generator', version: '^1.0.0', source: 'openclaw' },
70
+ ],
71
+ crons: [
72
+ {
73
+ skill: 'content-generator',
74
+ schedule: '0 9 * * *',
75
+ params: { type: 'daily_post' },
76
+ description: 'สร้าง content ทุกเช้า 9 โมง',
77
+ },
78
+ {
79
+ skill: 'facebook-poster',
80
+ schedule: '0 10,14,18 * * *',
81
+ params: { autoSchedule: true },
82
+ description: 'โพสต์ Facebook วันละ 3 ครั้ง',
83
+ },
84
+ ],
85
+ config: {
86
+ 'facebook-poster': {
87
+ pageId: { required: true },
88
+ accessToken: { env: 'FB_ACCESS_TOKEN', required: true },
89
+ },
90
+ 'twitter-poster': {
91
+ apiKey: { env: 'TWITTER_API_KEY', required: true },
92
+ apiSecret: { env: 'TWITTER_API_SECRET', required: true },
93
+ },
94
+ },
95
+ },
96
+ 'monitoring-kit': {
97
+ name: 'monitoring-kit',
98
+ version: '1.0.0',
99
+ description: 'ระบบตรวจสอบและแจ้งเตือน',
100
+ author: 'ClawFlow',
101
+ skills: [
102
+ { name: 'uptime-checker', version: '^1.0.0', source: 'openclaw' },
103
+ { name: 'discord-notifier', version: '^1.0.0', source: 'openclaw' },
104
+ { name: 'log-analyzer', version: '^1.0.0', source: 'openclaw' },
105
+ ],
106
+ crons: [
107
+ {
108
+ skill: 'uptime-checker',
109
+ schedule: '* * * * *',
110
+ params: { urls: [] },
111
+ description: 'เช็ค uptime ทุกนาที',
112
+ },
113
+ {
114
+ skill: 'log-analyzer',
115
+ schedule: '0 */6 * * *',
116
+ params: { reportType: 'summary' },
117
+ description: 'วิเคราะห์ log ทุก 6 ชั่วโมง',
118
+ },
119
+ ],
120
+ config: {
121
+ 'uptime-checker': {
122
+ urls: { required: true, type: 'array' },
123
+ timeout: { default: 5000 },
124
+ },
125
+ 'discord-notifier': {
126
+ webhookUrl: { env: 'DISCORD_WEBHOOK', required: true },
127
+ },
128
+ },
129
+ },
130
+ 'data-sync-kit': {
131
+ name: 'data-sync-kit',
132
+ version: '1.0.0',
133
+ description: 'ซิงค์ข้อมูลระหว่างระบบต่างๆ',
134
+ author: 'ClawFlow',
135
+ skills: [
136
+ { name: 'gsheet-sync', version: '^1.0.0', source: 'openclaw' },
137
+ { name: 'notion-sync', version: '^1.0.0', source: 'openclaw' },
138
+ { name: 'db-backup', version: '^1.0.0', source: 'openclaw' },
139
+ ],
140
+ crons: [
141
+ {
142
+ skill: 'db-backup',
143
+ schedule: '0 2 * * *',
144
+ params: { compress: true },
145
+ description: 'Backup database ตี 2 ทุกวัน',
146
+ },
147
+ {
148
+ skill: 'gsheet-sync',
149
+ schedule: '0 */4 * * *',
150
+ params: { mode: 'incremental' },
151
+ description: 'Sync Google Sheets ทุก 4 ชั่วโมง',
152
+ },
153
+ ],
154
+ config: {
155
+ 'gsheet-sync': {
156
+ credentials: { env: 'GOOGLE_CREDENTIALS', required: true },
157
+ sheetId: { required: true },
158
+ },
159
+ 'notion-sync': {
160
+ token: { env: 'NOTION_TOKEN', required: true },
161
+ databaseId: { required: true },
162
+ },
163
+ },
164
+ },
165
+ };
166
+
167
+ Object.entries(builtins).forEach(([name, pkg]) => {
168
+ this.packages.set(name, pkg);
169
+ });
170
+ }
171
+
172
+ /**
173
+ * ดึงข้อมูล package
174
+ * ลองหาจาก built-in ก่อน ถ้าไม่มีจะไปดึงจาก npm
175
+ */
176
+ async getPackage(name, options = {}) {
177
+ const { fetchFromNpm = true } = options;
178
+
179
+ // 1. ตรวจสอบใน built-in packages ก่อน
180
+ if (this.packages.has(name)) {
181
+ return this.packages.get(name);
182
+ }
183
+
184
+ // 2. ตรวจสอบใน npm registry (ถ้า enable)
185
+ if (fetchFromNpm) {
186
+ try {
187
+ const npmPkg = await this.npmRegistry.getPackage(name);
188
+ if (npmPkg && this.npmRegistry.isClawFlowPackage({ name, keywords: npmPkg.keywords })) {
189
+ return npmPkg;
190
+ }
191
+ } catch (error) {
192
+ // ถ้า fetch ไม่สำเร็จ ให้ return null
193
+ console.warn(`Failed to fetch ${name} from npm:`, error.message);
194
+ }
195
+ }
196
+
197
+ return null;
198
+ }
199
+
200
+ /**
201
+ * ดึงรายการ packages ที่มีให้ติดตั้ง
202
+ * รวมทั้ง built-in และจาก npm registry
203
+ */
204
+ async getAvailablePackages(options = {}) {
205
+ const { includeNpm = true, limit = 100 } = options;
206
+
207
+ // 1. Built-in packages
208
+ const packages = Array.from(this.packages.values()).map((pkg) => ({
209
+ name: pkg.name,
210
+ version: pkg.version,
211
+ description: pkg.description,
212
+ author: pkg.author,
213
+ skills: pkg.skills?.length || 0,
214
+ crons: pkg.crons?.length || 0,
215
+ source: 'builtin',
216
+ }));
217
+
218
+ // 2. NPM packages (ถ้า enable)
219
+ if (includeNpm) {
220
+ try {
221
+ const npmPackages = await this.npmRegistry.getPopularPackages(limit);
222
+ for (const pkg of npmPackages) {
223
+ // ไม่ add ถ้าชื่อซ้ำกับ builtin
224
+ if (!this.packages.has(pkg.name)) {
225
+ packages.push({
226
+ name: pkg.name,
227
+ version: pkg.version,
228
+ description: pkg.description,
229
+ author: pkg.author,
230
+ skills: pkg.skills?.length || 0,
231
+ crons: pkg.crons?.length || 0,
232
+ source: 'npm',
233
+ });
234
+ }
235
+ }
236
+ } catch (error) {
237
+ console.warn('Failed to fetch npm packages:', error.message);
238
+ }
239
+ }
240
+
241
+ return packages;
242
+ }
243
+
244
+ /**
245
+ * ดึงรายการ packages ที่ติดตั้งแล้ว
246
+ */
247
+ getInstalledPackages() {
248
+ return this.configManager.getInstalledPackages();
249
+ }
250
+
251
+ /**
252
+ * ค้นหา package
253
+ * ค้นหาทั้งใน built-in และ npm registry
254
+ */
255
+ async searchPackages(query, options = {}) {
256
+ const { includeNpm = true, limit = 50 } = options;
257
+ const results = [];
258
+ const seen = new Set();
259
+
260
+ // 1. ค้นหาใน built-in packages
261
+ for (const [name, pkg] of this.packages) {
262
+ if (
263
+ name.includes(query) ||
264
+ pkg.description?.includes(query) ||
265
+ pkg.skills?.some((s) => s.name?.includes(query))
266
+ ) {
267
+ results.push({ ...pkg, source: 'builtin' });
268
+ seen.add(name);
269
+ }
270
+ }
271
+
272
+ // 2. ค้นหาใน npm registry (ถ้า enable)
273
+ if (includeNpm) {
274
+ try {
275
+ const npmResults = await this.npmRegistry.searchClawFlowPackages(query);
276
+ for (const pkg of npmResults) {
277
+ if (!seen.has(pkg.name)) {
278
+ results.push({ ...pkg, source: 'npm' });
279
+ seen.add(pkg.name);
280
+ }
281
+ }
282
+ } catch (error) {
283
+ console.warn('Failed to search npm packages:', error.message);
284
+ }
285
+ }
286
+
287
+ return results.slice(0, limit);
288
+ }
289
+
290
+ /**
291
+ * ตรวจสอบว่า package มีอยู่หรือไม่
292
+ * ตรวจสอบทั้ง built-in และ npm
293
+ */
294
+ async hasPackage(name, options = {}) {
295
+ const { checkNpm = true } = options;
296
+
297
+ // 1. ตรวจสอบ built-in
298
+ if (this.packages.has(name)) {
299
+ return true;
300
+ }
301
+
302
+ // 2. ตรวจสอบ npm (ถ้า enable)
303
+ if (checkNpm) {
304
+ try {
305
+ const npmPkg = await this.npmRegistry.getPackage(name);
306
+ return npmPkg !== null;
307
+ } catch {
308
+ return false;
309
+ }
310
+ }
311
+
312
+ return false;
313
+ }
314
+
315
+ /**
316
+ * ดึง dependencies ของ package
317
+ */
318
+ getDependencies(name) {
319
+ const pkg = this.getPackage(name);
320
+ if (!pkg) return [];
321
+ return pkg.skills.map(s => s.name);
322
+ }
323
+
324
+ /**
325
+ * โหลด package จาก remote registry (legacy)
326
+ */
327
+ async fetchRemotePackage(name) {
328
+ const config = this.configManager.getConfig();
329
+ const registryUrl = config.registry?.url;
330
+
331
+ if (!registryUrl) {
332
+ return null;
333
+ }
334
+
335
+ try {
336
+ const response = await axios.get(`${registryUrl}/packages/${name}`);
337
+ return response.data;
338
+ } catch (error) {
339
+ return null;
340
+ }
341
+ }
342
+
343
+ /**
344
+ * ดึงรายการ npm packages ยอดนิยม
345
+ */
346
+ async getNpmPopularPackages(limit = 20) {
347
+ return this.npmRegistry.getPopularPackages(limit);
348
+ }
349
+
350
+ /**
351
+ * ดึงข้อมูล package จาก npm โดยตรง
352
+ */
353
+ async getNpmPackage(name, version = 'latest') {
354
+ return this.npmRegistry.getPackage(name, version);
355
+ }
356
+
357
+ /**
358
+ * ตรวจสอบว่าเป็น npm package หรือไม่
359
+ */
360
+ isNpmPackage(name) {
361
+ return name.startsWith('@') || name.includes('/');
362
+ }
363
+
364
+ /**
365
+ * ล้าง npm cache
366
+ */
367
+ clearNpmCache() {
368
+ this.npmRegistry.clearCache();
369
+ }
370
+
371
+ /**
372
+ * ดึง versions ทั้งหมดของ package จาก npm
373
+ */
374
+ async getPackageVersions(name) {
375
+ const manifest = await this.npmRegistry.getPackageManifest(name);
376
+ if (!manifest) return [];
377
+
378
+ return Object.keys(manifest.versions || {}).sort((a, b) => {
379
+ // Sort by semver (latest first)
380
+ const semver = require('semver');
381
+ return semver.rcompare(a, b);
382
+ });
383
+ }
384
+
385
+ /**
386
+ * Resolve package name ที่อาจมี version specifier
387
+ * เช่น "trading-kit@^1.0.0" -> { name: "trading-kit", version: "^1.0.0" }
388
+ */
389
+ parsePackageSpecifier(spec) {
390
+ const match = spec.match(/^(@?[^@]+)(?:@(.+))?$/);
391
+ if (!match) return null;
392
+
393
+ return {
394
+ name: match[1],
395
+ version: match[2] || 'latest',
396
+ };
397
+ }
398
+ }
399
+
400
+ module.exports = Registry;
package/src/index.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * ClawFlow - Core Module
3
+ *
4
+ * Skill + Cron Installer for OpenClaw
5
+ * ติดตั้ง skill พร้อมตั้งค่าใช้งานทันที
6
+ */
7
+
8
+ const ConfigManager = require('./core/ConfigManager');
9
+ const Registry = require('./core/Registry');
10
+ const Installer = require('./core/Installer');
11
+ const CronManager = require('./core/CronManager');
12
+ const PackageResolver = require('./core/PackageResolver');
13
+
14
+ class ClawFlow {
15
+ constructor(options = {}) {
16
+ this.config = new ConfigManager(options.configPath, {
17
+ skillsPath: options.skillsPath,
18
+ cronJobsFile: options.cronJobsFile,
19
+ openclawBin: options.openclawBin,
20
+ clawhubBin: options.clawhubBin,
21
+ });
22
+ this.registry = new Registry(this.config);
23
+ this.installer = new Installer(this.config, this.registry);
24
+ this.cronManager = new CronManager(this.config);
25
+ this.installer.setCronManager(this.cronManager);
26
+ this.resolver = new PackageResolver(this.registry);
27
+ }
28
+
29
+ /**
30
+ * ติดตั้ง package พร้อม skills และ cronjobs
31
+ */
32
+ async install(packageName, options = {}) {
33
+ return this.installer.install(packageName, options);
34
+ }
35
+
36
+ /**
37
+ * ถอนการติดตั้ง package
38
+ */
39
+ async remove(packageName, options = {}) {
40
+ return this.installer.remove(packageName, options);
41
+ }
42
+
43
+ /**
44
+ * แสดงรายการ packages ที่ติดตั้ง
45
+ */
46
+ async listInstalled() {
47
+ return this.registry.getInstalledPackages();
48
+ }
49
+
50
+ /**
51
+ * แสดงรายการ packages ที่พร้อมติดตั้ง
52
+ */
53
+ async listAvailable() {
54
+ return this.registry.getAvailablePackages();
55
+ }
56
+
57
+ /**
58
+ * เพิ่ม cronjob
59
+ */
60
+ async addCron(skillName, schedule, params = {}) {
61
+ return this.cronManager.add(skillName, schedule, params);
62
+ }
63
+
64
+ /**
65
+ * ลบ cronjob
66
+ */
67
+ async removeCron(cronId) {
68
+ return this.cronManager.remove(cronId);
69
+ }
70
+
71
+ /**
72
+ * แสดงรายการ cronjobs
73
+ */
74
+ async listCrons() {
75
+ return this.cronManager.list();
76
+ }
77
+
78
+ /**
79
+ * แสดงสถานะระบบ
80
+ */
81
+ async getStatus() {
82
+ return {
83
+ version: require('../package.json').version,
84
+ config: this.config.getConfigPath(),
85
+ installed: await this.listInstalled(),
86
+ crons: await this.listCrons(),
87
+ };
88
+ }
89
+ }
90
+
91
+ module.exports = ClawFlow;