@digitalpresence/cliclaw 0.1.2 → 0.2.1

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 (40) hide show
  1. package/dist/agent/crud.d.ts.map +1 -1
  2. package/dist/agent/crud.js +3 -4
  3. package/dist/agent/crud.js.map +1 -1
  4. package/dist/agent/memory.js +4 -4
  5. package/dist/agent/memory.js.map +1 -1
  6. package/dist/agent/permissions.d.ts +2 -2
  7. package/dist/agent/permissions.d.ts.map +1 -1
  8. package/dist/agent/permissions.js +16 -13
  9. package/dist/agent/permissions.js.map +1 -1
  10. package/dist/cli.js +2 -0
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/agent.d.ts.map +1 -1
  13. package/dist/commands/agent.js +4 -6
  14. package/dist/commands/agent.js.map +1 -1
  15. package/dist/commands/cron.js +4 -4
  16. package/dist/commands/cron.js.map +1 -1
  17. package/dist/commands/init.d.ts +3 -0
  18. package/dist/commands/init.d.ts.map +1 -0
  19. package/dist/commands/init.js +19 -0
  20. package/dist/commands/init.js.map +1 -0
  21. package/dist/cron/daemon.js +2 -2
  22. package/dist/cron/daemon.js.map +1 -1
  23. package/dist/cron/handlers.d.ts +1 -1
  24. package/dist/cron/handlers.d.ts.map +1 -1
  25. package/dist/cron/handlers.js +14 -5
  26. package/dist/cron/handlers.js.map +1 -1
  27. package/dist/cron/ralph-wiggum.d.ts.map +1 -1
  28. package/dist/cron/ralph-wiggum.js +109 -54
  29. package/dist/cron/ralph-wiggum.js.map +1 -1
  30. package/package.json +2 -2
  31. package/src/agent/crud.ts +3 -4
  32. package/src/agent/memory.ts +4 -4
  33. package/src/agent/permissions.ts +14 -17
  34. package/src/cli.ts +2 -0
  35. package/src/commands/agent.ts +4 -6
  36. package/src/commands/cron.ts +4 -4
  37. package/src/commands/init.ts +22 -0
  38. package/src/cron/daemon.ts +2 -2
  39. package/src/cron/handlers.ts +17 -6
  40. package/src/cron/ralph-wiggum.ts +131 -63
@@ -1,35 +1,95 @@
1
- import { query } from "@anthropic-ai/claude-agent-sdk";
2
- import { existsSync, mkdirSync, writeFileSync, readFileSync, realpathSync } from "fs";
3
- import { join, dirname } from "path";
4
- import { fileURLToPath } from "url";
1
+ import { spawn } from "child_process";
2
+ import { createInterface } from "readline";
3
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
4
+ import { join } from "path";
5
5
  import { getProgressFilePath, ensureCronDirs, writeRunningMarker, clearRunningMarker } from "./progress.js";
6
6
  import { cronLog } from "./logger.js";
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
7
  const CONTINUE_MARKER = "NEEDS_MORE_ITERATIONS";
