cron-claude 2.0.0 → 2.0.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/README.md CHANGED
@@ -1,22 +1,53 @@
1
1
  # cron-claude
2
2
 
3
- > Schedule tasks for Claude. Claude runs them with full tool access.
3
+ > **Claude is the cron daemon.** Schedule tasks Claude executes them on a loop with full tool access (Slack, bash, files, APIs).
4
4
 
5
- ## The problem with daemon-based cron
5
+ ## TL;DR
6
6
 
7
- The old approach spawned `claude --print` on a schedule. `--print` disables MCP tools. No Slack, no bash, no files — just text in, text out. You had to use `--dangerously-skip-permissions` just to get anything done.
7
+ ```bash
8
+ npm install -g cron-claude
9
+ cron-claude mcp install # wire up MCP in Claude Code
10
+
11
+ cron-claude add \
12
+ --id daily-standup \
13
+ --schedule "0 9 * * 1-5" \
14
+ --prompt "Post a standup summary to #dev-team on Slack"
15
+
16
+ # Then in Claude Code:
17
+ # "Call start_loop to begin."
18
+ ```
19
+
20
+ Claude starts looping: every 60s it checks for due jobs and spawns subagents to run them.
21
+
22
+ ---
23
+
24
+ ## How It Works
8
25
 
9
- ## How v2 works
26
+ **Claude is the executor — not a background daemon.**
10
27
 
11
- **Claude is the daemon.** You paste one line into a Claude Code session and it loops forever:
28
+ When you say `"Call start_loop"` in Claude Code, the MCP returns Claude's operating instructions. From that point:
12
29
 
13
- 1. Every 60s: call `get_due_jobs` → atomically claims due jobs (disk state = source of truth)
14
- 2. For each due job: spawn a **subagent** with the job's prompt
15
- 3. Subagent does the work with full tool access (Slack, bash, files, any MCP)
16
- 4. Subagent calls `mark_job_run` releases the lock, writes a log
17
- 5. Subagents run in parallel no blocking
30
+ 1. **Every 60s** Claude calls `get_due_jobs`
31
+ 2. **For each due job** Claude spawns a **subagent** with the job's prompt
32
+ 3. **The subagent** runs with full tool access, does the task, calls `mark_job_run` when done
33
+ 4. **Disk state** `get_due_jobs` atomically marks jobs as `running` before returning, preventing any job from being picked up twice even if loop iterations overlap
34
+ 5. **Repeat** forever, until told to stop
18
35
 
19
- No background daemon. No LaunchAgent. No permission dialogs. Survives Claude session restarts (disk state persists).
36
+ No LaunchAgent. No `--print` flag. No `--dangerously-skip-permissions`. Subagents run inside your existing Claude session with all your approved MCP servers already connected.
37
+
38
+ ---
39
+
40
+ ## For Claude (reading this as an agent)
41
+
42
+ If you have cron-claude MCP loaded, your role is to be the executor loop:
43
+
44
+ 1. Call `start_loop` → get your operating instructions and job list
45
+ 2. Every 60 seconds: call `get_due_jobs` → for each job, spawn a subagent
46
+ 3. Each subagent: execute the job prompt, then call `mark_job_run(id, output)`
47
+ 4. Never execute jobs yourself — always delegate to subagents
48
+ 5. Loop indefinitely
49
+
50
+ The MCP server description and tool descriptions contain full instructions. You do not need to read this README.
20
51
 
21
52
  ---
22
53
 
@@ -24,158 +55,96 @@ No background daemon. No LaunchAgent. No permission dialogs. Survives Claude ses
24
55
 
25
56
  ```bash
26
57
  npm install -g cron-claude
58
+ cron-claude mcp install # adds cron-claude-mcp to ~/.claude/settings.json
27
59
  ```
28
60
 
29
- ## Quick Start
61
+ ## Managing Jobs
30
62
 
31
- **1. Install the MCP server into Claude Code:**
32
63
  ```bash
33
- cron-claude mcp install
34
- ```
64
+ # Add a job
65
+ cron-claude add --id <id> --schedule "<cron>" --prompt "<what to do>"
35
66
 
