clawflowbang 1.0.1 → 1.1.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/README.md +164 -49
- package/bin/clawflowhub.js +150 -62
- package/package.json +17 -5
- package/src/commands/create.js +286 -0
- package/src/commands/cron.js +78 -18
- package/src/commands/doctor.js +146 -0
- package/src/commands/explore.js +49 -0
- package/src/commands/init.js +3 -3
- package/src/commands/register.js +83 -0
- package/src/commands/update.js +35 -0
- package/src/core/ConfigManager.js +132 -132
- package/src/core/CronManager.js +245 -245
- package/src/core/Installer.js +226 -109
- package/src/core/OpenClawCLI.js +52 -7
- package/src/core/TerminalUI.js +10 -13
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -23
- package/.github/pull_request_template.md +0 -19
- package/CODE_OF_CONDUCT.md +0 -29
- package/SECURITY.md +0 -20
- package/SUPPORT.md +0 -21
package/src/core/CronManager.js
CHANGED
|
@@ -3,46 +3,46 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const fs = require('fs-extra');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const cron = require('node-cron');
|
|
8
|
-
const chalk = require('chalk');
|
|
9
|
-
const OpenClawCLI = require('./OpenClawCLI');
|
|
10
|
-
const { normalizeCronExpression } = require('./CronFormat');
|
|
11
|
-
|
|
12
|
-
class CronManager {
|
|
13
|
-
constructor(configManager) {
|
|
14
|
-
this.configManager = configManager;
|
|
15
|
-
this.tasks = new Map();
|
|
16
|
-
this.jobsFile = configManager.getCronJobsFilePath();
|
|
17
|
-
this.openclawCLI = new OpenClawCLI(configManager);
|
|
18
|
-
this.useOpenClawCron = this.openclawCLI.hasOpenClaw();
|
|
19
|
-
|
|
20
|
-
if (!this.useOpenClawCron) {
|
|
21
|
-
this.ensureJobsFile();
|
|
22
|
-
}
|
|
23
|
-
}
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const cron = require('node-cron');
|
|
8
|
+
const chalk = require('chalk');
|
|
9
|
+
const OpenClawCLI = require('./OpenClawCLI');
|
|
10
|
+
const { normalizeCronExpression } = require('./CronFormat');
|
|
11
|
+
|
|
12
|
+
class CronManager {
|
|
13
|
+
constructor(configManager) {
|
|
14
|
+
this.configManager = configManager;
|
|
15
|
+
this.tasks = new Map();
|
|
16
|
+
this.jobsFile = configManager.getCronJobsFilePath();
|
|
17
|
+
this.openclawCLI = new OpenClawCLI(configManager);
|
|
18
|
+
this.useOpenClawCron = this.openclawCLI.hasOpenClaw();
|
|
19
|
+
|
|
20
|
+
if (!this.useOpenClawCron) {
|
|
21
|
+
this.ensureJobsFile();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* สร้างไฟล์ jobs ถ้ายังไม่มี
|
|
27
27
|
*/
|
|
28
|
-
ensureJobsFile() {
|
|
29
|
-
fs.ensureDirSync(path.dirname(this.jobsFile));
|
|
30
|
-
if (!fs.existsSync(this.jobsFile)) {
|
|
31
|
-
fs.writeJsonSync(this.jobsFile, { jobs: [] }, { spaces: 2 });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
28
|
+
ensureJobsFile() {
|
|
29
|
+
fs.ensureDirSync(path.dirname(this.jobsFile));
|
|
30
|
+
if (!fs.existsSync(this.jobsFile)) {
|
|
31
|
+
fs.writeJsonSync(this.jobsFile, { jobs: [] }, { spaces: 2 });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* อ่านรายการ jobs
|
|
37
37
|
*/
|
|
38
|
-
getJobs() {
|
|
39
|
-
if (!fs.existsSync(this.jobsFile)) {
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const data = fs.readJsonSync(this.jobsFile);
|
|
44
|
-
return data.jobs || [];
|
|
45
|
-
}
|
|
38
|
+
getJobs() {
|
|
39
|
+
if (!fs.existsSync(this.jobsFile)) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const data = fs.readJsonSync(this.jobsFile);
|
|
44
|
+
return data.jobs || [];
|
|
45
|
+
}
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* บันทึกรายการ jobs
|
|
@@ -54,76 +54,76 @@ class CronManager {
|
|
|
54
54
|
/**
|
|
55
55
|
* เพิ่ม cronjob
|
|
56
56
|
*/
|
|
57
|
-
async add(skillName, schedule, params = {}, description = '') {
|
|
58
|
-
const normalizedSchedule = normalizeCronExpression(schedule);
|
|
59
|
-
|
|
60
|
-
if (this.useOpenClawCron) {
|
|
61
|
-
const uniqueName = `cfh:${skillName}:${Date.now()}`;
|
|
62
|
-
const message = `Run skill
|
|
63
|
-
const created = await this.openclawCLI.addCronJob({
|
|
64
|
-
name: uniqueName,
|
|
65
|
-
description: description || `Run ${skillName}`,
|
|
66
|
-
schedule: normalizedSchedule,
|
|
67
|
-
message,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
let jobId = created.jobId;
|
|
71
|
-
if (!jobId) {
|
|
72
|
-
const jobs = await this.openclawCLI.listCronJobs();
|
|
73
|
-
const matched = jobs.find((job) => job.name === uniqueName);
|
|
74
|
-
jobId = matched?.id || null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (!jobId) {
|
|
78
|
-
throw new Error('สร้าง cronjob ผ่าน openclaw สำเร็จ แต่ไม่สามารถระบุ job id ได้');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
this.configManager.addCron({
|
|
82
|
-
id: jobId,
|
|
83
|
-
skill: skillName,
|
|
84
|
-
schedule: normalizedSchedule,
|
|
85
|
-
description: description || `Run ${skillName}`,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
console.log(chalk.green(`✓ เพิ่ม cronjob (openclaw): ${skillName} (${normalizedSchedule})`));
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
id: jobId,
|
|
92
|
-
skill: skillName,
|
|
93
|
-
schedule: normalizedSchedule,
|
|
94
|
-
params,
|
|
95
|
-
description: description || `Run ${skillName}`,
|
|
96
|
-
enabled: true,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const jobs = this.getJobs();
|
|
101
|
-
const jobId = `cron_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
57
|
+
async add(skillName, schedule, params = {}, description = '') {
|
|
58
|
+
const normalizedSchedule = normalizeCronExpression(schedule);
|
|
59
|
+
|
|
60
|
+
if (this.useOpenClawCron) {
|
|
61
|
+
const uniqueName = `cfh:${skillName}:${Date.now()}`;
|
|
62
|
+
const message = `Run skill ${skillName} with params: ${JSON.stringify(params)}`;
|
|
63
|
+
const created = await this.openclawCLI.addCronJob({
|
|
64
|
+
name: uniqueName,
|
|
65
|
+
description: description || `Run ${skillName}`,
|
|
66
|
+
schedule: normalizedSchedule,
|
|
67
|
+
message,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
let jobId = created.jobId;
|
|
71
|
+
if (!jobId) {
|
|
72
|
+
const jobs = await this.openclawCLI.listCronJobs();
|
|
73
|
+
const matched = jobs.find((job) => job.name === uniqueName);
|
|
74
|
+
jobId = matched?.id || null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!jobId) {
|
|
78
|
+
throw new Error('สร้าง cronjob ผ่าน openclaw สำเร็จ แต่ไม่สามารถระบุ job id ได้');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.configManager.addCron({
|
|
82
|
+
id: jobId,
|
|
83
|
+
skill: skillName,
|
|
84
|
+
schedule: normalizedSchedule,
|
|
85
|
+
description: description || `Run ${skillName}`,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
console.log(chalk.green(`✓ เพิ่ม cronjob (openclaw): ${skillName} (${normalizedSchedule})`));
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
id: jobId,
|
|
92
|
+
skill: skillName,
|
|
93
|
+
schedule: normalizedSchedule,
|
|
94
|
+
params,
|
|
95
|
+
description: description || `Run ${skillName}`,
|
|
96
|
+
enabled: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const jobs = this.getJobs();
|
|
101
|
+
const jobId = `cron_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
102
102
|
|
|
103
103
|
const job = {
|
|
104
|
-
id: jobId,
|
|
105
|
-
skill: skillName,
|
|
106
|
-
schedule: normalizedSchedule,
|
|
107
|
-
params,
|
|
108
|
-
description: description || `Run ${skillName}`,
|
|
109
|
-
enabled: true,
|
|
110
|
-
createdAt: new Date().toISOString(),
|
|
111
|
-
lastRun: null,
|
|
112
|
-
nextRun: this.getNextRun(normalizedSchedule),
|
|
113
|
-
runCount: 0,
|
|
114
|
-
errorCount: 0,
|
|
115
|
-
};
|
|
104
|
+
id: jobId,
|
|
105
|
+
skill: skillName,
|
|
106
|
+
schedule: normalizedSchedule,
|
|
107
|
+
params,
|
|
108
|
+
description: description || `Run ${skillName}`,
|
|
109
|
+
enabled: true,
|
|
110
|
+
createdAt: new Date().toISOString(),
|
|
111
|
+
lastRun: null,
|
|
112
|
+
nextRun: this.getNextRun(normalizedSchedule),
|
|
113
|
+
runCount: 0,
|
|
114
|
+
errorCount: 0,
|
|
115
|
+
};
|
|
116
116
|
|
|
117
117
|
jobs.push(job);
|
|
118
118
|
this.saveJobs(jobs);
|
|
119
119
|
|
|
120
120
|
// บันทึกลง config ด้วย
|
|
121
121
|
this.configManager.addCron({
|
|
122
|
-
id: jobId,
|
|
123
|
-
skill: skillName,
|
|
124
|
-
schedule: normalizedSchedule,
|
|
125
|
-
description,
|
|
126
|
-
});
|
|
122
|
+
id: jobId,
|
|
123
|
+
skill: skillName,
|
|
124
|
+
schedule: normalizedSchedule,
|
|
125
|
+
description,
|
|
126
|
+
});
|
|
127
127
|
|
|
128
128
|
// สร้าง cron script
|
|
129
129
|
this.createCronScript(job);
|
|
@@ -133,89 +133,89 @@ class CronManager {
|
|
|
133
133
|
this.startJob(job);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
console.log(chalk.green(`✓ เพิ่ม cronjob: ${skillName} (${normalizedSchedule})`));
|
|
137
|
-
|
|
138
|
-
return job;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* แก้ไข cronjob
|
|
143
|
-
*/
|
|
144
|
-
async edit(jobId, updates = {}) {
|
|
145
|
-
const normalized = { ...updates };
|
|
146
|
-
|
|
147
|
-
if (updates.schedule) {
|
|
148
|
-
normalized.schedule = normalizeCronExpression(updates.schedule);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (this.useOpenClawCron) {
|
|
152
|
-
const tracked = this.configManager.getCrons().find((c) => c.id === jobId);
|
|
153
|
-
const message =
|
|
154
|
-
Object.prototype.hasOwnProperty.call(updates, 'params') && tracked?.skill
|
|
155
|
-
? `Run skill
|
|
156
|
-
: undefined;
|
|
157
|
-
|
|
158
|
-
if (Object.prototype.hasOwnProperty.call(updates, 'params') && !tracked?.skill) {
|
|
159
|
-
throw new Error('แก้ไข params ไม่ได้ เพราะไม่พบ mapping skill ของ cron นี้ใน config');
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
await this.openclawCLI.editCronJob(jobId, {
|
|
163
|
-
schedule: normalized.schedule,
|
|
164
|
-
description: normalized.description,
|
|
165
|
-
message,
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
this.configManager.updateCron(jobId, {
|
|
169
|
-
...(normalized.schedule ? { schedule: normalized.schedule } : {}),
|
|
170
|
-
...(typeof normalized.description === 'string' ? { description: normalized.description } : {}),
|
|
171
|
-
...(Object.prototype.hasOwnProperty.call(updates, 'params') ? { params: updates.params } : {}),
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
return { id: jobId, ...normalized };
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const jobs = this.getJobs();
|
|
178
|
-
const job = jobs.find((j) => j.id === jobId);
|
|
179
|
-
|
|
180
|
-
if (!job) {
|
|
181
|
-
throw new Error(`ไม่พบ cronjob ID: ${jobId}`);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (normalized.schedule) {
|
|
185
|
-
job.schedule = normalized.schedule;
|
|
186
|
-
job.nextRun = this.getNextRun(normalized.schedule);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (typeof normalized.description === 'string') {
|
|
190
|
-
job.description = normalized.description;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (Object.prototype.hasOwnProperty.call(updates, 'params')) {
|
|
194
|
-
job.params = updates.params || {};
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
this.saveJobs(jobs);
|
|
198
|
-
this.configManager.updateCron(jobId, {
|
|
199
|
-
...(normalized.schedule ? { schedule: normalized.schedule } : {}),
|
|
200
|
-
...(typeof normalized.description === 'string' ? { description: normalized.description } : {}),
|
|
201
|
-
...(Object.prototype.hasOwnProperty.call(updates, 'params') ? { params: updates.params } : {}),
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
return job;
|
|
205
|
-
}
|
|
136
|
+
console.log(chalk.green(`✓ เพิ่ม cronjob: ${skillName} (${normalizedSchedule})`));
|
|
137
|
+
|
|
138
|
+
return job;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* แก้ไข cronjob
|
|
143
|
+
*/
|
|
144
|
+
async edit(jobId, updates = {}) {
|
|
145
|
+
const normalized = { ...updates };
|
|
146
|
+
|
|
147
|
+
if (updates.schedule) {
|
|
148
|
+
normalized.schedule = normalizeCronExpression(updates.schedule);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (this.useOpenClawCron) {
|
|
152
|
+
const tracked = this.configManager.getCrons().find((c) => c.id === jobId);
|
|
153
|
+
const message =
|
|
154
|
+
Object.prototype.hasOwnProperty.call(updates, 'params') && tracked?.skill
|
|
155
|
+
? `Run skill ${tracked.skill} with params: ${JSON.stringify(updates.params || {})}`
|
|
156
|
+
: undefined;
|
|
157
|
+
|
|
158
|
+
if (Object.prototype.hasOwnProperty.call(updates, 'params') && !tracked?.skill) {
|
|
159
|
+
throw new Error('แก้ไข params ไม่ได้ เพราะไม่พบ mapping skill ของ cron นี้ใน config');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await this.openclawCLI.editCronJob(jobId, {
|
|
163
|
+
schedule: normalized.schedule,
|
|
164
|
+
description: normalized.description,
|
|
165
|
+
message,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
this.configManager.updateCron(jobId, {
|
|
169
|
+
...(normalized.schedule ? { schedule: normalized.schedule } : {}),
|
|
170
|
+
...(typeof normalized.description === 'string' ? { description: normalized.description } : {}),
|
|
171
|
+
...(Object.prototype.hasOwnProperty.call(updates, 'params') ? { params: updates.params } : {}),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
return { id: jobId, ...normalized };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const jobs = this.getJobs();
|
|
178
|
+
const job = jobs.find((j) => j.id === jobId);
|
|
179
|
+
|
|
180
|
+
if (!job) {
|
|
181
|
+
throw new Error(`ไม่พบ cronjob ID: ${jobId}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (normalized.schedule) {
|
|
185
|
+
job.schedule = normalized.schedule;
|
|
186
|
+
job.nextRun = this.getNextRun(normalized.schedule);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (typeof normalized.description === 'string') {
|
|
190
|
+
job.description = normalized.description;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (Object.prototype.hasOwnProperty.call(updates, 'params')) {
|
|
194
|
+
job.params = updates.params || {};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
this.saveJobs(jobs);
|
|
198
|
+
this.configManager.updateCron(jobId, {
|
|
199
|
+
...(normalized.schedule ? { schedule: normalized.schedule } : {}),
|
|
200
|
+
...(typeof normalized.description === 'string' ? { description: normalized.description } : {}),
|
|
201
|
+
...(Object.prototype.hasOwnProperty.call(updates, 'params') ? { params: updates.params } : {}),
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
return job;
|
|
205
|
+
}
|
|
206
206
|
|
|
207
207
|
/**
|
|
208
208
|
* ลบ cronjob
|
|
209
209
|
*/
|
|
210
|
-
async remove(jobId) {
|
|
211
|
-
if (this.useOpenClawCron) {
|
|
212
|
-
await this.openclawCLI.removeCronJob(jobId);
|
|
213
|
-
this.configManager.removeCron(jobId);
|
|
214
|
-
console.log(chalk.green(`✓ ลบ cronjob (openclaw): ${jobId}`));
|
|
215
|
-
return { success: true, removed: { id: jobId } };
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
let jobs = this.getJobs();
|
|
210
|
+
async remove(jobId) {
|
|
211
|
+
if (this.useOpenClawCron) {
|
|
212
|
+
await this.openclawCLI.removeCronJob(jobId);
|
|
213
|
+
this.configManager.removeCron(jobId);
|
|
214
|
+
console.log(chalk.green(`✓ ลบ cronjob (openclaw): ${jobId}`));
|
|
215
|
+
return { success: true, removed: { id: jobId } };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
let jobs = this.getJobs();
|
|
219
219
|
const job = jobs.find(j => j.id === jobId);
|
|
220
220
|
|
|
221
221
|
if (!job) {
|
|
@@ -243,12 +243,12 @@ class CronManager {
|
|
|
243
243
|
/**
|
|
244
244
|
* แสดงรายการ cronjobs
|
|
245
245
|
*/
|
|
246
|
-
list() {
|
|
247
|
-
if (this.useOpenClawCron) {
|
|
248
|
-
return this.listViaOpenClaw();
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const jobs = this.getJobs();
|
|
246
|
+
list() {
|
|
247
|
+
if (this.useOpenClawCron) {
|
|
248
|
+
return this.listViaOpenClaw();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const jobs = this.getJobs();
|
|
252
252
|
|
|
253
253
|
if (jobs.length === 0) {
|
|
254
254
|
console.log(chalk.gray('ไม่มี cronjob ที่ตั้งไว้'));
|
|
@@ -265,30 +265,30 @@ class CronManager {
|
|
|
265
265
|
nextRun: job.nextRun,
|
|
266
266
|
runCount: job.runCount,
|
|
267
267
|
}));
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* แสดงรายการ cronjobs ผ่าน OpenClaw CLI
|
|
272
|
-
*/
|
|
273
|
-
async listViaOpenClaw() {
|
|
274
|
-
const jobs = await this.openclawCLI.listCronJobs();
|
|
275
|
-
|
|
276
|
-
if (!jobs || jobs.length === 0) {
|
|
277
|
-
console.log(chalk.gray('ไม่มี cronjob ที่ตั้งไว้'));
|
|
278
|
-
return [];
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return jobs.map((job) => ({
|
|
282
|
-
id: job.id,
|
|
283
|
-
skill: job.name || 'unknown',
|
|
284
|
-
schedule: job.schedule?.expr || job.schedule?.kind || '-',
|
|
285
|
-
description: job.description || '',
|
|
286
|
-
enabled: job.enabled !== false,
|
|
287
|
-
lastRun: job.lastRunAt || null,
|
|
288
|
-
nextRun: job.nextRunAt || null,
|
|
289
|
-
runCount: job.runCount || 0,
|
|
290
|
-
}));
|
|
291
|
-
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* แสดงรายการ cronjobs ผ่าน OpenClaw CLI
|
|
272
|
+
*/
|
|
273
|
+
async listViaOpenClaw() {
|
|
274
|
+
const jobs = await this.openclawCLI.listCronJobs();
|
|
275
|
+
|
|
276
|
+
if (!jobs || jobs.length === 0) {
|
|
277
|
+
console.log(chalk.gray('ไม่มี cronjob ที่ตั้งไว้'));
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return jobs.map((job) => ({
|
|
282
|
+
id: job.id,
|
|
283
|
+
skill: job.name || 'unknown',
|
|
284
|
+
schedule: job.schedule?.expr || job.schedule?.kind || '-',
|
|
285
|
+
description: job.description || '',
|
|
286
|
+
enabled: job.enabled !== false,
|
|
287
|
+
lastRun: job.lastRunAt || null,
|
|
288
|
+
nextRun: job.nextRunAt || null,
|
|
289
|
+
runCount: job.runCount || 0,
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
292
292
|
|
|
293
293
|
/**
|
|
294
294
|
* เริ่มต้น job
|
|
@@ -311,16 +311,16 @@ class CronManager {
|
|
|
311
311
|
/**
|
|
312
312
|
* หยุด job
|
|
313
313
|
*/
|
|
314
|
-
stopJob(jobId) {
|
|
315
|
-
const task = this.tasks.get(jobId);
|
|
316
|
-
if (task) {
|
|
317
|
-
task.stop();
|
|
318
|
-
if (typeof task.destroy === 'function') {
|
|
319
|
-
task.destroy();
|
|
320
|
-
}
|
|
321
|
-
this.tasks.delete(jobId);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
314
|
+
stopJob(jobId) {
|
|
315
|
+
const task = this.tasks.get(jobId);
|
|
316
|
+
if (task) {
|
|
317
|
+
task.stop();
|
|
318
|
+
if (typeof task.destroy === 'function') {
|
|
319
|
+
task.destroy();
|
|
320
|
+
}
|
|
321
|
+
this.tasks.delete(jobId);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
324
|
|
|
325
325
|
/**
|
|
326
326
|
* รัน job
|
|
@@ -362,10 +362,10 @@ class CronManager {
|
|
|
362
362
|
/**
|
|
363
363
|
* รัน skill
|
|
364
364
|
*/
|
|
365
|
-
async runSkill(skillName, params) {
|
|
366
|
-
// ในโลกจริงจะเรียก OpenClaw API
|
|
367
|
-
// const response = await axios.post(`${baseUrl}/api/skills/execute`, {
|
|
368
|
-
// name: skillName,
|
|
365
|
+
async runSkill(skillName, params) {
|
|
366
|
+
// ในโลกจริงจะเรียก OpenClaw API
|
|
367
|
+
// const response = await axios.post(`${baseUrl}/api/skills/execute`, {
|
|
368
|
+
// name: skillName,
|
|
369
369
|
// params,
|
|
370
370
|
// });
|
|
371
371
|
|
|
@@ -392,7 +392,7 @@ async function run() {
|
|
|
392
392
|
console.log(\`[\${new Date().toISOString()}] Running \${skill}...\`);
|
|
393
393
|
|
|
394
394
|
// Call OpenClaw API
|
|
395
|
-
const baseUrl = process.env.OPENCLAW_URL || 'http://localhost:
|
|
395
|
+
const baseUrl = process.env.OPENCLAW_URL || 'http://localhost:18789';
|
|
396
396
|
const response = await axios.post(\`\${baseUrl}/api/skills/execute\`, {
|
|
397
397
|
name: skill,
|
|
398
398
|
params: { ...config, ...params },
|
|
@@ -435,7 +435,7 @@ run();
|
|
|
435
435
|
/**
|
|
436
436
|
* คำนวณเวลารันครั้งถัดไป
|
|
437
437
|
*/
|
|
438
|
-
getNextRun(_schedule) {
|
|
438
|
+
getNextRun(_schedule) {
|
|
439
439
|
// ง่ายๆ แค่ return null ตอนนี้
|
|
440
440
|
// ในอนาคตอาจใช้ library คำนวณจริง
|
|
441
441
|
return null;
|
|
@@ -444,13 +444,13 @@ run();
|
|
|
444
444
|
/**
|
|
445
445
|
* เปิด/ปิด job
|
|
446
446
|
*/
|
|
447
|
-
toggleJob(jobId, enabled) {
|
|
448
|
-
if (this.useOpenClawCron) {
|
|
449
|
-
throw new Error('โหมด openclaw cron: ให้ใช้คำสั่ง "openclaw cron enable|disable <id>"');
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const jobs = this.getJobs();
|
|
453
|
-
const job = jobs.find(j => j.id === jobId);
|
|
447
|
+
toggleJob(jobId, enabled) {
|
|
448
|
+
if (this.useOpenClawCron) {
|
|
449
|
+
throw new Error('โหมด openclaw cron: ให้ใช้คำสั่ง "openclaw cron enable|disable <id>"');
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const jobs = this.getJobs();
|
|
453
|
+
const job = jobs.find(j => j.id === jobId);
|
|
454
454
|
|
|
455
455
|
if (!job) {
|
|
456
456
|
throw new Error(`ไม่พบ cronjob ID: ${jobId}`);
|
|
@@ -473,13 +473,13 @@ run();
|
|
|
473
473
|
/**
|
|
474
474
|
* เริ่มต้นระบบ cron (เรียกตอน start)
|
|
475
475
|
*/
|
|
476
|
-
startAll() {
|
|
477
|
-
if (this.useOpenClawCron) {
|
|
478
|
-
console.log(chalk.green('✓ ใช้ openclaw cron scheduler (ไม่ต้อง start local tasks)'));
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
const jobs = this.getJobs().filter(j => j.enabled);
|
|
476
|
+
startAll() {
|
|
477
|
+
if (this.useOpenClawCron) {
|
|
478
|
+
console.log(chalk.green('✓ ใช้ openclaw cron scheduler (ไม่ต้อง start local tasks)'));
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
const jobs = this.getJobs().filter(j => j.enabled);
|
|
483
483
|
|
|
484
484
|
for (const job of jobs) {
|
|
485
485
|
this.startJob(job);
|
|
@@ -491,18 +491,18 @@ run();
|
|
|
491
491
|
/**
|
|
492
492
|
* หยุดระบบ cron ทั้งหมด
|
|
493
493
|
*/
|
|
494
|
-
stopAll() {
|
|
495
|
-
if (this.useOpenClawCron) {
|
|
496
|
-
console.log(chalk.yellow('⏹️ openclaw cron scheduler ยังทำงานภายนอก process นี้'));
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
for (const [, task] of this.tasks) {
|
|
501
|
-
task.stop();
|
|
502
|
-
if (typeof task.destroy === 'function') {
|
|
503
|
-
task.destroy();
|
|
504
|
-
}
|
|
505
|
-
}
|
|
494
|
+
stopAll() {
|
|
495
|
+
if (this.useOpenClawCron) {
|
|
496
|
+
console.log(chalk.yellow('⏹️ openclaw cron scheduler ยังทำงานภายนอก process นี้'));
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
for (const [, task] of this.tasks) {
|
|
501
|
+
task.stop();
|
|
502
|
+
if (typeof task.destroy === 'function') {
|
|
503
|
+
task.destroy();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
506
|
this.tasks.clear();
|
|
507
507
|
|
|
508
508
|
console.log(chalk.yellow('⏹️ หยุดระบบ cron'));
|