@patrick-rodgers/cron-claude 0.1.0 → 0.1.2
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/.claude-plugin/plugin.json +27 -0
- package/.mcp.json +8 -0
- package/CLAUDE.md +321 -0
- package/README.md +440 -401
- package/commands/cron-list.md +21 -0
- package/commands/cron-run.md +18 -0
- package/commands/cron-status.md +20 -0
- package/dist/cli.js +55 -57
- package/dist/cli.js.map +1 -1
- package/dist/config.js +15 -20
- package/dist/config.js.map +1 -1
- package/dist/executor.js +36 -44
- package/dist/executor.js.map +1 -1
- package/dist/index.js +6 -22
- package/dist/index.js.map +1 -1
- package/dist/logger.js +33 -46
- package/dist/logger.js.map +1 -1
- package/dist/mcp-server.js +80 -79
- package/dist/mcp-server.js.map +1 -1
- package/dist/notifier.js +5 -13
- package/dist/notifier.js.map +1 -1
- package/dist/scheduler.js +57 -69
- package/dist/scheduler.js.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/hooks/hooks.json +5 -0
- package/hooks/session-start.sh +23 -0
- package/package.json +70 -52
- package/skills/cron/SKILL.md +187 -0
- package/tasks/example-daily-summary.md +37 -0
- package/tasks/example-weekly-backup.md +27 -0
- package/install.ps1 +0 -93
- package/uninstall.ps1 +0 -59
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# cron-list
|
|
2
|
+
|
|
3
|
+
List all scheduled tasks with their status and next run times.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
When this command is invoked, Claude will automatically call the `cron_list_tasks` MCP tool to display all tasks.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/cron-list
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Claude will show you:
|
|
16
|
+
- Task IDs
|
|
17
|
+
- Schedules (cron expressions)
|
|
18
|
+
- Invocation methods (CLI or API)
|
|
19
|
+
- Enabled/disabled status
|
|
20
|
+
- Registration status
|
|
21
|
+
- Last and next run times
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# cron-run
|
|
2
|
+
|
|
3
|
+
Manually execute a task immediately for testing purposes.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
When this command is invoked with a task ID, Claude will run the task right away without waiting for the schedule.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
/cron-run daily-summary
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Claude will:
|
|
16
|
+
1. Execute the task immediately
|
|
17
|
+
2. Show execution results
|
|
18
|
+
3. Offer to view logs
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# cron-status
|
|
2
|
+
|
|
3
|
+
Check the status of the Cron-Claude MCP server and view system configuration.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
When this command is invoked, Claude will automatically call the `cron_status` MCP tool to display:
|
|
8
|
+
- Version information
|
|
9
|
+
- Configuration directory locations
|
|
10
|
+
- Total number of tasks
|
|
11
|
+
- Secret key status
|
|
12
|
+
- Available tools
|
|
13
|
+
|
|
14
|
+
## Example
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
/cron-status
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Claude will show you the current system status and configuration.
|
package/dist/cli.js
CHANGED
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
2
|
/**
|
|
4
3
|
* CLI interface for cron-claude
|
|
5
4
|
* Manage scheduled Claude tasks
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const TASKS_DIR = (0, path_1.join)(PROJECT_ROOT, 'tasks');
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
8
|
+
import { join, resolve, dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import matter from 'gray-matter';
|
|
11
|
+
import { registerTask, unregisterTask, enableTask, disableTask, getTaskStatus } from './scheduler.js';
|
|
12
|
+
import { executeTask } from './executor.js';
|
|
13
|
+
import { verifyLogFile } from './logger.js';
|
|
14
|
+
import { loadConfig } from './config.js';
|
|
15
|
+
import { execSync } from 'child_process';
|
|
16
|
+
const program = new Command();
|
|
17
|
+
// Get project root (ESM equivalent of __dirname)
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
20
|
+
const PROJECT_ROOT = resolve(__dirname, '..');
|
|
21
|
+
const TASKS_DIR = join(PROJECT_ROOT, 'tasks');
|
|
24
22
|
// Ensure tasks directory exists
|
|
25
|
-
if (!
|
|
26
|
-
|
|
23
|
+
if (!existsSync(TASKS_DIR)) {
|
|
24
|
+
mkdirSync(TASKS_DIR, { recursive: true });
|
|
27
25
|
}
|
|
28
26
|
/**
|
|
29
27
|
* Get all task files
|
|
30
28
|
*/
|
|
31
29
|
function getTaskFiles() {
|
|
32
30
|
try {
|
|
33
|
-
return
|
|
31
|
+
return readdirSync(TASKS_DIR).filter((f) => f.endsWith('.md'));
|
|
34
32
|
}
|
|
35
33
|
catch {
|
|
36
34
|
return [];
|
|
@@ -40,9 +38,9 @@ function getTaskFiles() {
|
|
|
40
38
|
* Parse task file
|
|
41
39
|
*/
|
|
42
40
|
function parseTask(filename) {
|
|
43
|
-
const filePath =
|
|
44
|
-
const content =
|
|
45
|
-
const parsed = (
|
|
41
|
+
const filePath = join(TASKS_DIR, filename);
|
|
42
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
43
|
+
const parsed = matter(content);
|
|
46
44
|
return { filePath, ...parsed.data, instructions: parsed.content };
|
|
47
45
|
}
|
|
48
46
|
program
|
|
@@ -61,27 +59,27 @@ program
|
|
|
61
59
|
// TODO: Add interactive prompts
|
|
62
60
|
// For now, create a template
|
|
63
61
|
const taskId = `task-${Date.now()}`;
|
|
64
|
-
const template = `---
|
|
65
|
-
id: ${taskId}
|
|
66
|
-
schedule: "0 9 * * *" # Every day at 9 AM
|
|
67
|
-
invocation: cli # or 'api'
|
|
68
|
-
notifications:
|
|
69
|
-
toast: true
|
|
70
|
-
enabled: true
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
# Task Instructions
|
|
74
|
-
|
|
75
|
-
Write your instructions for Claude here.
|
|
76
|
-
|
|
77
|
-
## Example
|
|
78
|
-
- Check email
|
|
79
|
-
- Summarize important messages
|
|
80
|
-
- Create a daily report
|
|
62
|
+
const template = `---
|
|
63
|
+
id: ${taskId}
|
|
64
|
+
schedule: "0 9 * * *" # Every day at 9 AM
|
|
65
|
+
invocation: cli # or 'api'
|
|
66
|
+
notifications:
|
|
67
|
+
toast: true
|
|
68
|
+
enabled: true
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
# Task Instructions
|
|
72
|
+
|
|
73
|
+
Write your instructions for Claude here.
|
|
74
|
+
|
|
75
|
+
## Example
|
|
76
|
+
- Check email
|
|
77
|
+
- Summarize important messages
|
|
78
|
+
- Create a daily report
|
|
81
79
|
`;
|
|
82
80
|
const filename = `${taskId}.md`;
|
|
83
|
-
const filePath =
|
|
84
|
-
|
|
81
|
+
const filePath = join(TASKS_DIR, filename);
|
|
82
|
+
writeFileSync(filePath, template, 'utf-8');
|
|
85
83
|
console.log(`✓ Task template created: ${filename}`);
|
|
86
84
|
console.log(` Location: ${filePath}`);
|
|
87
85
|
console.log('\nNext steps:');
|
|
@@ -97,8 +95,8 @@ program
|
|
|
97
95
|
.action((taskId) => {
|
|
98
96
|
try {
|
|
99
97
|
const filename = `${taskId}.md`;
|
|
100
|
-
const filePath =
|
|
101
|
-
if (!
|
|
98
|
+
const filePath = join(TASKS_DIR, filename);
|
|
99
|
+
if (!existsSync(filePath)) {
|
|
102
100
|
console.error(`Error: Task file not found: ${filename}`);
|
|
103
101
|
process.exit(1);
|
|
104
102
|
}
|
|
@@ -107,7 +105,7 @@ program
|
|
|
107
105
|
console.error('Error: Task must have a schedule defined');
|
|
108
106
|
process.exit(1);
|
|
109
107
|
}
|
|
110
|
-
|
|
108
|
+
registerTask(taskId, filePath, task.schedule, PROJECT_ROOT);
|
|
111
109
|
}
|
|
112
110
|
catch (error) {
|
|
113
111
|
console.error('Error registering task:', error);
|
|
@@ -123,7 +121,7 @@ program
|
|
|
123
121
|
.description('Unregister a task from Windows Task Scheduler')
|
|
124
122
|
.action((taskId) => {
|
|
125
123
|
try {
|
|
126
|
-
|
|
124
|
+
unregisterTask(taskId);
|
|
127
125
|
}
|
|
128
126
|
catch (error) {
|
|
129
127
|
console.error('Error unregistering task:', error);
|
|
@@ -146,7 +144,7 @@ program
|
|
|
146
144
|
files.forEach((file) => {
|
|
147
145
|
try {
|
|
148
146
|
const task = parseTask(file);
|
|
149
|
-
const status =
|
|
147
|
+
const status = getTaskStatus(task.id);
|
|
150
148
|
console.log(`📋 ${task.id}`);
|
|
151
149
|
console.log(` Schedule: ${task.schedule}`);
|
|
152
150
|
console.log(` Method: ${task.invocation}`);
|
|
@@ -179,7 +177,7 @@ program
|
|
|
179
177
|
.description('Enable a task in Windows Task Scheduler')
|
|
180
178
|
.action((taskId) => {
|
|
181
179
|
try {
|
|
182
|
-
|
|
180
|
+
enableTask(taskId);
|
|
183
181
|
}
|
|
184
182
|
catch (error) {
|
|
185
183
|
console.error('Error enabling task:', error);
|
|
@@ -194,7 +192,7 @@ program
|
|
|
194
192
|
.description('Disable a task in Windows Task Scheduler')
|
|
195
193
|
.action((taskId) => {
|
|
196
194
|
try {
|
|
197
|
-
|
|
195
|
+
disableTask(taskId);
|
|
198
196
|
}
|
|
199
197
|
catch (error) {
|
|
200
198
|
console.error('Error disabling task:', error);
|
|
@@ -210,13 +208,13 @@ program
|
|
|
210
208
|
.action(async (taskId) => {
|
|
211
209
|
try {
|
|
212
210
|
const filename = `${taskId}.md`;
|
|
213
|
-
const filePath =
|
|
214
|
-
if (!
|
|
211
|
+
const filePath = join(TASKS_DIR, filename);
|
|
212
|
+
if (!existsSync(filePath)) {
|
|
215
213
|
console.error(`Error: Task file not found: ${filename}`);
|
|
216
214
|
process.exit(1);
|
|
217
215
|
}
|
|
218
216
|
console.log(`Executing task: ${taskId}...\n`);
|
|
219
|
-
await
|
|
217
|
+
await executeTask(filePath);
|
|
220
218
|
console.log('\n✓ Task execution completed');
|
|
221
219
|
}
|
|
222
220
|
catch (error) {
|
|
@@ -233,7 +231,7 @@ program
|
|
|
233
231
|
.action((taskId) => {
|
|
234
232
|
try {
|
|
235
233
|
// Query memory skill for logs
|
|
236
|
-
const result =
|
|
234
|
+
const result = execSync(`odsp-memory recall --category=cron-task "${taskId}"`, {
|
|
237
235
|
encoding: 'utf-8',
|
|
238
236
|
});
|
|
239
237
|
console.log(result);
|
|
@@ -251,8 +249,8 @@ program
|
|
|
251
249
|
.description('Verify the signature of a log file')
|
|
252
250
|
.action((logFile) => {
|
|
253
251
|
try {
|
|
254
|
-
const content =
|
|
255
|
-
const result =
|
|
252
|
+
const content = readFileSync(logFile, 'utf-8');
|
|
253
|
+
const result = verifyLogFile(content);
|
|
256
254
|
if (result.valid) {
|
|
257
255
|
console.log('✓ Signature is valid - log has not been tampered with');
|
|
258
256
|
if (result.log) {
|
|
@@ -279,7 +277,7 @@ program
|
|
|
279
277
|
.command('status')
|
|
280
278
|
.description('Show cron-claude system status')
|
|
281
279
|
.action(() => {
|
|
282
|
-
const config =
|
|
280
|
+
const config = loadConfig();
|
|
283
281
|
const taskCount = getTaskFiles().length;
|
|
284
282
|
const { getConfigDir } = require('./config.js');
|
|
285
283
|
console.log('Cron-Claude System Status\n');
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,39 +1,34 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Configuration management for cron-claude
|
|
4
3
|
* Handles secret key generation and storage
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const path_1 = require("path");
|
|
13
|
-
const os_1 = require("os");
|
|
14
|
-
const CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.cron-claude');
|
|
15
|
-
const CONFIG_FILE = (0, path_1.join)(CONFIG_DIR, 'config.json');
|
|
5
|
+
import { randomBytes } from 'crypto';
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
const CONFIG_DIR = join(homedir(), '.cron-claude');
|
|
10
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
16
11
|
/**
|
|
17
12
|
* Ensure config directory exists
|
|
18
13
|
*/
|
|
19
14
|
function ensureConfigDir() {
|
|
20
|
-
if (!
|
|
21
|
-
|
|
15
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
16
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
22
17
|
}
|
|
23
18
|
}
|
|
24
19
|
/**
|
|
25
20
|
* Generate a new secret key for HMAC signing
|
|
26
21
|
*/
|
|
27
22
|
function generateSecretKey() {
|
|
28
|
-
return
|
|
23
|
+
return randomBytes(32).toString('hex');
|
|
29
24
|
}
|
|
30
25
|
/**
|
|
31
26
|
* Load or create configuration
|
|
32
27
|
*/
|
|
33
|
-
function loadConfig() {
|
|
28
|
+
export function loadConfig() {
|
|
34
29
|
ensureConfigDir();
|
|
35
|
-
if (
|
|
36
|
-
const data =
|
|
30
|
+
if (existsSync(CONFIG_FILE)) {
|
|
31
|
+
const data = readFileSync(CONFIG_FILE, 'utf-8');
|
|
37
32
|
return JSON.parse(data);
|
|
38
33
|
}
|
|
39
34
|
// Create new config with generated secret key
|
|
@@ -41,21 +36,21 @@ function loadConfig() {
|
|
|
41
36
|
secretKey: generateSecretKey(),
|
|
42
37
|
version: '0.1.0',
|
|
43
38
|
};
|
|
44
|
-
|
|
39
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
45
40
|
console.log('Generated new secret key for log signing');
|
|
46
41
|
return config;
|
|
47
42
|
}
|
|
48
43
|
/**
|
|
49
44
|
* Get the secret key for HMAC signing
|
|
50
45
|
*/
|
|
51
|
-
function getSecretKey() {
|
|
46
|
+
export function getSecretKey() {
|
|
52
47
|
const config = loadConfig();
|
|
53
48
|
return config.secretKey;
|
|
54
49
|
}
|
|
55
50
|
/**
|
|
56
51
|
* Get config directory path
|
|
57
52
|
*/
|
|
58
|
-
function getConfigDir() {
|
|
53
|
+
export function getConfigDir() {
|
|
59
54
|
return CONFIG_DIR;
|
|
60
55
|
}
|
|
61
56
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACnD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAOpD;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,eAAe,EAAE,CAAC;IAElB,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,8CAA8C;IAC9C,MAAM,MAAM,GAAW;QACrB,SAAS,EAAE,iBAAiB,EAAE;QAC9B,OAAO,EAAE,OAAO;KACjB,CAAC;IAEF,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAExD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,SAAS,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
package/dist/executor.js
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Task execution engine
|
|
4
3
|
* Executes tasks via CLI or API based on task configuration
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
exports.executeTask = executeTask;
|
|
12
|
-
exports.main = main;
|
|
13
|
-
const child_process_1 = require("child_process");
|
|
14
|
-
const fs_1 = require("fs");
|
|
15
|
-
const gray_matter_1 = __importDefault(require("gray-matter"));
|
|
16
|
-
const logger_js_1 = require("./logger.js");
|
|
17
|
-
const notifier_js_1 = require("./notifier.js");
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
7
|
+
import matter from 'gray-matter';
|
|
8
|
+
import { createLog, addLogStep, finalizeLog } from './logger.js';
|
|
9
|
+
import { sendNotification } from './notifier.js';
|
|
18
10
|
/**
|
|
19
11
|
* Parse task definition from markdown file
|
|
20
12
|
*/
|
|
21
|
-
function parseTaskDefinition(filePath) {
|
|
22
|
-
const content =
|
|
23
|
-
const parsed = (
|
|
13
|
+
export function parseTaskDefinition(filePath) {
|
|
14
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
15
|
+
const parsed = matter(content);
|
|
24
16
|
const taskDef = {
|
|
25
17
|
id: parsed.data.id || 'unknown',
|
|
26
18
|
schedule: parsed.data.schedule || '0 0 * * *',
|
|
@@ -35,17 +27,17 @@ function parseTaskDefinition(filePath) {
|
|
|
35
27
|
* Execute task via Claude CLI
|
|
36
28
|
*/
|
|
37
29
|
async function executeViaCLI(task, log) {
|
|
38
|
-
|
|
30
|
+
addLogStep(log, 'Starting CLI execution');
|
|
39
31
|
return new Promise((resolve) => {
|
|
40
32
|
try {
|
|
41
33
|
// Create a temporary file with the instructions
|
|
42
34
|
const tempFile = `${process.env.TEMP || '/tmp'}/cron-claude-task-${task.id}-${Date.now()}.md`;
|
|
43
35
|
const fs = require('fs');
|
|
44
36
|
fs.writeFileSync(tempFile, task.instructions, 'utf-8');
|
|
45
|
-
|
|
37
|
+
addLogStep(log, 'Created temporary task file', tempFile);
|
|
46
38
|
// Spawn claude-code process
|
|
47
|
-
|
|
48
|
-
const claude =
|
|
39
|
+
addLogStep(log, 'Spawning claude-code process');
|
|
40
|
+
const claude = spawn('claude-code', [tempFile], {
|
|
49
41
|
stdio: 'pipe',
|
|
50
42
|
shell: true,
|
|
51
43
|
});
|
|
@@ -54,24 +46,24 @@ async function executeViaCLI(task, log) {
|
|
|
54
46
|
claude.stdout?.on('data', (data) => {
|
|
55
47
|
const text = data.toString();
|
|
56
48
|
output += text;
|
|
57
|
-
|
|
49
|
+
addLogStep(log, 'CLI output', text);
|
|
58
50
|
});
|
|
59
51
|
claude.stderr?.on('data', (data) => {
|
|
60
52
|
const text = data.toString();
|
|
61
53
|
errorOutput += text;
|
|
62
|
-
|
|
54
|
+
addLogStep(log, 'CLI error output', text);
|
|
63
55
|
});
|
|
64
56
|
claude.on('close', (code) => {
|
|
65
57
|
// Clean up temp file
|
|
66
58
|
try {
|
|
67
59
|
fs.unlinkSync(tempFile);
|
|
68
|
-
|
|
60
|
+
addLogStep(log, 'Cleaned up temporary file');
|
|
69
61
|
}
|
|
70
62
|
catch (e) {
|
|
71
|
-
|
|
63
|
+
addLogStep(log, 'Warning: Could not clean up temp file', undefined, String(e));
|
|
72
64
|
}
|
|
73
65
|
if (code === 0) {
|
|
74
|
-
|
|
66
|
+
addLogStep(log, 'CLI execution completed successfully');
|
|
75
67
|
resolve({
|
|
76
68
|
success: true,
|
|
77
69
|
output,
|
|
@@ -79,7 +71,7 @@ async function executeViaCLI(task, log) {
|
|
|
79
71
|
});
|
|
80
72
|
}
|
|
81
73
|
else {
|
|
82
|
-
|
|
74
|
+
addLogStep(log, 'CLI execution failed', undefined, `Exit code: ${code}`);
|
|
83
75
|
resolve({
|
|
84
76
|
success: false,
|
|
85
77
|
output,
|
|
@@ -89,7 +81,7 @@ async function executeViaCLI(task, log) {
|
|
|
89
81
|
}
|
|
90
82
|
});
|
|
91
83
|
claude.on('error', (err) => {
|
|
92
|
-
|
|
84
|
+
addLogStep(log, 'CLI execution error', undefined, err.message);
|
|
93
85
|
resolve({
|
|
94
86
|
success: false,
|
|
95
87
|
output,
|
|
@@ -100,7 +92,7 @@ async function executeViaCLI(task, log) {
|
|
|
100
92
|
}
|
|
101
93
|
catch (error) {
|
|
102
94
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
103
|
-
|
|
95
|
+
addLogStep(log, 'Execution setup failed', undefined, errorMsg);
|
|
104
96
|
resolve({
|
|
105
97
|
success: false,
|
|
106
98
|
output: '',
|
|
@@ -114,14 +106,14 @@ async function executeViaCLI(task, log) {
|
|
|
114
106
|
* Execute task via Claude API
|
|
115
107
|
*/
|
|
116
108
|
async function executeViaAPI(task, log) {
|
|
117
|
-
|
|
109
|
+
addLogStep(log, 'Starting API execution');
|
|
118
110
|
try {
|
|
119
111
|
// Check for API key
|
|
120
112
|
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
121
113
|
if (!apiKey) {
|
|
122
114
|
throw new Error('ANTHROPIC_API_KEY environment variable not set');
|
|
123
115
|
}
|
|
124
|
-
|
|
116
|
+
addLogStep(log, 'API key found, making request');
|
|
125
117
|
// Make API call using fetch
|
|
126
118
|
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
127
119
|
method: 'POST',
|
|
@@ -147,7 +139,7 @@ async function executeViaAPI(task, log) {
|
|
|
147
139
|
}
|
|
148
140
|
const data = await response.json();
|
|
149
141
|
const output = data.content?.[0]?.text || JSON.stringify(data);
|
|
150
|
-
|
|
142
|
+
addLogStep(log, 'API request completed', output);
|
|
151
143
|
return {
|
|
152
144
|
success: true,
|
|
153
145
|
output,
|
|
@@ -156,7 +148,7 @@ async function executeViaAPI(task, log) {
|
|
|
156
148
|
}
|
|
157
149
|
catch (error) {
|
|
158
150
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
159
|
-
|
|
151
|
+
addLogStep(log, 'API execution failed', undefined, errorMsg);
|
|
160
152
|
return {
|
|
161
153
|
success: false,
|
|
162
154
|
output: '',
|
|
@@ -168,16 +160,16 @@ async function executeViaAPI(task, log) {
|
|
|
168
160
|
/**
|
|
169
161
|
* Execute a task
|
|
170
162
|
*/
|
|
171
|
-
async function executeTask(taskFilePath) {
|
|
163
|
+
export async function executeTask(taskFilePath) {
|
|
172
164
|
// Parse task definition
|
|
173
165
|
const task = parseTaskDefinition(taskFilePath);
|
|
174
166
|
// Create log
|
|
175
|
-
const log =
|
|
176
|
-
|
|
167
|
+
const log = createLog(task.id);
|
|
168
|
+
addLogStep(log, 'Task execution started', `Task: ${task.id}, Method: ${task.invocation}`);
|
|
177
169
|
// Check if task is enabled
|
|
178
170
|
if (!task.enabled) {
|
|
179
|
-
|
|
180
|
-
|
|
171
|
+
addLogStep(log, 'Task skipped - disabled');
|
|
172
|
+
finalizeLog(log, false);
|
|
181
173
|
return;
|
|
182
174
|
}
|
|
183
175
|
// Execute based on invocation method
|
|
@@ -189,16 +181,16 @@ async function executeTask(taskFilePath) {
|
|
|
189
181
|
result = await executeViaAPI(task, log);
|
|
190
182
|
}
|
|
191
183
|
else {
|
|
192
|
-
|
|
193
|
-
|
|
184
|
+
addLogStep(log, 'Invalid invocation method', undefined, `Unknown method: ${task.invocation}`);
|
|
185
|
+
finalizeLog(log, false);
|
|
194
186
|
return;
|
|
195
187
|
}
|
|
196
188
|
// Finalize log
|
|
197
|
-
|
|
189
|
+
finalizeLog(log, result.success);
|
|
198
190
|
// Send notification if enabled
|
|
199
191
|
if (task.notifications.toast) {
|
|
200
192
|
try {
|
|
201
|
-
await
|
|
193
|
+
await sendNotification(`Task ${task.id} ${result.success ? 'completed' : 'failed'}`, result.success
|
|
202
194
|
? `Task executed successfully`
|
|
203
195
|
: `Task failed: ${result.error || 'Unknown error'}`);
|
|
204
196
|
}
|
|
@@ -211,7 +203,7 @@ async function executeTask(taskFilePath) {
|
|
|
211
203
|
* Entry point for scheduled task execution
|
|
212
204
|
* Called by Windows Task Scheduler
|
|
213
205
|
*/
|
|
214
|
-
async function main() {
|
|
206
|
+
export async function main() {
|
|
215
207
|
// Get task file path from command line arguments
|
|
216
208
|
const taskFile = process.argv[2];
|
|
217
209
|
if (!taskFile) {
|
|
@@ -227,8 +219,8 @@ async function main() {
|
|
|
227
219
|
process.exit(1);
|
|
228
220
|
}
|
|
229
221
|
}
|
|
230
|
-
// Run if called directly
|
|
231
|
-
if (
|
|
222
|
+
// Run if called directly (ESM equivalent of require.main === module)
|
|
223
|
+
if (import.meta.url === `file://${process.argv[1].replace(/\\/g, '/')}`) {
|
|
232
224
|
main();
|
|
233
225
|
}
|
|
234
226
|
//# sourceMappingURL=executor.js.map
|