36
- **2. Add a job:**
37
- ```bash
38
- cron-claude add \
39
- --id morning-standup \
40
- --schedule "0 9 * * 1-5" \
41
- --prompt "Post a morning standup summary to the #standup Slack channel. Include what's in my calendar today."
42
- ```
43
-
44
- **3. Start the loop in Claude Code:**
67
+ # List all jobs (shows status, last run, schedule)
68
+ cron-claude list
45
69
 
46
- Paste this into any Claude Code session (or use the `cron-loop` prompt from the MCP prompt picker):
70
+ # Remove / enable / disable
71
+ cron-claude remove <id>
72
+ cron-claude enable <id>
73
+ cron-claude disable <id>
47
74
 
75
+ # Show agent loop setup instructions
76
+ cron-claude agent-loop
48
77
  ```
49
- Call start_loop to begin.
50
- ```
51
-
52
- That's it. Claude will read its operating instructions from `start_loop` and begin polling every 60 seconds.
53
-
54
- ---
55
-
56
- ## CLI Commands
57
-
58
- | Command | Description |
59
- |---------|-------------|
60
- | `cron-claude list` | List all jobs with status, last run, schedule |
61
- | `cron-claude add --id <id> --schedule <cron> --prompt <text>` | Add a new job |
62
- | `cron-claude remove <id>` | Remove a job |
63
- | `cron-claude enable <id>` | Enable a job |
64
- | `cron-claude disable <id>` | Disable a job |
65
- | `cron-claude status` | Summary of job counts |
66
- | `cron-claude agent-loop` | Print setup instructions |
67
- | `cron-claude mcp install` | Install MCP into Claude Code |
68
- | `cron-claude stop` | Stop and remove the legacy v1 LaunchAgent daemon |
69
78
 
70
- ### `add` options
79
+ ### `add` flags
71
80
 
72
81
  | Flag | Default | Description |
73
82
  |------|---------|-------------|
74
- | `--id` | required | Unique job identifier |
75
- | `--schedule` | required | Cron expression (e.g. `"0 9 * * 1-5"`) |
76
- | `--prompt` | required | What to tell Claude to do |
77
- | `--model` | `sonnet` | Claude model for the subagent |
78
- | `--disabled` | — | Create the job in disabled state |
83
+ | `--id` | required | Unique job name |
84
+ | `--schedule` | required | Cron expression (e.g. `"0 9 * * 1-5"` = 9am weekdays) |
85
+ | `--prompt` | required | What Claude should do |
86
+ | `--model` | `sonnet` | Claude model for subagents |
87
+ | `--disabled` | — | Create in disabled state |
79
88
 
80
89
  ---
81
90
 
82
91
  ## MCP Tools
83
92
 
84
- The `cron-claude-mcp` server exposes these tools to Claude:
93
+ | Tool | When to call | What it does |
94
+ |------|-------------|--------------|
95
+ | `start_loop` | Once, to begin | Returns full operating instructions + job list |
96
+ | `get_due_jobs` | Every 60s in the loop | Returns due jobs; atomically marks them `running` |
97
+ | `mark_job_run` | After each job (from subagent) | Clears running state, writes log |
98
+ | `add_cron` | To add a job | Adds a job to the registry |
99
+ | `list_crons` | To see jobs | Returns all jobs as JSON |
100
+ | `remove_cron` | To remove a job | Deletes from registry |
101
+ | `enable_cron` / `disable_cron` | To toggle | Enables or disables |
102
+ | `get_status` | Any time | Job count summary |
85
103
 
86
- | Tool | Description |
87
- |------|-------------|
88
- | `start_loop` | Call once to get operating instructions (entry point) |
89
- | `get_due_jobs` | Returns due jobs, atomically marks them `running` |
90
- | `mark_job_run` | Clears running state, writes log. Call after each job. |
91
- | `add_cron` | Add a new job |
92
- | `list_crons` | List all jobs |
93
- | `remove_cron` | Remove a job by ID |
94
- | `enable_cron` | Enable a job |
95
- | `disable_cron` | Disable a job |
96
- | `get_status` | Get job counts (total, enabled, disabled, running) |
104
+ ### MCP Prompt
97
105
 