8
+ const CONTAINER_IMAGE = "cliclaw-agent";
9
+ const CONTAINER_TIMEOUT_MS = 300_000; // 5 minutes per iteration
10
+ function loadTaskContent(store, agentName, job) {
11
+ const taskFilePath = join(store.workspacePath(agentName), "cron-tasks", job.taskFile);
12
+ if (existsSync(taskFilePath)) {
13
+ return readFileSync(taskFilePath, "utf-8");
14
+ }
15
+ return `Task file not found: ${job.taskFile}`;
16
+ }
17
+ /**
18
+ * Run a single iteration inside a Docker container.
19
+ * Returns parsed NDJSON events.
20
+ */
21
+ async function runContainerIteration(instancePath, prompt, sessionId) {
22
+ // Write session.json
23
+ writeFileSync(join(instancePath, "session.json"), JSON.stringify({ prompt, ...(sessionId ? { sessionId } : {}) }), "utf-8");
24
+ const args = [
25
+ "run", "--rm", "-i",
26
+ "-v", `${instancePath}:/instance`,
27
+ "--network=host",
28
+ "--cpus=2", "--memory=2g",
29
+ ];
30
+ // Pass API key
31
+ if (process.env.ANTHROPIC_API_KEY) {
32
+ args.push("-e", `ANTHROPIC_API_KEY=${process.env.ANTHROPIC_API_KEY}`);
33
+ }
34
+ args.push(CONTAINER_IMAGE);
35
+ return new Promise((resolve) => {
36
+ const child = spawn("docker", args, {
37
+ stdio: ["ignore", "pipe", "pipe"],
38
+ });
39
+ const timeout = setTimeout(() => {
40
+ child.kill("SIGTERM");
41
+ }, CONTAINER_TIMEOUT_MS);
42
+ const events = [];
43
+ const rl = createInterface({ input: child.stdout });
44
+ rl.on("line", (line) => {
45
+ if (!line.trim())
46
+ return;
47
+ try {
48
+ events.push(JSON.parse(line));
49
+ }
50
+ catch {
51
+ // skip malformed lines
52
+ }
53
+ });
54
+ let stderr = "";
55
+ child.stderr.on("data", (chunk) => {
56
+ stderr += chunk.toString();
57
+ });
58
+ child.on("close", (code) => {
59
+ clearTimeout(timeout);
60
+ rl.close();
61
+ if (stderr.trim()) {
62
+ console.error(`[ralph-wiggum] container stderr: ${stderr.trim()}`);
63
+ }
64
+ resolve({ events, exitCode: code ?? 1 });
65
+ });
66
+ });
67
+ }
10
68
  export async function executeRalphWiggumLoop(store, agentName, job, startedAt) {
11
69
  ensureCronDirs(agentName, job.id);
12
70
  writeRunningMarker(agentName, job.id, startedAt ?? new Date().toISOString());
13
- const workspacePath = store.workspacePath(agentName);
71
+ // Use the cron instance path
72
+ const instancesDir = join(store.workspacePath(agentName), "..", "..", "instances");
73
+ const cronInstancePath = join(instancesDir, agentName, "_cron");
74
+ // Ensure cron instance exists with necessary files
75
+ if (!existsSync(cronInstancePath)) {
76
+ mkdirSync(join(cronInstancePath, "workspace"), { recursive: true });
77
+ mkdirSync(join(cronInstancePath, "memory"), { recursive: true });
78
+ // Copy template files
79
+ const agentDir = store.workspacePath(agentName);
80
+ for (const file of ["SOUL.md", "ROLE.md"]) {
81
+ const src = join(agentDir, file);
82
+ if (existsSync(src)) {
83
+ writeFileSync(join(cronInstancePath, file), readFileSync(src, "utf-8"));
84
+ }
85
+ }
86
+ }
14
87
  const progressFile = getProgressFilePath(agentName, job.id);
88
+ const taskContent = loadTaskContent(store, agentName, job);
89
+ let totalCostUsd = 0;
90
+ let sessionId;
91
+ const transcript = [];
15
92
  try {
16
- // Ensure cliclaw CLI is in PATH
17
- const cleanEnv = { ...process.env };
18
- delete cleanEnv.CLAUDECODE;
19
- const monorepoRoot = join(__dirname, "..", "..", "..");
20
- const binScript = join(monorepoRoot, "packages", "cliclaw", "dist", "cli.js");
21
- if (existsSync(binScript)) {
22
- const resolvedBin = realpathSync(binScript);
23
- const localBin = join(workspacePath, ".bin");
24
- if (!existsSync(localBin))
25
- mkdirSync(localBin, { recursive: true });
26
- const wrapper = join(localBin, "cliclaw");
27
- writeFileSync(wrapper, `#!/bin/sh\nexec node "${resolvedBin}" "$@"\n`, { mode: 0o755 });
28
- cleanEnv.PATH = `${localBin}:${cleanEnv.PATH ?? ""}`;
29
- }
30
- let totalCostUsd = 0;
31
- let sessionId;
32
- const transcript = [];
33
93
  for (let iteration = 1; iteration <= job.maxIterations; iteration++) {
34
94
  cronLog("info", `Iteration ${iteration}/${job.maxIterations}`, agentName, job.id);
35
95
  // Clear the continue marker before each iteration
@@ -44,40 +104,30 @@ export async function executeRalphWiggumLoop(store, agentName, job, startedAt) {
44
104
  prompt = [
45
105
  `You are executing a scheduled task. Here are your instructions:`,
46
106
  ``,
47
- `${job.task}`,
107
+ taskContent,
48
108
  ``,
49
- `Write your output/progress to: ${progressFile}`,
109
+ `Write your output/progress to: /instance/workspace/progress.md`,
50
110
  ``,
51
- `If you CANNOT finish the task in this iteration and need to be re-invoked, write "${CONTINUE_MARKER}" anywhere in ${progressFile}. Otherwise, just complete the task normally — no special signal is needed.`,
111
+ `If you CANNOT finish the task in this iteration and need to be re-invoked, write "${CONTINUE_MARKER}" anywhere in the progress file. Otherwise, just complete the task normally — no special signal is needed.`,
52
112
  ].join("\n");
53
113
  }
54
114
  else {
55
115
  prompt = [
56
- `You are continuing a scheduled task. Read your progress file at: ${progressFile}`,
116
+ `You are continuing a scheduled task. Read your progress file at: /instance/workspace/progress.md`,
57
117
  `Continue from where you left off.`,
58
118
  ``,
59
- `Original task: ${job.task}`,
119
+ `Original task:`,
120
+ taskContent,
60
121
  ``,
61
- `If you CANNOT finish the task in this iteration and need to be re-invoked, write "${CONTINUE_MARKER}" anywhere in ${progressFile}. Otherwise, just complete the task normally — no special signal is needed.`,
122
+ `If you CANNOT finish the task in this iteration and need to be re-invoked, write "${CONTINUE_MARKER}" anywhere in the progress file. Otherwise, just complete the task normally — no special signal is needed.`,
62
123
  ].join("\n");
63
124
  }
64
- const conversation = query({
65
- prompt,
66
- options: {
67
- cwd: workspacePath,
68
- env: cleanEnv,
69
- systemPrompt: { type: "preset", preset: "claude_code" },
70
- settingSources: ["project"],
71
- includePartialMessages: true,
72
- allowedTools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
73
- ...(sessionId ? { resume: sessionId } : {}),
74
- },
75
- });
125
+ const { events } = await runContainerIteration(cronInstancePath, prompt, sessionId);
126
+ // Process events into transcript
76
127
  let currentToolInput = "";
77
- for await (const event of conversation) {
78
- const msg = event;
79
- if (msg.type === "stream_event" && msg.event) {
80
- const streamEvent = msg.event;
128
+ for (const event of events) {
129
+ if (event.type === "stream_event" && event.event) {
130
+ const streamEvent = event.event;
81
131
  if (streamEvent.type === "content_block_start" && streamEvent.content_block?.type === "tool_use") {
82
132
  transcript.push({ type: "tool", name: streamEvent.content_block.name ?? "unknown", done: false });
83
133
  currentToolInput = "";
@@ -109,25 +159,30 @@ export async function executeRalphWiggumLoop(store, agentName, job, startedAt) {
109
159
  currentToolInput = "";
110
160
  }
111
161
  }
112
- else if (msg.type === "tool_result") {
162
+ else if (event.type === "tool_result") {
113
163
  const lastTool = [...transcript].reverse().find((b) => b.type === "tool" && !b.done);
114
164
  if (lastTool && lastTool.type === "tool") {
115
165
  lastTool.done = true;
116
166
  }
117
167
  }
118
- else if (msg.type === "result") {
119
- if ("total_cost_usd" in msg) {
120
- totalCostUsd += msg.total_cost_usd ?? 0;
168
+ else if (event.type === "result") {
169
+ if (event.total_cost_usd) {
170
+ totalCostUsd += event.total_cost_usd;
121
171
  }
122
- if (msg.session_id) {
123
- sessionId = msg.session_id;
172
+ if (event.session_id) {
173
+ sessionId = event.session_id;
124
174
  }
125
175
  }
126
176
  }
127
177
  // Check if the agent needs more iterations by reading the progress file
128
- const needsMore = existsSync(progressFile) &&
178
+ // In container mode, progress is written to workspace/progress.md
179
+ const containerProgressFile = join(cronInstancePath, "workspace", "progress.md");
180
+ const needsMore = existsSync(containerProgressFile) &&
181
+ readFileSync(containerProgressFile, "utf-8").includes(CONTINUE_MARKER);
182
+ // Also check the original progress file location
183
+ const needsMoreOriginal = existsSync(progressFile) &&
129
184
  readFileSync(progressFile, "utf-8").includes(CONTINUE_MARKER);
130
- if (!needsMore) {
185
+ if (!needsMore && !needsMoreOriginal) {
131
186
  cronLog("info", `Task completed at iteration ${iteration}`, agentName, job.id);
132
187
  return { completed: true, iterations: iteration, totalCostUsd, transcript };
133
188
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ralph-wiggum.js","sourceRoot":"","sources":["../../src/cron/ralph-wiggum.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ralph-wiggum.js","sourceRoot":"","sources":["../../src/cron/ralph-wiggum.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalpresence/cliclaw",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "cliclaw": "./dist/cli.js"
@@ -13,7 +13,7 @@
13
13
  "mime-types": "^3.0.2",
14
14
  "node-cron": "^4.2.1",
15
15
  "open": "^10.1.0",
16
- "@digitalpresence/cliclaw-auth": "0.1.1"
16
+ "@digitalpresence/cliclaw-auth": "0.2.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/mime-types": "^3.0.1",
package/src/agent/crud.ts CHANGED
@@ -16,8 +16,7 @@ export async function handleAgentCreate(
16
16
  name,
17
17
  displayName,
18
18
  role,
19
- permissions: [],
20
- memory: [],
19
+ integrations: [],
21
20
  cronJobs: [],
22
21
  createdAt: now,
23
22
  updatedAt: now,
@@ -32,8 +31,8 @@ export async function handleAgentList(store: AgentStore): Promise<void> {
32
31
  agents.map((a) => ({
33
32
  name: a.name,
34
33
  displayName: a.displayName,
35
- permissions: a.permissions.length,
36
- memory: a.memory.length,
34
+ integrations: a.integrations.length,
35
+ cronJobs: a.cronJobs.length,
37
36
  })),
38
37
  );
39
38
  }
@@ -32,7 +32,7 @@ export async function handleAgentMemoryAdd(
32
32
  const importance = opts?.importance ? (parseInt(opts.importance, 10) as 1 | 2 | 3) : 2;
33
33
 
34
34
  const entry = memoryStore.add(fact, { tags, source, importance });
35
- store.regenerateClaudeMd(name);
35
+ store.regenerateContextMd(name);
36
36
 
37
37
  outputJson({ status: "added", name, entry });
38
38
  }
@@ -52,14 +52,14 @@ export async function handleAgentMemoryRemove(
52
52
 
53
53
  if (tag) {
54
54
  const removed = memoryStore.removeByTag(tag);
55
- store.regenerateClaudeMd(name);
55
+ store.regenerateContextMd(name);
56
56
  outputJson({ status: "removed", name, removedByTag: tag, count: removed });
57
57
  } else if (id) {
58
58
  const removed = memoryStore.remove(id);
59
59
  if (!removed) {
60
60
  outputError("memory_not_found", `Memory "${id}" not found`);
61
61
  }
62
- store.regenerateClaudeMd(name);
62
+ store.regenerateContextMd(name);
63
63
  outputJson({ status: "removed", name, id });
64
64
  } else {
65
65
  outputError("invalid_args", "Provide an ID or --tag to remove");
@@ -89,7 +89,7 @@ export async function handleAgentMemoryClear(store: AgentStore, name: string): P
89
89
 
90
90
  const memoryStore = store.getMemoryStore(name);
91
91
  const cleared = memoryStore.clear();
92
- store.regenerateClaudeMd(name);
92
+ store.regenerateContextMd(name);
93
93
 
94
94
  outputJson({ status: "cleared", name, cleared });
95
95
  }
@@ -5,50 +5,47 @@ export async function handleAgentGrant(
5
5
  store: AgentStore,
6
6
  name: string,
7
7
  integration: string,
8
- account: string,
9
8
  ): Promise<void> {
10
9
  const agent = store.get(name);
11
10
  if (!agent) {
12
11
  outputError("agent_not_found", `Agent "${name}" not found`);
12
+ return;
13
13
  }
14
14
 
15
- const exists = agent.permissions.some(
16
- (p) => p.integration === integration && p.account === account,
17
- );
18
- if (exists) {
19
- outputError("permission_exists", `Agent "${name}" already has ${integration}:${account}`);
15
+ if (agent.integrations.includes(integration)) {
16
+ outputError("integration_exists", `Agent "${name}" already has ${integration}`);
17
+ return;
20
18
  }
21
19
 
22
- agent.permissions.push({ integration, account });
20
+ agent.integrations.push(integration);
23
21
  agent.updatedAt = new Date().toISOString();
24
22
  store.save(agent);
25
- store.regenerateClaudeMd(name);
23
+ store.regenerateContextMd(name);
26
24
 
27
- outputJson({ status: "granted", name, integration, account });
25
+ outputJson({ status: "granted", name, integration });
28
26
  }
29
27
 
30
28
  export async function handleAgentRevoke(
31
29
  store: AgentStore,
32
30
  name: string,
33
31
  integration: string,
34
- account: string,
35
32
  ): Promise<void> {
36
33
  const agent = store.get(name);
37
34
  if (!agent) {
38
35
  outputError("agent_not_found", `Agent "${name}" not found`);
36
+ return;
39
37
  }
40
38
 
41
- const idx = agent.permissions.findIndex(
42
- (p) => p.integration === integration && p.account === account,
43
- );
39
+ const idx = agent.integrations.indexOf(integration);
44
40
  if (idx === -1) {
45
- outputError("permission_not_found", `Agent "${name}" does not have ${integration}:${account}`);
41
+ outputError("integration_not_found", `Agent "${name}" does not have ${integration}`);
42
+ return;
46
43
  }
47
44
 
48
- agent.permissions.splice(idx, 1);
45
+ agent.integrations.splice(idx, 1);
49
46
  agent.updatedAt = new Date().toISOString();
50
47
  store.save(agent);
51
- store.regenerateClaudeMd(name);
48
+ store.regenerateContextMd(name);
52
49
 
53
- outputJson({ status: "revoked", name, integration, account });
50
+ outputJson({ status: "revoked", name, integration });
54
51
  }
package/src/cli.ts CHANGED
@@ -10,6 +10,7 @@ import { registerCalendarCommands } from "./commands/calendar.js";
10
10
  import { registerFormsCommands } from "./commands/forms.js";
11
11
  import { registerAgentCommands } from "./commands/agent.js";
12
12
  import { registerCronCommands } from "./commands/cron.js";
13
+ import { registerInitCommand } from "./commands/init.js";
13
14
  import { outputError } from "./lib/output.js";
14
15
 
15
16
  function getClientManager(): { clientManager: OAuthClientManager; port: number } {
@@ -35,6 +36,7 @@ registerCalendarCommands(program, getClientManager);
35
36
  registerFormsCommands(program, getClientManager);
36
37
  registerAgentCommands(program, () => new AgentStore(getAgentsDir()));
37
38
  registerCronCommands(program, () => new AgentStore(getAgentsDir()));
39
+ registerInitCommand(program);
38
40
 
39
41
  program.parseAsync().catch((err) => {
40
42
  outputError("cli_error", err instanceof Error ? err.message : String(err));
@@ -50,22 +50,20 @@ export function registerAgentCommands(program: Command, getAgentStore: AgentStor
50
50
 
51
51
  agent
52
52
  .command("grant")
53
- .description("Grant a permission to an agent")
53
+ .description("Grant an integration to an agent")
54
54
  .argument("<name>", "Agent name")
55
55
  .requiredOption("--integration <integration>", "Integration name (gmail, gdrive)")
56
- .requiredOption("--account <account>", "Account name")
57
56
  .action(async (name, opts) => {
58
- await handleAgentGrant(getAgentStore(), name, opts.integration, opts.account);
57
+ await handleAgentGrant(getAgentStore(), name, opts.integration);
59
58
  });
60
59
 
61
60
  agent
62
61
  .command("revoke")
63
- .description("Revoke a permission from an agent")
62
+ .description("Revoke an integration from an agent")
64
63
  .argument("<name>", "Agent name")
65
64
  .requiredOption("--integration <integration>", "Integration name (gmail, gdrive)")
66
- .requiredOption("--account <account>", "Account name")
67
65
  .action(async (name, opts) => {
68
- await handleAgentRevoke(getAgentStore(), name, opts.integration, opts.account);
66
+ await handleAgentRevoke(getAgentStore(), name, opts.integration);
69
67
  });
70
68
 
71
69
  const memory = agent
@@ -22,17 +22,17 @@ export function registerCronCommands(program: Command, getAgentStore: AgentStore
22
22
  .description("Add a cron job to an agent")
23
23
  .argument("<agent>", "Agent name")
24
24
  .requiredOption("--schedule <schedule>", "Cron expression (e.g. \"0 9 * * *\")")
25
- .requiredOption("--task <task>", "Natural language task instructions")
25
+ .requiredOption("--task <task>", "Task description (written to markdown file)")
26
+ .option("--task-file <taskFile>", "Custom task file name (default: {jobId}.md)")
26
27
  .option("--max-iterations <n>", "Maximum loop iterations", "10")
27
- .option("--completion-promise <word>", "Completion word", "TASK_COMPLETE")
28
28
  .action(async (agent, opts) => {
29
29
  await handleCronAdd(
30
30
  getAgentStore(),
31
31
  agent,
32
32
  opts.schedule,
33
+ opts.taskFile || "",
33
34
  opts.task,
34
35
  parseInt(opts.maxIterations, 10),
35
- opts.completionPromise,
36
36
  );
37
37
  });
38
38
 
@@ -91,7 +91,7 @@ export function registerCronCommands(program: Command, getAgentStore: AgentStore
91
91
  const job = config!.cronJobs.find((j) => j.id === jobId);
92
92
  if (!job) outputError("job_not_found", `Job "${jobId}" not found`);
93
93
 
94
- cronLog("info", `Manual trigger: ${job!.task}`, agent, jobId);
94
+ cronLog("info", `Manual trigger: ${job!.taskFile}`, agent, jobId);
95
95
 
96
96
  const startedAt = new Date().toISOString();
97
97
  try {
@@ -0,0 +1,22 @@
1
+ import { Command } from "commander";
2
+ import { writeFileSync, existsSync, mkdirSync } from "fs";
3
+ import { join } from "path";
4
+ import { generateUniversalClaudeMd, getConfigDir } from "@digitalpresence/cliclaw-auth";
5
+ import { outputJson } from "../lib/output.js";
6
+
7
+ export function registerInitCommand(program: Command): void {
8
+ program
9
+ .command("init")
10
+ .description("Initialize/update the universal CLAUDE.md for all agents")
11
+ .action(async () => {
12
+ const configDir = getConfigDir();
13
+ if (!existsSync(configDir)) {
14
+ mkdirSync(configDir, { recursive: true });
15
+ }
16
+
17
+ const claudeMdPath = join(configDir, "CLAUDE.md");
18
+ writeFileSync(claudeMdPath, generateUniversalClaudeMd(), "utf-8");
19
+
20
+ outputJson({ status: "initialized", path: claudeMdPath });
21
+ });
22
+ }
@@ -51,7 +51,7 @@ export async function startDaemon(store: AgentStore): Promise<void> {
51
51
  }
52
52
 
53
53
  running.add(key);
54
- cronLog("info", `Executing: ${job.task}`, agentName, job.id);
54
+ cronLog("info", `Executing: ${job.taskFile}`, agentName, job.id);
55
55
  const startedAt = new Date().toISOString();
56
56
 
57
57
  try {
@@ -87,7 +87,7 @@ export async function startDaemon(store: AgentStore): Promise<void> {
87
87
  });
88
88
 
89
89
  schedules.set(key, task);
90
- cronLog("info", `Scheduled: "${job.task}" at ${job.schedule}`, agentName, job.id);
90
+ cronLog("info", `Scheduled: "${job.taskFile}" at ${job.schedule}`, agentName, job.id);
91
91
  }
92
92
 
93
93
  function syncSchedules(): void {
@@ -1,4 +1,6 @@
1
1
  import { randomBytes } from "crypto";
2
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
3
+ import { join } from "path";
2
4
  import type { AgentStore, CronJobConfig } from "@digitalpresence/cliclaw-auth";
3
5
  import { outputJson, outputError } from "../lib/output.js";
4
6
 
@@ -6,25 +8,34 @@ export async function handleCronAdd(
6
8
  store: AgentStore,
7
9
  agentName: string,
8
10
  schedule: string,
9
- task: string,
11
+ taskFile: string,
12
+ taskContent: string,
10
13
  maxIterations: number,
11
- completionPromise: string,
12
14
  ): Promise<void> {
13
15
  const agent = store.get(agentName);
14
16
  if (!agent) outputError("agent_not_found", `Agent "${agentName}" not found`);
15
17
 
18
+ const jobId = randomBytes(6).toString("hex");
19
+
20
+ // Write task markdown file
21
+ const cronTasksDir = join(store.workspacePath(agentName), "cron-tasks");
22
+ if (!existsSync(cronTasksDir)) {
23
+ mkdirSync(cronTasksDir, { recursive: true });
24
+ }
25
+ const taskFilePath = taskFile || `${jobId}.md`;
26
+ writeFileSync(join(cronTasksDir, taskFilePath), taskContent, "utf-8");
27
+
16
28
  const job: CronJobConfig = {
17
- id: randomBytes(6).toString("hex"),
29
+ id: jobId,
18
30
  schedule,
19
- task,
31
+ taskFile: taskFilePath,
20
32
  maxIterations,
21
- completionPromise,
22
33
  enabled: true,
23
34
  createdAt: new Date().toISOString(),
24
35
  };
25
36
 
26
37
  store.addCronJob(agentName, job);
27
- outputJson({ status: "added", jobId: job.id, schedule, task });
38
+ outputJson({ status: "added", jobId: job.id, schedule, taskFile: taskFilePath });
28
39
  }
29
40
 
30
41
  export async function handleCronRemove(