cf-claw 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +15 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +262 -0
- package/dist/agent.js.map +1 -0
- package/dist/agents.d.ts +51 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +478 -0
- package/dist/agents.js.map +1 -0
- package/dist/api/routes.d.ts +3 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +491 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/bot.d.ts +4 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +295 -0
- package/dist/bot.js.map +1 -0
- package/dist/canvas.d.ts +37 -0
- package/dist/canvas.d.ts.map +1 -0
- package/dist/canvas.js +47 -0
- package/dist/canvas.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +202 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +6 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +384 -0
- package/dist/commands.js.map +1 -0
- package/dist/components/TaskList.d.ts +7 -0
- package/dist/components/TaskList.d.ts.map +1 -0
- package/dist/components/TaskList.js +37 -0
- package/dist/components/TaskList.js.map +1 -0
- package/dist/config/encryption.d.ts +10 -0
- package/dist/config/encryption.d.ts.map +1 -0
- package/dist/config/encryption.js +111 -0
- package/dist/config/encryption.js.map +1 -0
- package/dist/config/json-config.d.ts +114 -0
- package/dist/config/json-config.d.ts.map +1 -0
- package/dist/config/json-config.js +388 -0
- package/dist/config/json-config.js.map +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +137 -0
- package/dist/config.js.map +1 -0
- package/dist/context/pruning.d.ts +30 -0
- package/dist/context/pruning.d.ts.map +1 -0
- package/dist/context/pruning.js +132 -0
- package/dist/context/pruning.js.map +1 -0
- package/dist/dashboard/404/index.html +1 -0
- package/dist/dashboard/404.html +1 -0
- package/dist/dashboard/_next/static/chunks/117-c657912d4a6fa056.js +2 -0
- package/dist/dashboard/_next/static/chunks/191-a6922264096cb3ad.js +11 -0
- package/dist/dashboard/_next/static/chunks/343-71498a8257bc1e81.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/_not-found/page-15cbe4395e02a084.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/layout-191efbc962809bb4.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/manual/page-3c401ecf89979cd7.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/page-dff55e58941a3c4d.js +1 -0
- package/dist/dashboard/_next/static/chunks/fd9d1056-9583fa19bc194043.js +1 -0
- package/dist/dashboard/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
- package/dist/dashboard/_next/static/chunks/main-2461f93106bcf687.js +1 -0
- package/dist/dashboard/_next/static/chunks/main-app-89f5ec28b3bb0e7f.js +1 -0
- package/dist/dashboard/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
- package/dist/dashboard/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
- package/dist/dashboard/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/dashboard/_next/static/chunks/webpack-616e068a201ad621.js +1 -0
- package/dist/dashboard/_next/static/css/baff0f221c10680b.css +3 -0
- package/dist/dashboard/_next/static/pyqPyo6dkz4uTWdfdFAOJ/_buildManifest.js +1 -0
- package/dist/dashboard/_next/static/pyqPyo6dkz4uTWdfdFAOJ/_ssgManifest.js +1 -0
- package/dist/dashboard/index.html +1 -0
- package/dist/dashboard/index.txt +7 -0
- package/dist/dashboard/manual/index.html +1 -0
- package/dist/dashboard/manual/index.txt +7 -0
- package/dist/documents.d.ts +20 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +227 -0
- package/dist/documents.js.map +1 -0
- package/dist/embeddings.d.ts +15 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +40 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/factory.d.ts +72 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +2010 -0
- package/dist/factory.js.map +1 -0
- package/dist/groups.d.ts +13 -0
- package/dist/groups.d.ts.map +1 -0
- package/dist/groups.js +42 -0
- package/dist/groups.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +223 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/taskStorage.d.ts +4 -0
- package/dist/lib/taskStorage.d.ts.map +1 -0
- package/dist/lib/taskStorage.js +28 -0
- package/dist/lib/taskStorage.js.map +1 -0
- package/dist/llm/anthropic.d.ts +13 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +96 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/failover.d.ts +13 -0
- package/dist/llm/failover.d.ts.map +1 -0
- package/dist/llm/failover.js +42 -0
- package/dist/llm/failover.js.map +1 -0
- package/dist/llm/google.d.ts +13 -0
- package/dist/llm/google.d.ts.map +1 -0
- package/dist/llm/google.js +112 -0
- package/dist/llm/google.js.map +1 -0
- package/dist/llm/groq.d.ts +8 -0
- package/dist/llm/groq.d.ts.map +1 -0
- package/dist/llm/groq.js +13 -0
- package/dist/llm/groq.js.map +1 -0
- package/dist/llm/index.d.ts +11 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +10 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/ollama.d.ts +9 -0
- package/dist/llm/ollama.d.ts.map +1 -0
- package/dist/llm/ollama.js +27 -0
- package/dist/llm/ollama.js.map +1 -0
- package/dist/llm/openai-compat.d.ts +17 -0
- package/dist/llm/openai-compat.d.ts.map +1 -0
- package/dist/llm/openai-compat.js +69 -0
- package/dist/llm/openai-compat.js.map +1 -0
- package/dist/llm/openrouter.d.ts +8 -0
- package/dist/llm/openrouter.d.ts.map +1 -0
- package/dist/llm/openrouter.js +20 -0
- package/dist/llm/openrouter.js.map +1 -0
- package/dist/llm/provider.d.ts +41 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +2 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/registry.d.ts +10 -0
- package/dist/llm/registry.d.ts.map +1 -0
- package/dist/llm/registry.js +90 -0
- package/dist/llm/registry.js.map +1 -0
- package/dist/llm/thinking.d.ts +7 -0
- package/dist/llm/thinking.d.ts.map +1 -0
- package/dist/llm/thinking.js +34 -0
- package/dist/llm/thinking.js.map +1 -0
- package/dist/llm.d.ts +17 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +184 -0
- package/dist/llm.js.map +1 -0
- package/dist/logs.d.ts +11 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +54 -0
- package/dist/logs.js.map +1 -0
- package/dist/memory/knowledge-graph.d.ts +34 -0
- package/dist/memory/knowledge-graph.d.ts.map +1 -0
- package/dist/memory/knowledge-graph.js +137 -0
- package/dist/memory/knowledge-graph.js.map +1 -0
- package/dist/memory.d.ts +73 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +320 -0
- package/dist/memory.js.map +1 -0
- package/dist/mesh.d.ts +18 -0
- package/dist/mesh.d.ts.map +1 -0
- package/dist/mesh.js +120 -0
- package/dist/mesh.js.map +1 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +51 -0
- package/dist/paths.js.map +1 -0
- package/dist/proactive/heartbeat.d.ts +4 -0
- package/dist/proactive/heartbeat.d.ts.map +1 -0
- package/dist/proactive/heartbeat.js +56 -0
- package/dist/proactive/heartbeat.js.map +1 -0
- package/dist/proactive/recap.d.ts +12 -0
- package/dist/proactive/recap.d.ts.map +1 -0
- package/dist/proactive/recap.js +90 -0
- package/dist/proactive/recap.js.map +1 -0
- package/dist/proactive/recommendations.d.ts +11 -0
- package/dist/proactive/recommendations.d.ts.map +1 -0
- package/dist/proactive/recommendations.js +92 -0
- package/dist/proactive/recommendations.js.map +1 -0
- package/dist/projects.d.ts +44 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +101 -0
- package/dist/projects.js.map +1 -0
- package/dist/scheduler/index.d.ts +17 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +116 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/sessions.d.ts +19 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +176 -0
- package/dist/sessions.js.map +1 -0
- package/dist/skills/index.d.ts +14 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +126 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/swarm.d.ts +18 -0
- package/dist/swarm.d.ts.map +1 -0
- package/dist/swarm.js +146 -0
- package/dist/swarm.js.map +1 -0
- package/dist/taskListWidget.d.ts +76 -0
- package/dist/taskListWidget.d.ts.map +1 -0
- package/dist/taskListWidget.js +312 -0
- package/dist/taskListWidget.js.map +1 -0
- package/dist/tools/browser.d.ts +5 -0
- package/dist/tools/browser.d.ts.map +1 -0
- package/dist/tools/browser.js +104 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/config-tools.d.ts +4 -0
- package/dist/tools/config-tools.d.ts.map +1 -0
- package/dist/tools/config-tools.js +154 -0
- package/dist/tools/config-tools.js.map +1 -0
- package/dist/tools/files.d.ts +3 -0
- package/dist/tools/files.d.ts.map +1 -0
- package/dist/tools/files.js +208 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +1109 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mcp-bridge.d.ts +5 -0
- package/dist/tools/mcp-bridge.d.ts.map +1 -0
- package/dist/tools/mcp-bridge.js +200 -0
- package/dist/tools/mcp-bridge.js.map +1 -0
- package/dist/tools/shell.d.ts +8 -0
- package/dist/tools/shell.d.ts.map +1 -0
- package/dist/tools/shell.js +78 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/skills-manage.d.ts +25 -0
- package/dist/tools/skills-manage.d.ts.map +1 -0
- package/dist/tools/skills-manage.js +155 -0
- package/dist/tools/skills-manage.js.map +1 -0
- package/dist/tools/web-search.d.ts +4 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +60 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tts.d.ts +6 -0
- package/dist/tts.d.ts.map +1 -0
- package/dist/tts.js +42 -0
- package/dist/tts.js.map +1 -0
- package/dist/types/task.d.ts +7 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +2 -0
- package/dist/types/task.js.map +1 -0
- package/dist/typing.d.ts +18 -0
- package/dist/typing.d.ts.map +1 -0
- package/dist/typing.js +63 -0
- package/dist/typing.js.map +1 -0
- package/dist/usage.d.ts +28 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +69 -0
- package/dist/usage.js.map +1 -0
- package/dist/voice.d.ts +6 -0
- package/dist/voice.d.ts.map +1 -0
- package/dist/voice.js +47 -0
- package/dist/voice.js.map +1 -0
- package/dist/webchat/index.d.ts +3 -0
- package/dist/webchat/index.d.ts.map +1 -0
- package/dist/webchat/index.js +3 -0
- package/dist/webchat/index.js.map +1 -0
- package/dist/webchat/public/index.html +344 -0
- package/dist/webchat/public/public/index.html +344 -0
- package/dist/webchat/public/public/task-list-widget.js +410 -0
- package/dist/webchat/public/task-list-widget.js +410 -0
- package/dist/webchat/server.d.ts +3 -0
- package/dist/webchat/server.d.ts.map +1 -0
- package/dist/webchat/server.js +80 -0
- package/dist/webchat/server.js.map +1 -0
- package/dist/webchat/ws.d.ts +4 -0
- package/dist/webchat/ws.d.ts.map +1 -0
- package/dist/webchat/ws.js +232 -0
- package/dist/webchat/ws.js.map +1 -0
- package/dist/webhooks/index.d.ts +14 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +86 -0
- package/dist/webhooks/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { config } from "../config.js";
|
|
2
|
+
import { listTasks } from "../scheduler/index.js";
|
|
3
|
+
const checks = [];
|
|
4
|
+
export function registerHeartbeatCheck(name, check) {
|
|
5
|
+
checks.push({ name, check });
|
|
6
|
+
}
|
|
7
|
+
let heartbeatInterval = null;
|
|
8
|
+
export function startHeartbeat(sendFn) {
|
|
9
|
+
if (heartbeatInterval)
|
|
10
|
+
return;
|
|
11
|
+
registerHeartbeatCheck("overdue_tasks", async () => {
|
|
12
|
+
const tasks = listTasks();
|
|
13
|
+
const enabled = tasks.filter((t) => t.enabled);
|
|
14
|
+
const overdue = enabled.filter((t) => {
|
|
15
|
+
if (!t.next_run)
|
|
16
|
+
return false;
|
|
17
|
+
return new Date(t.next_run) < new Date(Date.now() - 5 * 60 * 1000);
|
|
18
|
+
});
|
|
19
|
+
if (overdue.length > 0) {
|
|
20
|
+
return `⏰ ${overdue.length} scheduled task(s) overdue: ${overdue.map((t) => t.name).join(", ")}`;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
});
|
|
24
|
+
console.log(`💓 Heartbeat started (interval: ${config.heartbeatIntervalMs / 1000}s)`);
|
|
25
|
+
heartbeatInterval = setInterval(async () => {
|
|
26
|
+
try {
|
|
27
|
+
const notifications = [];
|
|
28
|
+
for (const check of checks) {
|
|
29
|
+
try {
|
|
30
|
+
const result = await check.check();
|
|
31
|
+
if (result) {
|
|
32
|
+
notifications.push(result);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.warn(`💓 Check "${check.name}" failed: ${err instanceof Error ? err.message : err}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (notifications.length > 0) {
|
|
40
|
+
const message = `💓 **Heartbeat Alert**\n\n${notifications.join("\n")}`;
|
|
41
|
+
await sendFn(message);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
console.error("💓 Heartbeat error:", err instanceof Error ? err.message : err);
|
|
46
|
+
}
|
|
47
|
+
}, config.heartbeatIntervalMs);
|
|
48
|
+
}
|
|
49
|
+
export function stopHeartbeat() {
|
|
50
|
+
if (heartbeatInterval) {
|
|
51
|
+
clearInterval(heartbeatInterval);
|
|
52
|
+
heartbeatInterval = null;
|
|
53
|
+
console.log("💓 Heartbeat stopped");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/proactive/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface RecapData {
|
|
2
|
+
messagesHandled: number;
|
|
3
|
+
summariesGenerated: number;
|
|
4
|
+
tasksCompleted: number;
|
|
5
|
+
pendingTasks: number;
|
|
6
|
+
topTopics: string[];
|
|
7
|
+
fullRecap: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function generateEveningRecap(): Promise<RecapData>;
|
|
10
|
+
export declare function scheduleEveningRecap(sendFn: (text: string) => Promise<void>): void;
|
|
11
|
+
export declare function cancelEveningRecap(): void;
|
|
12
|
+
//# sourceMappingURL=recap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recap.d.ts","sourceRoot":"","sources":["../../src/proactive/recap.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,SAAS;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,SAAS,CAAC,CAuD/D;AAID,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAuBlF;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { config } from "../config.js";
|
|
2
|
+
import { chatCompletion as registryChatCompletion } from "../llm/index.js";
|
|
3
|
+
import { getRecentMessages, getRecentSummaries, getAllFacts, } from "../memory.js";
|
|
4
|
+
import { listTasks } from "../scheduler/index.js";
|
|
5
|
+
function countTodaysMessages() {
|
|
6
|
+
const recent = getRecentMessages(100);
|
|
7
|
+
const today = new Date().toISOString().split("T")[0];
|
|
8
|
+
return recent.filter((m) => m.content && m.content.length > 0).length;
|
|
9
|
+
}
|
|
10
|
+
export async function generateEveningRecap() {
|
|
11
|
+
const messages = getRecentMessages(50);
|
|
12
|
+
const summaries = getRecentSummaries(10);
|
|
13
|
+
const facts = getAllFacts();
|
|
14
|
+
const tasks = listTasks();
|
|
15
|
+
const today = new Date().toLocaleDateString("sv-SE", {
|
|
16
|
+
weekday: "long",
|
|
17
|
+
year: "numeric",
|
|
18
|
+
month: "long",
|
|
19
|
+
day: "numeric",
|
|
20
|
+
timeZone: "Europe/Stockholm",
|
|
21
|
+
});
|
|
22
|
+
const recentContext = messages
|
|
23
|
+
.slice(-20)
|
|
24
|
+
.map((m) => `${m.role}: ${m.content}`)
|
|
25
|
+
.join("\n");
|
|
26
|
+
const pendingTasks = tasks.filter((t) => t.enabled);
|
|
27
|
+
const recapPrompt = `Generate a concise evening recap for today (${today}).
|
|
28
|
+
|
|
29
|
+
Recent messages:
|
|
30
|
+
${recentContext || "(no messages today)"}
|
|
31
|
+
|
|
32
|
+
Active tasks: ${pendingTasks.length}
|
|
33
|
+
Pending tasks: ${pendingTasks.map((t) => `- ${t.name}`).join("\n") || "none"}
|
|
34
|
+
|
|
35
|
+
Provide a brief, friendly summary covering:
|
|
36
|
+
1. Key topics discussed today
|
|
37
|
+
2. Tasks or actions completed
|
|
38
|
+
3. Pending items to follow up on
|
|
39
|
+
4. Any notable decisions or changes
|
|
40
|
+
|
|
41
|
+
Keep it conversational and under 200 words.`;
|
|
42
|
+
let recapText;
|
|
43
|
+
try {
|
|
44
|
+
const result = await registryChatCompletion({
|
|
45
|
+
messages: [{ role: "user", content: recapPrompt }],
|
|
46
|
+
});
|
|
47
|
+
recapText = result.content || "No recap generated.";
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
recapText = "Could not generate recap due to LLM error.";
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
messagesHandled: countTodaysMessages(),
|
|
54
|
+
summariesGenerated: summaries.length,
|
|
55
|
+
tasksCompleted: 0,
|
|
56
|
+
pendingTasks: pendingTasks.length,
|
|
57
|
+
topTopics: [],
|
|
58
|
+
fullRecap: recapText,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
let recapTimeout = null;
|
|
62
|
+
export function scheduleEveningRecap(sendFn) {
|
|
63
|
+
const now = new Date();
|
|
64
|
+
const recapTime = new Date();
|
|
65
|
+
recapTime.setHours(config.recapHour, 0, 0, 0);
|
|
66
|
+
if (recapTime <= now) {
|
|
67
|
+
recapTime.setDate(recapTime.getDate() + 1);
|
|
68
|
+
}
|
|
69
|
+
const msUntilRecap = recapTime.getTime() - now.getTime();
|
|
70
|
+
console.log(`📋 Evening recap scheduled for ${recapTime.toLocaleTimeString("sv-SE")} (${Math.round(msUntilRecap / 60000)} min from now)`);
|
|
71
|
+
recapTimeout = setTimeout(async () => {
|
|
72
|
+
try {
|
|
73
|
+
console.log("📋 Generating evening recap...");
|
|
74
|
+
const recap = await generateEveningRecap();
|
|
75
|
+
await sendFn(`📋 **Evening Recap**\n\n${recap.fullRecap}`);
|
|
76
|
+
console.log("📋 Evening recap sent");
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error("📋 Evening recap failed:", err instanceof Error ? err.message : err);
|
|
80
|
+
}
|
|
81
|
+
scheduleEveningRecap(sendFn);
|
|
82
|
+
}, msUntilRecap);
|
|
83
|
+
}
|
|
84
|
+
export function cancelEveningRecap() {
|
|
85
|
+
if (recapTimeout) {
|
|
86
|
+
clearTimeout(recapTimeout);
|
|
87
|
+
recapTimeout = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=recap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recap.js","sourceRoot":"","sources":["../../src/proactive/recap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface Recommendation {
|
|
2
|
+
type: string;
|
|
3
|
+
message: string;
|
|
4
|
+
confidence: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function trackMessage(role: string, content: string): void;
|
|
7
|
+
export declare function generateRecommendations(): Promise<Recommendation[]>;
|
|
8
|
+
export declare function startRecommendations(sendFn: (text: string) => Promise<void>): void;
|
|
9
|
+
export declare function stopRecommendations(): void;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=recommendations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.d.ts","sourceRoot":"","sources":["../../src/proactive/recommendations.ts"],"names":[],"mappings":"AAIA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAIhE;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAiDzE;AAID,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAkBlF;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { getAllFacts } from "../memory.js";
|
|
2
|
+
import { getEntityRelations, searchEntities } from "../memory/knowledge-graph.js";
|
|
3
|
+
const observedPatterns = [];
|
|
4
|
+
function updatePatterns(message) {
|
|
5
|
+
const words = message.toLowerCase().split(/\s+/);
|
|
6
|
+
const topicKeywords = words.filter((w) => w.length > 4).slice(0, 5);
|
|
7
|
+
for (const keyword of topicKeywords) {
|
|
8
|
+
const existing = observedPatterns.find((p) => p.topic === keyword);
|
|
9
|
+
if (existing) {
|
|
10
|
+
existing.frequency++;
|
|
11
|
+
existing.lastSeen = new Date();
|
|
12
|
+
}
|
|
13
|
+
else if (observedPatterns.length < 100) {
|
|
14
|
+
observedPatterns.push({ topic: keyword, frequency: 1, lastSeen: new Date() });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function trackMessage(role, content) {
|
|
19
|
+
if (role === "user") {
|
|
20
|
+
updatePatterns(content);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function generateRecommendations() {
|
|
24
|
+
const recommendations = [];
|
|
25
|
+
const frequentTopics = observedPatterns
|
|
26
|
+
.filter((p) => p.frequency >= 3)
|
|
27
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
28
|
+
.slice(0, 5);
|
|
29
|
+
if (frequentTopics.length > 0) {
|
|
30
|
+
const topics = frequentTopics.map((t) => `${t.topic} (${t.frequency}x)`).join(", ");
|
|
31
|
+
recommendations.push({
|
|
32
|
+
type: "frequent_topics",
|
|
33
|
+
message: `You've been asking about: ${topics}. Want me to set up a scheduled task or create a skill for this?`,
|
|
34
|
+
confidence: 0.7,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const kgEntities = searchEntities("", 5);
|
|
39
|
+
const entityNames = kgEntities.map((e) => e.name);
|
|
40
|
+
for (const name of entityNames) {
|
|
41
|
+
const relations = getEntityRelations(name);
|
|
42
|
+
if (relations.outgoing.length > 3) {
|
|
43
|
+
recommendations.push({
|
|
44
|
+
type: "knowledge_hub",
|
|
45
|
+
message: `"${name}" has many connections in your knowledge graph. Consider organizing or summarizing these relationships.`,
|
|
46
|
+
confidence: 0.5,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch { }
|
|
52
|
+
const facts = getAllFacts();
|
|
53
|
+
const oldFacts = facts.filter((f) => {
|
|
54
|
+
if (!f.updated_at)
|
|
55
|
+
return false;
|
|
56
|
+
const age = Date.now() - new Date(f.updated_at).getTime();
|
|
57
|
+
return age > 30 * 24 * 60 * 60 * 1000;
|
|
58
|
+
});
|
|
59
|
+
if (oldFacts.length > 0) {
|
|
60
|
+
recommendations.push({
|
|
61
|
+
type: "stale_facts",
|
|
62
|
+
message: `${oldFacts.length} fact(s) haven't been updated in 30+ days. Want me to review if they're still accurate?`,
|
|
63
|
+
confidence: 0.6,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return recommendations.filter((r) => r.confidence >= 0.5);
|
|
67
|
+
}
|
|
68
|
+
let recommendationInterval = null;
|
|
69
|
+
export function startRecommendations(sendFn) {
|
|
70
|
+
const INTERVAL = 30 * 60 * 1000;
|
|
71
|
+
recommendationInterval = setInterval(async () => {
|
|
72
|
+
try {
|
|
73
|
+
const recs = await generateRecommendations();
|
|
74
|
+
const highConfidence = recs.filter((r) => r.confidence >= 0.7);
|
|
75
|
+
if (highConfidence.length > 0) {
|
|
76
|
+
const messages = highConfidence.map((r) => `💡 ${r.message}`).join("\n\n");
|
|
77
|
+
await sendFn(messages);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
console.warn("💡 Recommendations error:", err instanceof Error ? err.message : err);
|
|
82
|
+
}
|
|
83
|
+
}, INTERVAL);
|
|
84
|
+
console.log("💡 Smart recommendations started");
|
|
85
|
+
}
|
|
86
|
+
export function stopRecommendations() {
|
|
87
|
+
if (recommendationInterval) {
|
|
88
|
+
clearInterval(recommendationInterval);
|
|
89
|
+
recommendationInterval = null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=recommendations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.js","sourceRoot":"","sources":["../../src/proactive/recommendations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface Project {
|
|
2
|
+
id: number;
|
|
3
|
+
title: string;
|
|
4
|
+
description: string;
|
|
5
|
+
status: string;
|
|
6
|
+
progress: number;
|
|
7
|
+
phase: string;
|
|
8
|
+
teams: string[];
|
|
9
|
+
taskCount: number;
|
|
10
|
+
completedTasks: number;
|
|
11
|
+
created_at: string;
|
|
12
|
+
updated_at: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ProjectTask {
|
|
15
|
+
id: number;
|
|
16
|
+
project_id: number;
|
|
17
|
+
title: string;
|
|
18
|
+
description: string;
|
|
19
|
+
status: string;
|
|
20
|
+
assignee: string | null;
|
|
21
|
+
sort_order: number;
|
|
22
|
+
created_at: string;
|
|
23
|
+
updated_at: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function createProject(data: {
|
|
26
|
+
title: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
status?: string;
|
|
29
|
+
phase?: string;
|
|
30
|
+
teams?: string[];
|
|
31
|
+
}): Project;
|
|
32
|
+
export declare function listProjects(): Project[];
|
|
33
|
+
export declare function updateProjectById(id: number, data: Partial<Pick<Project, "title" | "description" | "status" | "progress" | "phase" | "teams">>): Project | null;
|
|
34
|
+
export declare function deleteProject(id: number): boolean;
|
|
35
|
+
export declare function createProjectTask(projectId: number, data: {
|
|
36
|
+
title: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
status?: string;
|
|
39
|
+
assignee?: string;
|
|
40
|
+
}): ProjectTask | null;
|
|
41
|
+
export declare function listProjectTasks(projectId: number): ProjectTask[];
|
|
42
|
+
export declare function updateProjectTask(taskId: number, data: Partial<Pick<ProjectTask, "title" | "description" | "status" | "assignee">>): ProjectTask | null;
|
|
43
|
+
export declare function deleteProjectTask(taskId: number): boolean;
|
|
44
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../src/projects.ts"],"names":[],"mappings":"AA4DA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmBD,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,GAAG,OAAO,CAWV;AAED,wBAAgB,YAAY,IAAI,OAAO,EAAE,CAExC;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,GAChG,OAAO,GAAG,IAAI,CAahB;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAChF,WAAW,GAAG,IAAI,CAepB;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAEjE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC,GAChF,WAAW,GAAG,IAAI,CAWpB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|
package/dist/projects.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { getDataDir } from "./paths.js";
|
|
5
|
+
const DATA_DIR = getDataDir();
|
|
6
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
7
|
+
const DB_PATH = path.join(DATA_DIR, "cf-claw.db");
|
|
8
|
+
const db = new Database(DB_PATH);
|
|
9
|
+
db.exec(`
|
|
10
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
11
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
12
|
+
title TEXT NOT NULL,
|
|
13
|
+
description TEXT DEFAULT '',
|
|
14
|
+
status TEXT DEFAULT 'planning' CHECK(status IN ('planning','in_progress','review','completed','archived')),
|
|
15
|
+
progress INTEGER DEFAULT 0,
|
|
16
|
+
phase TEXT DEFAULT 'Planning',
|
|
17
|
+
teams TEXT DEFAULT '[]',
|
|
18
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
19
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
CREATE TABLE IF NOT EXISTS project_tasks (
|
|
23
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
24
|
+
project_id INTEGER NOT NULL,
|
|
25
|
+
title TEXT NOT NULL,
|
|
26
|
+
description TEXT DEFAULT '',
|
|
27
|
+
status TEXT DEFAULT 'backlog' CHECK(status IN ('backlog','working','review','done')),
|
|
28
|
+
assignee TEXT,
|
|
29
|
+
sort_order INTEGER DEFAULT 0,
|
|
30
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
31
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
32
|
+
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
|
33
|
+
);
|
|
34
|
+
`);
|
|
35
|
+
const insertProject = db.prepare("INSERT INTO projects (title, description, status, progress, phase, teams) VALUES (?, ?, ?, ?, ?, ?)");
|
|
36
|
+
const getAllProjects = db.prepare("SELECT * FROM projects ORDER BY updated_at DESC");
|
|
37
|
+
const getProjectById = db.prepare("SELECT * FROM projects WHERE id = ?");
|
|
38
|
+
const updateProject = db.prepare("UPDATE projects SET title = ?, description = ?, status = ?, progress = ?, phase = ?, teams = ?, updated_at = datetime('now') WHERE id = ?");
|
|
39
|
+
const deleteProjectStmt = db.prepare("DELETE FROM projects WHERE id = ?");
|
|
40
|
+
const insertTask = db.prepare("INSERT INTO project_tasks (project_id, title, description, status, assignee, sort_order) VALUES (?, ?, ?, ?, ?, ?)");
|
|
41
|
+
const getTasksByProject = db.prepare("SELECT * FROM project_tasks WHERE project_id = ? ORDER BY sort_order, id");
|
|
42
|
+
const updateTask = db.prepare("UPDATE project_tasks SET title = ?, description = ?, status = ?, assignee = ?, updated_at = datetime('now') WHERE id = ?");
|
|
43
|
+
const deleteTaskStmt = db.prepare("DELETE FROM project_tasks WHERE id = ?");
|
|
44
|
+
const getTaskCount = db.prepare("SELECT COUNT(*) as total, SUM(CASE WHEN status = 'done' THEN 1 ELSE 0 END) as completed FROM project_tasks WHERE project_id = ?");
|
|
45
|
+
function rowToProject(row) {
|
|
46
|
+
const counts = getTaskCount.get(row.id);
|
|
47
|
+
return {
|
|
48
|
+
id: row.id,
|
|
49
|
+
title: row.title,
|
|
50
|
+
description: row.description || "",
|
|
51
|
+
status: row.status,
|
|
52
|
+
progress: row.progress || 0,
|
|
53
|
+
phase: row.phase || "Planning",
|
|
54
|
+
teams: JSON.parse(row.teams || "[]"),
|
|
55
|
+
taskCount: counts?.total || 0,
|
|
56
|
+
completedTasks: counts?.completed || 0,
|
|
57
|
+
created_at: row.created_at,
|
|
58
|
+
updated_at: row.updated_at,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function createProject(data) {
|
|
62
|
+
const result = insertProject.run(data.title, data.description || "", data.status || "planning", 0, data.phase || "Planning", JSON.stringify(data.teams || []));
|
|
63
|
+
const row = getProjectById.get(Number(result.lastInsertRowid));
|
|
64
|
+
return rowToProject(row);
|
|
65
|
+
}
|
|
66
|
+
export function listProjects() {
|
|
67
|
+
return getAllProjects.all().map(rowToProject);
|
|
68
|
+
}
|
|
69
|
+
export function updateProjectById(id, data) {
|
|
70
|
+
const existing = getProjectById.get(id);
|
|
71
|
+
if (!existing)
|
|
72
|
+
return null;
|
|
73
|
+
updateProject.run(data.title ?? existing.title, data.description ?? existing.description, data.status ?? existing.status, data.progress ?? existing.progress, data.phase ?? existing.phase, JSON.stringify(data.teams ?? JSON.parse(existing.teams || "[]")), id);
|
|
74
|
+
return rowToProject(getProjectById.get(id));
|
|
75
|
+
}
|
|
76
|
+
export function deleteProject(id) {
|
|
77
|
+
return deleteProjectStmt.run(id).changes > 0;
|
|
78
|
+
}
|
|
79
|
+
export function createProjectTask(projectId, data) {
|
|
80
|
+
if (!getProjectById.get(projectId))
|
|
81
|
+
return null;
|
|
82
|
+
const maxOrder = db.prepare("SELECT COALESCE(MAX(sort_order), 0) + 1 as next FROM project_tasks WHERE project_id = ?").get(projectId);
|
|
83
|
+
insertTask.run(projectId, data.title, data.description || "", data.status || "backlog", data.assignee || null, maxOrder.next);
|
|
84
|
+
const tasks = getTasksByProject.all(projectId);
|
|
85
|
+
return tasks[tasks.length - 1];
|
|
86
|
+
}
|
|
87
|
+
export function listProjectTasks(projectId) {
|
|
88
|
+
return getTasksByProject.all(projectId);
|
|
89
|
+
}
|
|
90
|
+
export function updateProjectTask(taskId, data) {
|
|
91
|
+
const existing = db.prepare("SELECT * FROM project_tasks WHERE id = ?").get(taskId);
|
|
92
|
+
if (!existing)
|
|
93
|
+
return null;
|
|
94
|
+
updateTask.run(data.title ?? existing.title, data.description ?? existing.description, data.status ?? existing.status, data.assignee ?? existing.assignee, taskId);
|
|
95
|
+
return db.prepare("SELECT * FROM project_tasks WHERE id = ?").get(taskId);
|
|
96
|
+
}
|
|
97
|
+
export function deleteProjectTask(taskId) {
|
|
98
|
+
return deleteTaskStmt.run(taskId).changes > 0;
|
|
99
|
+
}
|
|
100
|
+
process.on("exit", () => db.close());
|
|
101
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../src/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ScheduledTask {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
cron_expr: string;
|
|
5
|
+
prompt: string;
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
last_run: string | null;
|
|
8
|
+
next_run: string | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function createTask(name: string, cronExpr: string, prompt: string): ScheduledTask;
|
|
11
|
+
export declare function listTasks(): ScheduledTask[];
|
|
12
|
+
export declare function pauseTask(id: number): boolean;
|
|
13
|
+
export declare function resumeTask(id: number): boolean;
|
|
14
|
+
export declare function deleteScheduledTask(id: number): boolean;
|
|
15
|
+
export declare function startScheduler(): void;
|
|
16
|
+
export declare function stopScheduler(): void;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AA+CA,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAwBD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAaxF;AAED,wBAAgB,SAAS,IAAI,aAAa,EAAE,CAE3C;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAG7C;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAI9C;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGvD;AAID,wBAAgB,cAAc,IAAI,IAAI,CA4BrC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAMpC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { CronExpressionParser } from "cron-parser";
|
|
5
|
+
import { runAgentLoop } from "../agent.js";
|
|
6
|
+
import { getDataDir } from "../paths.js";
|
|
7
|
+
const DATA_DIR = getDataDir();
|
|
8
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
9
|
+
const dbPath = path.join(DATA_DIR, "cf-claw.db");
|
|
10
|
+
const db = new Database(dbPath);
|
|
11
|
+
db.exec(`
|
|
12
|
+
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
13
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
14
|
+
name TEXT NOT NULL,
|
|
15
|
+
cron_expr TEXT NOT NULL,
|
|
16
|
+
prompt TEXT NOT NULL,
|
|
17
|
+
enabled INTEGER DEFAULT 1,
|
|
18
|
+
last_run TEXT,
|
|
19
|
+
next_run TEXT,
|
|
20
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
21
|
+
);
|
|
22
|
+
`);
|
|
23
|
+
const insertTask = db.prepare("INSERT INTO scheduled_tasks (name, cron_expr, prompt) VALUES (?, ?, ?)");
|
|
24
|
+
const getAllTasks = db.prepare("SELECT * FROM scheduled_tasks ORDER BY id");
|
|
25
|
+
const getEnabledTasks = db.prepare("SELECT * FROM scheduled_tasks WHERE enabled = 1");
|
|
26
|
+
const updateTaskRun = db.prepare("UPDATE scheduled_tasks SET last_run = datetime('now'), next_run = ? WHERE id = ?");
|
|
27
|
+
const toggleTask = db.prepare("UPDATE scheduled_tasks SET enabled = ? WHERE id = ?");
|
|
28
|
+
const deleteTask = db.prepare("DELETE FROM scheduled_tasks WHERE id = ?");
|
|
29
|
+
function parseCronMinutes(cronExpr) {
|
|
30
|
+
try {
|
|
31
|
+
const interval = CronExpressionParser.parse(cronExpr);
|
|
32
|
+
return interval.next().toDate().getTime();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function parseIntervalMinutes(cronExpr) {
|
|
39
|
+
const match = cronExpr.match(/^every\s+(\d+)\s*(?:min(?:ute)?s?)?$/i);
|
|
40
|
+
if (match) {
|
|
41
|
+
const mins = parseInt(match[1], 10);
|
|
42
|
+
return Date.now() + mins * 60 * 1000;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
function getNextRunMs(cronExpr) {
|
|
47
|
+
return parseCronMinutes(cronExpr) ?? parseIntervalMinutes(cronExpr) ?? (Date.now() + 60000);
|
|
48
|
+
}
|
|
49
|
+
export function createTask(name, cronExpr, prompt) {
|
|
50
|
+
const result = insertTask.run(name, cronExpr, prompt);
|
|
51
|
+
const nextRun = new Date(getNextRunMs(cronExpr)).toISOString();
|
|
52
|
+
updateTaskRun.run(nextRun, Number(result.lastInsertRowid));
|
|
53
|
+
return {
|
|
54
|
+
id: Number(result.lastInsertRowid),
|
|
55
|
+
name,
|
|
56
|
+
cron_expr: cronExpr,
|
|
57
|
+
prompt,
|
|
58
|
+
enabled: true,
|
|
59
|
+
last_run: null,
|
|
60
|
+
next_run: nextRun,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function listTasks() {
|
|
64
|
+
return getAllTasks.all();
|
|
65
|
+
}
|
|
66
|
+
export function pauseTask(id) {
|
|
67
|
+
toggleTask.run(0, id);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
export function resumeTask(id) {
|
|
71
|
+
const nextRun = new Date(Date.now() + 60000).toISOString();
|
|
72
|
+
toggleTask.run(1, id);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
export function deleteScheduledTask(id) {
|
|
76
|
+
deleteTask.run(id);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
let schedulerInterval = null;
|
|
80
|
+
export function startScheduler() {
|
|
81
|
+
if (schedulerInterval)
|
|
82
|
+
return;
|
|
83
|
+
console.log("⏰ Scheduler started (checking every 60s)");
|
|
84
|
+
schedulerInterval = setInterval(async () => {
|
|
85
|
+
try {
|
|
86
|
+
const tasks = getEnabledTasks.all();
|
|
87
|
+
const now = Date.now();
|
|
88
|
+
for (const task of tasks) {
|
|
89
|
+
const nextRun = task.next_run ? new Date(task.next_run).getTime() : 0;
|
|
90
|
+
if (nextRun > 0 && now >= nextRun) {
|
|
91
|
+
console.log(`⏰ Running scheduled task: ${task.name}`);
|
|
92
|
+
try {
|
|
93
|
+
await runAgentLoop(task.prompt);
|
|
94
|
+
console.log(`⏰ Task "${task.name}" completed`);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
console.error(`⏰ Task "${task.name}" failed: ${err instanceof Error ? err.message : err}`);
|
|
98
|
+
}
|
|
99
|
+
const next = getNextRunMs(task.cron_expr);
|
|
100
|
+
updateTaskRun.run(new Date(next).toISOString(), task.id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
console.error("⏰ Scheduler error:", err instanceof Error ? err.message : err);
|
|
106
|
+
}
|
|
107
|
+
}, 60000);
|
|
108
|
+
}
|
|
109
|
+
export function stopScheduler() {
|
|
110
|
+
if (schedulerInterval) {
|
|
111
|
+
clearInterval(schedulerInterval);
|
|
112
|
+
schedulerInterval = null;
|
|
113
|
+
console.log("⏰ Scheduler stopped");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface AgentSession {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
systemPrompt?: string;
|
|
5
|
+
createdAt: string;
|
|
6
|
+
lastActive: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SessionMessage {
|
|
9
|
+
role: string;
|
|
10
|
+
content: string;
|
|
11
|
+
toolCalls?: string;
|
|
12
|
+
toolCallId?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function sessionsCreate(name: string, systemPrompt?: string): AgentSession;
|
|
15
|
+
export declare function sessionsList(): AgentSession[];
|
|
16
|
+
export declare function sessionsHistory(sessionId: string, limit?: number): SessionMessage[];
|
|
17
|
+
export declare function sessionsDelete(sessionId: string): boolean;
|
|
18
|
+
export declare function sessionsSend(sessionId: string, message: string): Promise<string>;
|
|
19
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"AA2DA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,CAUhF;AAED,wBAAgB,YAAY,IAAI,YAAY,EAAE,CAS7C;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,cAAc,EAAE,CAQvF;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgHtF"}
|