98
- ### MCP Prompts
99
-
100
- | Prompt | Description |
101
- |--------|-------------|
102
- | `cron-loop` | Tells Claude to call `start_loop` — use from the prompt picker |
106
+ Use `cron-loop` from the Claude Code prompt picker — it sends `"Call start_loop to begin."` automatically.
103
107
 
104
108
  ---
105
109
 
106
- ## Atomic Job Locking
107
-
108
- `get_due_jobs` atomically claims jobs before returning them:
110
+ ## Job State & Duplicate Prevention
109
111
 
110
- 1. Finds jobs where: `enabled=true`, `status=idle`, `lastRunAt` was >55s ago, cron schedule fired in last 60s
111
- 2. Sets `status=running`, `startedAt=now` on disk **before** returning the list
112
- 3. A second call to `get_due_jobs` sees `status=running` and skips those jobs
112
+ `get_due_jobs` uses **atomic locking** to prevent duplicate execution:
113
113
 
114
- This prevents duplicate execution if two loop iterations somehow overlap.
114
+ - Sets `status: "running"` on disk **before** returning the job list
115
+ - Any concurrent call sees `status: "running"` and skips that job
116
+ - `mark_job_run` resets `status: "idle"` and records `lastRunAt`
115
117
 
116
- `mark_job_run` resets `status=idle`, records `lastRunAt`, and writes a log to `~/.cron-claude/logs/`.
117
-
118
- If a job is stuck `running` for >10 minutes (subagent crashed), call:
118
+ If a subagent crashes without calling `mark_job_run`, the job stays locked. Reset it:
119
119
  ```
120
- mark_job_run with id="<job-id>", error="timeout"
120
+ mark_job_run with id="<job-id>", error="timeout — manually reset"
121
121
  ```
122
122
 
123
123
  ---
124
124
 
125
125
  ## Logs
126
126
 
127
- Logs are written to `~/.cron-claude/logs/` as `<job-id>_<timestamp>.log`:
127
+ `~/.cron-claude/logs/<job-id>_<timestamp>.log`
128
128
 
129
129
  ```
130
- Job: morning-standup
131
- Time: 2025-01-15T09:00:03.241Z
130
+ Job: daily-standup
131
+ Time: 2025-01-15T09:00:03Z
132
132
  Status: success
133
133
  ---
134
- Posted standup to #standup. Calendar shows: 10am design review, 2pm 1:1 with Alex.
135
- ```
136
-
137
- ---
138
-
139
- ## Why Not `--print` Mode?
140
-
141
- `claude --print` disables all MCP tools. You can't use Slack MCP, bash, file access, or any external integrations. The only way around it was `--dangerously-skip-permissions`, which bypasses all permission checks.
142
-
143
- In agent loop mode, subagents run inside your existing Claude session with all your approved MCP servers already connected. No flags needed.
144
-
145
- ---
146
-
147
- ## Configuration
148
-
149
- Jobs are stored in `~/.cron-claude/jobs.json`:
150
-
151
- ```json
152
- {
153
- "jobs": [
154
- {
155
- "id": "morning-standup",
156
- "schedule": "0 9 * * 1-5",
157
- "prompt": "Post a morning standup to #standup",
158
- "model": "sonnet",
159
- "enabled": true,
160
- "status": "idle",
161
- "lastRunAt": 1736931603241,
162
- "startedAt": null
163
- }
164
- ]
165
- }
134
+ Posted standup to #dev-team. Calendar: 10am design review, 2pm 1:1 with Alex.
166
135
  ```
167
136
 
168
137
  ---
169
138
 
170
139
  ## Upgrading from v1
171
140
 
172
- If you ran v1 (daemon mode), stop the LaunchAgent:
141
+ v1 used a LaunchAgent + `claude --print` subprocesses (which disabled MCP tools). Stop it:
173
142
 
174
143
  ```bash
175
144
  cron-claude stop
176
145
  ```
177
146
 
178
- Your jobs in `~/.cron-claude/jobs.json` are migrated automatically v2 just ignores the old `headless`, `dangerouslySkipPermissions`, and `executor` fields (they'll be stripped on next write).
147
+ Existing jobs in `~/.cron-claude/jobs.json` work as-is. Old fields (`headless`, `dangerouslySkipPermissions`) are ignored.
179
148
 
180
149
  ---
181
150
 
package/dist/cli.js CHANGED
File without changes
@@ -6,9 +6,25 @@ import { createRequire } from 'module';
6
6
  import { addJob, removeJob, listJobs, toggleJob, updateJob, isJobDue, logExecution, JobSchema, } from './config.js';
7
7
  const require = createRequire(import.meta.url);
8
8
  const { version } = require('../package.json');
9
- export const server = new McpServer({
10
- name: 'cron-claude',
11
- version,
9
+ export const server = new McpServer({ name: 'cron-claude', version }, {
10
+ instructions: `cron-claude: You are the cron executor.
11
+
12
+ YOUR ROLE: You run a continuous agent loop that executes scheduled Claude jobs on behalf of the user.
13
+
14
+ HOW TO START: Call start_loop — it returns your full operating instructions and the list of configured jobs.
15
+
16
+ THE LOOP (runs forever until user says stop):
17
+ Every 60 seconds:
18
+ 1. Call get_due_jobs → returns jobs due NOW, atomically marks them "running"
19
+ 2. For each returned job → spawn a subagent with the job prompt
20
+ The subagent must call mark_job_run(id, output) when it finishes
21
+ 3. Subagents run IN PARALLEL — do not wait for one before starting the next
22
+ 4. Wait 60 seconds, repeat
23
+
24
+ WHY SUBAGENTS: Each job runs in its own agent context with full tool access (Slack, bash, files, APIs).
25
+ The disk state (status: "running") prevents any job from executing twice.
26
+
27
+ To begin: call start_loop.`,
12
28
  });
13
29
  // add_cron
14
30
  server.tool('add_cron', 'Add a new scheduled Claude job (agent loop mode)', {
@@ -113,7 +129,7 @@ server.tool('get_status', 'Get status of all cron-claude jobs (counts)', {}, (_a
113
129
  };
114
130
  });
115
131
  // get_due_jobs — atomically claims due jobs to prevent duplicate execution
116
- server.tool('get_due_jobs', 'Returns jobs that are due to run right now. Atomically marks them as "running" before returning so concurrent calls cannot pick up the same job. Call this every 60 seconds in agent loop mode.', {}, (_args) => {
132
+ server.tool('get_due_jobs', 'AGENT LOOP STEP 1: Call this every 60 seconds. Returns jobs whose cron schedule matches right now. Atomically marks each returned job as "running" on disk so a second call will never return the same job while it is still executing. For each returned job: spawn a subagent with the job\'s prompt and instruct it to call mark_job_run(id, output) when done. Run all subagents in parallel.', {}, (_args) => {
117
133
  const now = Date.now();
118
134
  // Find jobs that are due and not already claimed
119
135
  const dueJobs = listJobs().filter((job) => {
@@ -135,7 +151,7 @@ server.tool('get_due_jobs', 'Returns jobs that are due to run right now. Atomica
135
151
  };
136
152
  });
137
153
  // mark_job_run — releases the running lock and writes a log
138
- server.tool('mark_job_run', 'Records that a job was executed. Clears the running status and writes a log. Call after completing each job returned by get_due_jobs.', {
154
+ server.tool('mark_job_run', 'AGENT LOOP STEP 2 (call from subagent): Records that a job finished. Clears its "running" status on disk (allowing it to run again next cycle) and writes a log entry. Every subagent spawned by the loop MUST call this when done, even on failure — otherwise the job stays locked as "running" forever.', {
139
155
  id: z.string().min(1).describe('Job ID that was run'),
140
156
  output: z.string().optional().describe('Output or summary of what was done'),
141
157
  error: z.string().optional().describe('Error message if the job failed'),
@@ -159,7 +175,7 @@ server.tool('mark_job_run', 'Records that a job was executed. Clears the running
159
175
  }
160
176
  });
161
177
  // start_loop — returns operating instructions for the agent
162
- server.tool('start_loop', 'Start the agent loop. Call once to get operating instructions for running cron-claude as an autonomous daemon.', {}, (_args) => {
178
+ server.tool('start_loop', 'CALL THIS FIRST. Returns your complete operating instructions as the cron-claude executor, plus the current list of configured jobs. After calling this, begin the loop: every 60 seconds call get_due_jobs, spawn subagents for each returned job, each subagent calls mark_job_run when done.', {}, (_args) => {
163
179
  const jobs = listJobs().filter((j) => j.enabled);
164
180
  const jobList = jobs.length === 0
165
181
  ? '(no enabled jobs — add some with cron-claude add or the add_cron tool)'
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cron-claude",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Schedule Claude jobs in agent loop mode — no daemon, full tool access",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
package/dist/daemon.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import { Scheduler } from './scheduler.js';
2
- export declare class Daemon {
3
- private scheduler;
4
- private watcher;
5
- private configPath;
6
- constructor(configPath?: string);
7
- start(): void;
8
- stop(): void;
9
- getScheduler(): Scheduler;
10
- private loadAndSchedule;
11
- private watchConfig;
12
- }
13
- export declare function main(): void;
package/dist/daemon.js DELETED
@@ -1,104 +0,0 @@
1
- import fs from 'node:fs';
2
- import { loadConfig, getConfigPath, ensureConfigDir } from './config.js';
3
- import { Scheduler } from './scheduler.js';
4
- export class Daemon {
5
- scheduler;
6
- watcher = null;
7
- configPath;
8
- constructor(configPath) {
9
- this.configPath = configPath ?? getConfigPath();
10
- this.scheduler = new Scheduler({
11
- onJobStart: (job) => {
12
- console.log(`[cron-claude] Running job: ${job.id}`);
13
- },
14
- onJobComplete: (job, output) => {
15
- console.log(`[cron-claude] Job ${job.id} completed. Output: ${output.slice(0, 200)}`);
16
- },
17
- onJobError: (job, error) => {
18
- console.error(`[cron-claude] Job ${job.id} failed: ${error.message}`);
19
- },
20
- });
21
- }
22
- start() {
23
- ensureConfigDir();
24
- console.log('[cron-claude] Daemon starting...');
25
- this.loadAndSchedule();
26
- this.watchConfig();
27
- console.log('[cron-claude] Daemon running. Watching for config changes.');
28
- }
29
- stop() {
30
- console.log('[cron-claude] Daemon stopping...');
31
- this.scheduler.unscheduleAll();
32
- if (this.watcher) {
33
- this.watcher.close();
34
- this.watcher = null;
35
- }
36
- console.log('[cron-claude] Daemon stopped.');
37
- }
38
- getScheduler() {
39
- return this.scheduler;
40
- }
41
- loadAndSchedule() {
42
- try {
43
- const config = loadConfig(this.configPath);
44
- this.scheduler.unscheduleAll();
45
- for (const job of config.jobs) {
46
- try {
47
- this.scheduler.schedule(job);
48
- console.log(`[cron-claude] Scheduled: ${job.id} (${job.schedule})`);
49
- }
50
- catch (err) {
51
- console.error(`[cron-claude] Failed to schedule ${job.id}: ${err.message}`);
52
- }
53
- }
54
- console.log(`[cron-claude] ${this.scheduler.getScheduledIds().length} jobs scheduled.`);
55
- }
56
- catch (err) {
57
- console.error(`[cron-claude] Failed to load config: ${err.message}`);
58
- }
59
- }
60
- watchConfig() {
61
- let debounce = null;
62
- try {
63
- this.watcher = fs.watch(this.configPath, () => {
64
- if (debounce)
65
- clearTimeout(debounce);
66
- debounce = setTimeout(() => {
67
- console.log('[cron-claude] Config changed, reloading...');
68
- this.loadAndSchedule();
69
- }, 500);
70
- });
71
- }
72
- catch {
73
- console.warn('[cron-claude] Could not watch config file. Changes require restart.');
74
- }
75
- }
76
- }
77
- /* c8 ignore start */
78
- export function main() {
79
- const daemon = new Daemon();
80
- daemon.start();
81
- process.on('SIGINT', () => {
82
- daemon.stop();
83
- process.exit(0);
84
- });
85
- process.on('SIGTERM', () => {
86
- daemon.stop();
87
- process.exit(0);
88
- });
89
- // Safety net: log unhandled rejections instead of crashing the daemon.
90
- // Cron callbacks already catch their own rejections, so this should be rare.
91
- process.on('unhandledRejection', (reason) => {
92
- console.error('[cron-claude] Unhandled rejection (bug — please report):', reason);
93
- });
94
- process.on('uncaughtException', (err) => {
95
- console.error('[cron-claude] Uncaught exception (bug — please report):', err);
96
- // Don't exit — keep the daemon alive so cron jobs continue running
97
- });
98
- }
99
- const isMain = process.argv[1]?.endsWith('daemon.ts') || process.argv[1]?.endsWith('daemon.js');
100
- if (isMain) {
101
- main();
102
- }
103
- /* c8 ignore stop */
104
- //# sourceMappingURL=daemon.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- import { Job } from './config.js';
2
- export interface SchedulerOptions {
3
- claudePath?: string;
4
- onJobStart?: (job: Job) => void;
5
- onJobComplete?: (job: Job, output: string) => void;
6
- onJobError?: (job: Job, error: Error) => void;
7
- }
8
- export declare class Scheduler {
9
- private tasks;
10
- private options;
11
- constructor(options?: SchedulerOptions);
12
- getClaudePath(): string;
13
- schedule(job: Job): void;
14
- unschedule(jobId: string): void;
15
- unscheduleAll(): void;
16
- getScheduledIds(): string[];
17
- executeJob(job: Job): Promise<string>;
18
- private openTerminal;
19
- private logJobOutput;
20
- }
package/dist/scheduler.js DELETED
@@ -1,143 +0,0 @@
1
- import cron from 'node-cron';
2
- import { execFile, spawn } from 'node:child_process';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { getLogsDir } from './config.js';
6
- const CLAUDE_PATH = path.join(process.env.HOME || '~', '.local', 'bin', 'claude');
7
- export class Scheduler {
8
- tasks = new Map();
9
- options;
10
- constructor(options = {}) {
11
- this.options = options;
12
- }
13
- getClaudePath() {
14
- return this.options.claudePath ?? CLAUDE_PATH;
15
- }
16
- schedule(job) {
17
- if (!job.enabled)
18
- return;
19
- if (!cron.validate(job.schedule)) {
20
- throw new Error(`Invalid cron schedule for job "${job.id}": ${job.schedule}`);
21
- }
22
- // Stop existing task if re-scheduling
23
- this.unschedule(job.id);
24
- const task = cron.schedule(job.schedule, () => {
25
- this.executeJob(job).catch(() => {
26
- // Error already handled via onJobError callback; suppress unhandled rejection
27
- // to prevent Node.js from crashing the daemon on job failures
28
- });
29
- });
30
- this.tasks.set(job.id, task);
31
- }
32
- unschedule(jobId) {
33
- const existing = this.tasks.get(jobId);
34
- if (existing) {
35
- existing.stop();
36
- this.tasks.delete(jobId);
37
- }
38
- }
39
- unscheduleAll() {
40
- for (const [id] of this.tasks) {
41
- this.unschedule(id);
42
- }
43
- }
44
- getScheduledIds() {
45
- return Array.from(this.tasks.keys());
46
- }
47
- executeJob(job) {
48
- return new Promise((resolve, reject) => {
49
- this.options.onJobStart?.(job);
50
- if (job.headless) {
51
- // Headless: silent background execution, capture output to log file.
52
- // Use spawn with stdin='ignore' so claude doesn't wait for TTY input
53
- // (execFile leaves stdin open which causes silent hangs on rate limit errors).
54
- const args = [];
55
- if (job.dangerouslySkipPermissions)
56
- args.push('--dangerously-skip-permissions');
57
- args.push('--print', '--model', job.model, job.prompt);
58
- const claudePath = this.getClaudePath();
59
- const proc = spawn(claudePath, args, {
60
- stdio: ['ignore', 'pipe', 'pipe'],
61
- });
62
- let stdout = '';
63
- let stderr = '';
64
- proc.stdout.on('data', (chunk) => { stdout += chunk.toString(); });
65
- proc.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
66
- const timer = setTimeout(() => {
67
- proc.kill();
68
- }, 300000);
69
- proc.on('close', (code) => {
70
- clearTimeout(timer);
71
- const output = stdout || stderr || '';
72
- const error = code !== 0 ? new Error(`Command failed with code ${code}: ${output.trim()}`) : undefined;
73
- this.logJobOutput(job, output, error);
74
- if (error) {
75
- this.options.onJobError?.(job, error);
76
- reject(error);
77
- }
78
- else {
79
- this.options.onJobComplete?.(job, output);
80
- resolve(output);
81
- }
82
- });
83
- }
84
- else {
85
- // Non-headless: open a real Terminal window with an interactive claude session
86
- this.openTerminal(job, resolve, reject);
87
- }
88
- });
89
- }
90
- openTerminal(job, resolve, reject) {
91
- const claudePath = this.getClaudePath();
92
- const flags = job.dangerouslySkipPermissions ? '--dangerously-skip-permissions ' : '';
93
- const promptEscaped = job.prompt.replace(/'/g, "'\\''");
94
- const claudeCmd = `${claudePath} ${flags}--model ${job.model} '${promptEscaped}'`;
95
- // Write a temp script so we can open it cleanly in Terminal
96
- const tmpScript = path.join(process.env.HOME || '~', '.cron-claude', `run-${job.id}-${Date.now()}.sh`);
97
- try {
98
- fs.writeFileSync(tmpScript, `#!/bin/bash\necho "cron-claude: running job ${job.id}"\n${claudeCmd}\necho "\\ncron-claude: job ${job.id} finished. Press enter to close."\nread\nrm -f '${tmpScript}'\n`, { mode: 0o755 });
99
- }
100
- catch (err) {
101
- const error = err;
102
- this.options.onJobError?.(job, error);
103
- reject(error);
104
- return;
105
- }
106
- // open -a Terminal <script> opens the script in a new Terminal window
107
- execFile('open', ['-a', 'Terminal', tmpScript], { timeout: 10000 }, (error) => {
108
- if (error) {
109
- fs.unlink(tmpScript, () => { });
110
- this.options.onJobError?.(job, error);
111
- reject(error);
112
- }
113
- else {
114
- this.options.onJobComplete?.(job, 'Terminal window opened');
115
- resolve('Terminal window opened');
116
- }
117
- });
118
- }
119
- logJobOutput(job, output, error) {
120
- const logsDir = getLogsDir();
121
- try {
122
- if (!fs.existsSync(logsDir)) {
123
- fs.mkdirSync(logsDir, { recursive: true });
124
- }
125
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
126
- const logFile = path.join(logsDir, `${job.id}_${timestamp}.log`);
127
- const content = [
128
- `Job: ${job.id}`,
129
- `Time: ${new Date().toISOString()}`,
130
- `Schedule: ${job.schedule}`,
131
- `Model: ${job.model}`,
132
- error ? `Error: ${error.message}` : 'Status: success',
133
- `---`,
134
- output,
135
- ].join('\n');
136
- fs.writeFileSync(logFile, content, 'utf-8');
137
- }
138
- catch {
139
- // Logging failure shouldn't crash the daemon
140
- }
141
- }
142
- }
143
- //# sourceMappingURL=scheduler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}