@curie-agent/core 0.2.4 → 0.3.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/LICENSE +179 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/channel-router.js +1 -1
- package/dist/src/channel-router.js.map +1 -1
- package/dist/src/context.d.ts +11 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +80 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/cron-manager.d.ts +27 -8
- package/dist/src/cron-manager.d.ts.map +1 -1
- package/dist/src/cron-manager.js +121 -33
- package/dist/src/cron-manager.js.map +1 -1
- package/dist/src/event-bus.d.ts +71 -0
- package/dist/src/event-bus.d.ts.map +1 -1
- package/dist/src/event-bus.js.map +1 -1
- package/dist/src/heartbeat-delivery.d.ts +2 -0
- package/dist/src/heartbeat-delivery.d.ts.map +1 -1
- package/dist/src/heartbeat-delivery.js +20 -3
- package/dist/src/heartbeat-delivery.js.map +1 -1
- package/dist/src/heartbeat-executor.d.ts +36 -2
- package/dist/src/heartbeat-executor.d.ts.map +1 -1
- package/dist/src/heartbeat-executor.js +32 -40
- package/dist/src/heartbeat-executor.js.map +1 -1
- package/dist/src/identity-files.d.ts +29 -0
- package/dist/src/identity-files.d.ts.map +1 -0
- package/dist/src/identity-files.js +59 -0
- package/dist/src/identity-files.js.map +1 -0
- package/dist/src/index.d.ts +19 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +13 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/pricing.d.ts +29 -0
- package/dist/src/pricing.d.ts.map +1 -0
- package/dist/src/pricing.js +85 -0
- package/dist/src/pricing.js.map +1 -0
- package/dist/src/safety/command-guard.d.ts.map +1 -1
- package/dist/src/safety/command-guard.js +35 -1
- package/dist/src/safety/command-guard.js.map +1 -1
- package/dist/src/safety/path-guard.d.ts +7 -3
- package/dist/src/safety/path-guard.d.ts.map +1 -1
- package/dist/src/safety/path-guard.js +14 -5
- package/dist/src/safety/path-guard.js.map +1 -1
- package/dist/src/safety/snapshot.js +1 -1
- package/dist/src/safety/snapshot.js.map +1 -1
- package/dist/src/session-store.d.ts +3 -1
- package/dist/src/session-store.d.ts.map +1 -1
- package/dist/src/session-store.js +24 -1
- package/dist/src/session-store.js.map +1 -1
- package/dist/src/settings.d.ts +98 -1
- package/dist/src/settings.d.ts.map +1 -1
- package/dist/src/settings.js +363 -83
- package/dist/src/settings.js.map +1 -1
- package/dist/src/shell-detect.d.ts +12 -0
- package/dist/src/shell-detect.d.ts.map +1 -0
- package/dist/src/shell-detect.js +31 -0
- package/dist/src/shell-detect.js.map +1 -0
- package/dist/src/subagent-executor.d.ts +68 -0
- package/dist/src/subagent-executor.d.ts.map +1 -0
- package/dist/src/subagent-executor.js +289 -0
- package/dist/src/subagent-executor.js.map +1 -0
- package/dist/src/task-executor.d.ts +31 -0
- package/dist/src/task-executor.d.ts.map +1 -0
- package/dist/src/task-executor.js +91 -0
- package/dist/src/task-executor.js.map +1 -0
- package/dist/src/task-manager.d.ts +83 -0
- package/dist/src/task-manager.d.ts.map +1 -0
- package/dist/src/task-manager.js +308 -0
- package/dist/src/task-manager.js.map +1 -0
- package/dist/src/task-migration.d.ts +10 -0
- package/dist/src/task-migration.d.ts.map +1 -0
- package/dist/src/task-migration.js +144 -0
- package/dist/src/task-migration.js.map +1 -0
- package/dist/src/task-summary.d.ts +7 -0
- package/dist/src/task-summary.d.ts.map +1 -0
- package/dist/src/task-summary.js +34 -0
- package/dist/src/task-summary.js.map +1 -0
- package/dist/src/template-utils.d.ts +16 -0
- package/dist/src/template-utils.d.ts.map +1 -0
- package/dist/src/template-utils.js +72 -0
- package/dist/src/template-utils.js.map +1 -0
- package/dist/src/token-monitor.d.ts +50 -0
- package/dist/src/token-monitor.d.ts.map +1 -0
- package/dist/src/token-monitor.js +119 -0
- package/dist/src/token-monitor.js.map +1 -0
- package/dist/src/turn-loop.d.ts +10 -1
- package/dist/src/turn-loop.d.ts.map +1 -1
- package/dist/src/turn-loop.js +152 -23
- package/dist/src/turn-loop.js.map +1 -1
- package/dist/src/unified-task.d.ts +76 -0
- package/dist/src/unified-task.d.ts.map +1 -0
- package/dist/src/unified-task.js +196 -0
- package/dist/src/unified-task.js.map +1 -0
- package/package.json +16 -11
- package/templates/AGENTS.md +53 -0
- package/templates/HEARTBEAT.md +37 -0
- package/templates/MEMORY.md +29 -0
- package/templates/SOUL.md +28 -0
- package/templates/TOOLS.md +29 -0
- package/templates/USER.md +35 -0
- package/templates/WIKI.md +146 -0
- package/templates/settings.json +90 -0
- package/templates/skills/deep-research/SKILL.md +273 -0
- package/templates/skills/deep-research/references/report-structure.md +149 -0
- package/templates/skills/deep-research/references/topic-guides.md +151 -0
- package/templates/skills/planning/SKILL.md +222 -0
- package/templates/skills/planning/references/business.md +82 -0
- package/templates/skills/planning/references/creative.md +111 -0
- package/templates/skills/planning/references/events.md +109 -0
- package/templates/skills/planning/references/personal.md +107 -0
- package/templates/skills/planning/references/templates.md +279 -0
- package/templates/skills/wiki/SKILL.md +70 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified task manager — replaces CronManager as the primary task store.
|
|
3
|
+
* Manages tasks across both personal (~/.curie-agent/tasks.json) and project (<cwd>/tasks.json) scopes.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { dirname, join } from 'node:path';
|
|
8
|
+
import { scheduleLabel, createTaskDefaults, generateTaskId, taskTimestamp, pickNextSchedule, computeNextFire } from './unified-task.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Constants
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const DEFAULT_FILE = join(homedir(), '.curie-agent', 'tasks.json');
|
|
13
|
+
const DEFAULT_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// File I/O helpers
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
function loadTasksFile(filePath) {
|
|
18
|
+
if (existsSync(filePath)) {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(readFileSync(filePath, 'utf-8'));
|
|
21
|
+
if (typeof parsed === 'object' && parsed !== null && 'tasks' in parsed && Array.isArray(parsed.tasks)) {
|
|
22
|
+
return parsed;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* corrupt — start fresh */
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { $schema: 'tasks.schema.json', version: 1, tasks: [] };
|
|
30
|
+
}
|
|
31
|
+
function saveTasksFile(data, filePath) {
|
|
32
|
+
const dir = dirname(filePath);
|
|
33
|
+
if (!existsSync(dir)) {
|
|
34
|
+
mkdirSync(dir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
37
|
+
}
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// TaskManager class
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
export class TaskManager {
|
|
42
|
+
data;
|
|
43
|
+
/** TTL for pruning completed tasks. */
|
|
44
|
+
ttlMs;
|
|
45
|
+
/** File path for persistence. */
|
|
46
|
+
filePath;
|
|
47
|
+
/** Set of task IDs currently being executed (prevents re-firing). */
|
|
48
|
+
executing = new Set();
|
|
49
|
+
constructor(optTtlOrPath, optFilePath) {
|
|
50
|
+
if (typeof optTtlOrPath === 'string') {
|
|
51
|
+
this.filePath = optTtlOrPath;
|
|
52
|
+
this.ttlMs = DEFAULT_TTL_MS;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
this.ttlMs = optTtlOrPath ?? DEFAULT_TTL_MS;
|
|
56
|
+
this.filePath = optFilePath ?? DEFAULT_FILE;
|
|
57
|
+
}
|
|
58
|
+
this.data = loadTasksFile(this.filePath);
|
|
59
|
+
this.pruneOld(Date.now() - this.ttlMs);
|
|
60
|
+
}
|
|
61
|
+
/** Reload the file from disk. */
|
|
62
|
+
load() {
|
|
63
|
+
this.data = loadTasksFile(this.filePath);
|
|
64
|
+
return this.data;
|
|
65
|
+
}
|
|
66
|
+
/** Persist to disk. */
|
|
67
|
+
save() {
|
|
68
|
+
saveTasksFile(this.data, this.filePath);
|
|
69
|
+
}
|
|
70
|
+
// -----------------------------------------------------------------------
|
|
71
|
+
// Creation
|
|
72
|
+
// -----------------------------------------------------------------------
|
|
73
|
+
/** Create a new task with the given mode and scope. */
|
|
74
|
+
create(options) {
|
|
75
|
+
const defaults = createTaskDefaults(options.mode, options.scope);
|
|
76
|
+
const task = {
|
|
77
|
+
id: generateTaskId(),
|
|
78
|
+
title: options.title,
|
|
79
|
+
description: options.description ?? '',
|
|
80
|
+
status: 'scheduled_at' in options && options.scheduled_at ? (options.mode === 'human' ? 'todo' : 'pending') : defaults.status,
|
|
81
|
+
priority: options.priority ?? 'medium',
|
|
82
|
+
tags: options.tags ?? [],
|
|
83
|
+
mode: options.mode,
|
|
84
|
+
scheduled_at: options.scheduled_at,
|
|
85
|
+
frequency: options.frequency ?? null,
|
|
86
|
+
scope: options.scope,
|
|
87
|
+
metadata: options.metadata,
|
|
88
|
+
order: this.data.tasks.length,
|
|
89
|
+
created_at: taskTimestamp(),
|
|
90
|
+
completed_at: undefined,
|
|
91
|
+
};
|
|
92
|
+
if (task.status === 'done' || task.status === 'canceled') {
|
|
93
|
+
task.completed_at = taskTimestamp();
|
|
94
|
+
}
|
|
95
|
+
this.data.tasks.push(task);
|
|
96
|
+
this.save();
|
|
97
|
+
return task;
|
|
98
|
+
}
|
|
99
|
+
// -----------------------------------------------------------------------
|
|
100
|
+
// Status updates
|
|
101
|
+
// -----------------------------------------------------------------------
|
|
102
|
+
/** Update a task's status and set completed_at if terminal. */
|
|
103
|
+
updateTaskStatus(id, status) {
|
|
104
|
+
const task = this.findTask(id);
|
|
105
|
+
if (!task)
|
|
106
|
+
return false;
|
|
107
|
+
const oldStatus = task.status;
|
|
108
|
+
task.status = status;
|
|
109
|
+
const terminalStatuses = ['done', 'canceled', 'completed', 'failed'];
|
|
110
|
+
if (terminalStatuses.includes(status)) {
|
|
111
|
+
task.completed_at = taskTimestamp();
|
|
112
|
+
}
|
|
113
|
+
// For recurring auto tasks with frequency, reset to pending instead of done
|
|
114
|
+
if (task.frequency && status === 'done') {
|
|
115
|
+
task.status = 'pending';
|
|
116
|
+
delete task.completed_at;
|
|
117
|
+
}
|
|
118
|
+
this.save();
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/** Advance through the manual task lifecycle (todo → in_progress → done). */
|
|
122
|
+
setTaskStatus(id, status) {
|
|
123
|
+
return this.updateTaskStatus(id, status);
|
|
124
|
+
}
|
|
125
|
+
// -----------------------------------------------------------------------
|
|
126
|
+
// Query
|
|
127
|
+
// -----------------------------------------------------------------------
|
|
128
|
+
/** Find a single task by ID. */
|
|
129
|
+
findTask(id) {
|
|
130
|
+
return this.data.tasks.find((t) => t.id === id);
|
|
131
|
+
}
|
|
132
|
+
/** List tasks with optional filters. */
|
|
133
|
+
list(options) {
|
|
134
|
+
let tasks = [...this.data.tasks];
|
|
135
|
+
if (options?.status)
|
|
136
|
+
tasks = tasks.filter((t) => t.status === options.status);
|
|
137
|
+
if (options?.mode)
|
|
138
|
+
tasks = tasks.filter((t) => t.mode === options.mode);
|
|
139
|
+
if (options?.scope)
|
|
140
|
+
tasks = tasks.filter((t) => t.scope === options.scope);
|
|
141
|
+
if (options?.priority)
|
|
142
|
+
tasks = tasks.filter((t) => t.priority === options.priority);
|
|
143
|
+
// Sort: active first (backlog/todo/in_progress/pending), then done/canceled
|
|
144
|
+
const activeStatuses = new Set(['backlog', 'todo', 'in_progress', 'pending']);
|
|
145
|
+
tasks.sort((a, b) => {
|
|
146
|
+
const aActive = activeStatuses.has(a.status) ? 0 : 1;
|
|
147
|
+
const bActive = activeStatuses.has(b.status) ? 0 : 1;
|
|
148
|
+
if (aActive !== bActive)
|
|
149
|
+
return aActive - bActive;
|
|
150
|
+
return a.order - b.order;
|
|
151
|
+
});
|
|
152
|
+
return tasks;
|
|
153
|
+
}
|
|
154
|
+
/** Get pending scheduled tasks that are due (mode=auto or notify with scheduled_at <= now). */
|
|
155
|
+
getNextTasks(now) {
|
|
156
|
+
const reference = now ?? Date.now();
|
|
157
|
+
return this.data.tasks.filter((t) => {
|
|
158
|
+
if (t.status !== 'pending')
|
|
159
|
+
return false;
|
|
160
|
+
if (!t.scheduled_at)
|
|
161
|
+
return false;
|
|
162
|
+
if (this.executing.has(t.id))
|
|
163
|
+
return false;
|
|
164
|
+
return t.scheduled_at <= reference;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// -----------------------------------------------------------------------
|
|
168
|
+
// Lifecycle helpers (for daemon integration)
|
|
169
|
+
// -----------------------------------------------------------------------
|
|
170
|
+
/** Mark a task as currently executing. */
|
|
171
|
+
markExecuting(id) {
|
|
172
|
+
const task = this.findTask(id);
|
|
173
|
+
if (!task)
|
|
174
|
+
return false;
|
|
175
|
+
task.status = 'executing';
|
|
176
|
+
this.executing.add(id);
|
|
177
|
+
this.save();
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
/** Clear executing flag for a task. */
|
|
181
|
+
clearExecuting(id) {
|
|
182
|
+
this.executing.delete(id);
|
|
183
|
+
}
|
|
184
|
+
// -----------------------------------------------------------------------
|
|
185
|
+
// Deletion
|
|
186
|
+
// -----------------------------------------------------------------------
|
|
187
|
+
/** Cancel (soft-delete) a pending/fired task. */
|
|
188
|
+
cancelTask(id) {
|
|
189
|
+
const task = this.findTask(id);
|
|
190
|
+
if (!task)
|
|
191
|
+
return false;
|
|
192
|
+
task.status = 'canceled';
|
|
193
|
+
task.completed_at = taskTimestamp();
|
|
194
|
+
this.save();
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
/** Remove completed/fired/failed tasks (hard-delete). */
|
|
198
|
+
clearCompleted() {
|
|
199
|
+
const before = this.data.tasks.length;
|
|
200
|
+
this.data.tasks = this.data.tasks.filter((t) => t.status !== 'done' && t.status !== 'canceled' && t.status !== 'completed' && t.status !== 'failed');
|
|
201
|
+
const removed = before - this.data.tasks.length;
|
|
202
|
+
if (removed > 0) {
|
|
203
|
+
// Renormalize orders after removal
|
|
204
|
+
this.renormalizeOrders();
|
|
205
|
+
this.save();
|
|
206
|
+
}
|
|
207
|
+
return removed;
|
|
208
|
+
}
|
|
209
|
+
/** Remove a task permanently. */
|
|
210
|
+
removeTask(id) {
|
|
211
|
+
const idx = this.data.tasks.findIndex((t) => t.id === id);
|
|
212
|
+
if (idx === -1)
|
|
213
|
+
return false;
|
|
214
|
+
this.data.tasks.splice(idx, 1);
|
|
215
|
+
this.renormalizeOrders();
|
|
216
|
+
this.save();
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
/** Renormalize the `order` field for all tasks in scope. */
|
|
220
|
+
renormalizeOrders() {
|
|
221
|
+
let order = 0;
|
|
222
|
+
for (const task of this.data.tasks) {
|
|
223
|
+
task.order = order++;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// -----------------------------------------------------------------------
|
|
227
|
+
// Pruning
|
|
228
|
+
// -----------------------------------------------------------------------
|
|
229
|
+
/** Remove completed tasks older than the cutoff. Pending/pending-like tasks always kept. */
|
|
230
|
+
pruneOld(cutoff) {
|
|
231
|
+
const before = this.data.tasks.length;
|
|
232
|
+
this.data.tasks = this.data.tasks.filter((t) => t.status === 'pending' || (t.scheduled_at && t.scheduled_at > cutoff) || t.created_at > new Date(cutoff).toISOString());
|
|
233
|
+
// Actually, prune by timestamp: keep pending tasks forever, remove old completed ones
|
|
234
|
+
this.data.tasks = this.data.tasks.filter((t) => {
|
|
235
|
+
if (t.status === 'pending')
|
|
236
|
+
return true;
|
|
237
|
+
if (!t.completed_at)
|
|
238
|
+
return t.created_at > new Date(cutoff).toISOString();
|
|
239
|
+
const completedTime = new Date(t.completed_at).getTime();
|
|
240
|
+
return completedTime >= cutoff;
|
|
241
|
+
});
|
|
242
|
+
const removed = before - this.data.tasks.length;
|
|
243
|
+
if (removed > 0) {
|
|
244
|
+
this.renormalizeOrders();
|
|
245
|
+
this.save();
|
|
246
|
+
}
|
|
247
|
+
return removed;
|
|
248
|
+
}
|
|
249
|
+
/** Count of pending tasks. */
|
|
250
|
+
get pendingCount() {
|
|
251
|
+
return this.data.tasks.filter((t) => t.status === 'pending').length;
|
|
252
|
+
}
|
|
253
|
+
// -----------------------------------------------------------------------
|
|
254
|
+
// Heartbeat helpers
|
|
255
|
+
// -----------------------------------------------------------------------
|
|
256
|
+
/** Check if a task is a recurring heartbeat (auto mode with frequency). */
|
|
257
|
+
isHeartbeat(task) {
|
|
258
|
+
return task.mode === 'agent' && task.frequency !== null;
|
|
259
|
+
}
|
|
260
|
+
/** Get all pending heartbeat tasks. */
|
|
261
|
+
getHeartbeats() {
|
|
262
|
+
return this.data.tasks.filter((t) => t.mode === 'agent' && t.frequency !== null && t.status === 'pending');
|
|
263
|
+
}
|
|
264
|
+
// -----------------------------------------------------------------------
|
|
265
|
+
// Heartbeat schedule management
|
|
266
|
+
// -----------------------------------------------------------------------
|
|
267
|
+
/**
|
|
268
|
+
* Evaluate all five heartbeat schedule settings and ensure exactly one
|
|
269
|
+
* pending auto+frequency task exists in the store. Called after settings change.
|
|
270
|
+
*/
|
|
271
|
+
rescheduleFromSettings(settings, now) {
|
|
272
|
+
const ref = now ?? Date.now();
|
|
273
|
+
const picked = pickNextSchedule(settings, ref);
|
|
274
|
+
if (!picked)
|
|
275
|
+
return;
|
|
276
|
+
const all = this.getHeartbeats();
|
|
277
|
+
const [primary, ...extras] = all;
|
|
278
|
+
for (const extra of extras) {
|
|
279
|
+
this.updateTaskStatus(extra.id, 'canceled');
|
|
280
|
+
}
|
|
281
|
+
if (primary) {
|
|
282
|
+
primary.frequency = picked;
|
|
283
|
+
primary.title = `Heartbeat: ${scheduleLabel(picked.type)}`;
|
|
284
|
+
primary.scheduled_at = computeNextFire(picked, ref);
|
|
285
|
+
this.save();
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
this.create({
|
|
289
|
+
title: `Heartbeat: ${scheduleLabel(picked.type)}`,
|
|
290
|
+
mode: 'agent',
|
|
291
|
+
scope: 'personal',
|
|
292
|
+
scheduled_at: computeNextFire(picked, ref),
|
|
293
|
+
frequency: picked,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/** Cancel all pending heartbeat tasks. Returns count cancelled. */
|
|
298
|
+
cancelAllHeartbeats() {
|
|
299
|
+
const hbs = this.getHeartbeats();
|
|
300
|
+
let count = 0;
|
|
301
|
+
for (const hb of hbs) {
|
|
302
|
+
this.updateTaskStatus(hb.id, 'canceled');
|
|
303
|
+
count++;
|
|
304
|
+
}
|
|
305
|
+
return count;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=task-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-manager.js","sourceRoot":"","sources":["../../src/task-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration utility: reads old todo.json and cron.json, writes tasks.json.
|
|
3
|
+
* Runs once — if tasks.json already exists, migration is skipped.
|
|
4
|
+
*/
|
|
5
|
+
import type { TasksFile } from './unified-task.js';
|
|
6
|
+
/**
|
|
7
|
+
* Main migration: merges todo.json and cron.json into tasks.json.
|
|
8
|
+
*/
|
|
9
|
+
export declare function migrateTasks(oldTodoPath?: string, oldCronPath?: string, newTasksPath?: string): TasksFile | null;
|
|
10
|
+
//# sourceMappingURL=task-migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-migration.d.ts","sourceRoot":"","sources":["../../src/task-migration.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAkD,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAqGnG;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CA0EhH"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration utility: reads old todo.json and cron.json, writes tasks.json.
|
|
3
|
+
* Runs once — if tasks.json already exists, migration is skipped.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { taskTimestamp } from './unified-task.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Status mappings
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/** Map old todo.json status → UnifiedTask status. */
|
|
13
|
+
function mapTodoStatus(status) {
|
|
14
|
+
switch (status) {
|
|
15
|
+
case 'backlog': return 'backlog';
|
|
16
|
+
case 'todo': return 'todo';
|
|
17
|
+
case 'in_progress': return 'in_progress';
|
|
18
|
+
case 'done': return 'done';
|
|
19
|
+
case 'canceled': return 'canceled';
|
|
20
|
+
default: return 'todo';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Map old cron.json type → UnifiedTask mode. */
|
|
24
|
+
function mapCronType(type) {
|
|
25
|
+
switch (type) {
|
|
26
|
+
case 'reminder': return 'notify';
|
|
27
|
+
case 'task': return 'agent';
|
|
28
|
+
case 'heartbeat': return 'agent';
|
|
29
|
+
default: return 'agent';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Map old cron.json status → UnifiedTask status. */
|
|
33
|
+
function mapCronStatus(status) {
|
|
34
|
+
switch (status) {
|
|
35
|
+
case 'pending': return 'pending';
|
|
36
|
+
case 'fired': return 'done'; // already notified
|
|
37
|
+
case 'executing': return 'pending'; // still pending in new model (daemon will run it)
|
|
38
|
+
case 'completed': return 'done';
|
|
39
|
+
case 'failed': return 'canceled';
|
|
40
|
+
case 'cancelled': return 'canceled';
|
|
41
|
+
default: return 'pending';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Migration functions
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
function readLegacyTodo(filePath) {
|
|
48
|
+
if (!filePath)
|
|
49
|
+
return null;
|
|
50
|
+
try {
|
|
51
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
52
|
+
return JSON.parse(raw);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function readLegacyCron(filePath) {
|
|
59
|
+
if (!filePath)
|
|
60
|
+
return null;
|
|
61
|
+
try {
|
|
62
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
63
|
+
return JSON.parse(raw);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Main migration: merges todo.json and cron.json into tasks.json.
|
|
71
|
+
*/
|
|
72
|
+
export function migrateTasks(oldTodoPath, oldCronPath, newTasksPath) {
|
|
73
|
+
const target = newTasksPath || join(homedir(), '.curie-agent', 'tasks.json');
|
|
74
|
+
// Skip if already migrated (file exists)
|
|
75
|
+
try {
|
|
76
|
+
if (readFileSync(target, 'utf-8').trim().length > 0)
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
/* target doesn't exist yet — proceed */
|
|
81
|
+
}
|
|
82
|
+
const newFile = { $schema: 'tasks.schema.json', version: 1, tasks: [] };
|
|
83
|
+
let order = 0;
|
|
84
|
+
// Migrate todo.json → human tasks
|
|
85
|
+
const todoPaths = [oldTodoPath, join(homedir(), '.curie-agent', 'todo.json')].filter(Boolean);
|
|
86
|
+
for (const filePath of todoPaths) {
|
|
87
|
+
const legacy = readLegacyTodo(filePath);
|
|
88
|
+
if (!legacy)
|
|
89
|
+
continue;
|
|
90
|
+
const scope = filePath.includes('.curie-agent') ? 'personal' : 'project';
|
|
91
|
+
for (const t of legacy.tasks || []) {
|
|
92
|
+
newFile.tasks.push({
|
|
93
|
+
id: t.id,
|
|
94
|
+
title: t.title,
|
|
95
|
+
description: t.description ?? '',
|
|
96
|
+
status: mapTodoStatus(t.status ?? ''),
|
|
97
|
+
priority: t.priority ?? 'medium',
|
|
98
|
+
tags: t.tags ?? [],
|
|
99
|
+
mode: 'human',
|
|
100
|
+
scheduled_at: undefined,
|
|
101
|
+
frequency: null,
|
|
102
|
+
result: undefined,
|
|
103
|
+
scope,
|
|
104
|
+
order: order++,
|
|
105
|
+
created_at: t.created_at ?? taskTimestamp(),
|
|
106
|
+
completed_at: t.status === 'done' ? new Date().toISOString() : undefined,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Migrate cron.json → auto/notify tasks
|
|
111
|
+
const cronPaths = [oldCronPath, join(homedir(), '.curie-agent', 'cron.json')].filter(Boolean);
|
|
112
|
+
for (const filePath of cronPaths) {
|
|
113
|
+
const legacy = readLegacyCron(filePath);
|
|
114
|
+
if (!legacy)
|
|
115
|
+
continue;
|
|
116
|
+
for (const t of legacy.tasks || []) {
|
|
117
|
+
// Skip already-fired tasks from migration (they've been delivered)
|
|
118
|
+
const status = mapCronStatus(t.status);
|
|
119
|
+
if (status === 'done' && !t.message.includes('Heartbeat'))
|
|
120
|
+
continue;
|
|
121
|
+
newFile.tasks.push({
|
|
122
|
+
id: t.id,
|
|
123
|
+
title: t.message,
|
|
124
|
+
description: '',
|
|
125
|
+
status,
|
|
126
|
+
priority: 'medium',
|
|
127
|
+
tags: [],
|
|
128
|
+
mode: mapCronType(t.type),
|
|
129
|
+
scheduled_at: t.scheduledAt || undefined,
|
|
130
|
+
frequency: t.schedule ? { type: t.schedule.type, value: t.schedule.value } : null,
|
|
131
|
+
result: t.status === 'completed' ? `Completed (${t.message})` : undefined,
|
|
132
|
+
scope: 'personal', // cron tasks are always personal
|
|
133
|
+
order: order++,
|
|
134
|
+
created_at: new Date(t.createdAt).toISOString(),
|
|
135
|
+
completed_at: status === 'done' || status === 'canceled' ? new Date().toISOString() : undefined,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (!newFile.tasks.length)
|
|
140
|
+
return null; // nothing to migrate
|
|
141
|
+
writeFileSync(target, JSON.stringify(newFile, null, 2), 'utf-8');
|
|
142
|
+
return newFile;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=task-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-migration.js","sourceRoot":"","sources":["../../src/task-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for reading and summarizing tasks from JSON files.
|
|
3
|
+
* Replaces the duplicate readTodoSummary() functions in task-executor.ts and heartbeat-executor.ts.
|
|
4
|
+
*/
|
|
5
|
+
/** Format active tasks as a summary string for context prompts. */
|
|
6
|
+
export declare function readTaskSummary(filePath: string): string;
|
|
7
|
+
//# sourceMappingURL=task-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-summary.d.ts","sourceRoot":"","sources":["../../src/task-summary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+BxD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility for reading and summarizing tasks from JSON files.
|
|
3
|
+
* Replaces the duplicate readTodoSummary() functions in task-executor.ts and heartbeat-executor.ts.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
/** Format active tasks as a summary string for context prompts. */
|
|
7
|
+
export function readTaskSummary(filePath) {
|
|
8
|
+
try {
|
|
9
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
10
|
+
const data = JSON.parse(raw);
|
|
11
|
+
if (typeof data !== 'object' || data === null || !('tasks' in data))
|
|
12
|
+
return '(corrupt tasks.json)';
|
|
13
|
+
const file = data;
|
|
14
|
+
if (!Array.isArray(file.tasks) || !file.tasks.length)
|
|
15
|
+
return '(empty)';
|
|
16
|
+
// Show non-done/non-canceled tasks sorted by order
|
|
17
|
+
const active = file.tasks.filter((t) => t.status && !['done', 'canceled'].includes(t.status));
|
|
18
|
+
active.sort((a, b) => a.order - b.order);
|
|
19
|
+
if (!active.length) {
|
|
20
|
+
const doneCount = file.tasks.filter((t) => t.status === 'done').length;
|
|
21
|
+
return `All ${file.tasks.length} task(s) complete (${doneCount} done).`;
|
|
22
|
+
}
|
|
23
|
+
const lines = active.map((t) => {
|
|
24
|
+
const icon = t.status === 'in_progress' ? '[*]' : '-';
|
|
25
|
+
const priority = t.priority && t.priority !== 'medium' ? ` [${t.priority}]` : '';
|
|
26
|
+
return `${icon} ${t.id.slice(0, 8)} ${t.title}${priority}`;
|
|
27
|
+
});
|
|
28
|
+
return lines.join('\n');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return '(corrupt tasks.json)';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=task-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-summary.js","sourceRoot":"","sources":["../../src/task-summary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,mEAAmE;AACnE,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAExC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC;YAAE,OAAO,sBAAsB,CAAC;QAEnG,MAAM,IAAI,GAAG,IAAiB,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAEvE,mDAAmD;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAC5D,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAEzC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;YACvE,OAAO,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,sBAAsB,SAAS,SAAS,CAAC;QAC1E,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;YACtD,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,QAAQ,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,sBAAsB,CAAC;IAChC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface TemplateData {
|
|
2
|
+
[key: string]: string;
|
|
3
|
+
}
|
|
4
|
+
/** Replace {{PLACEHOLDER}} tokens in template content. */
|
|
5
|
+
export declare function interpolateTemplate(content: string, data: TemplateData): string;
|
|
6
|
+
/** Read a template file, interpolate placeholders, write to target directory. */
|
|
7
|
+
export declare function copyTemplateFile(sourceDir: string, filename: string, targetDir: string, data: TemplateData): void;
|
|
8
|
+
/** Recursively copy a directory, skipping if destination already exists. */
|
|
9
|
+
export declare function copyDirectoryRecursive(src: string, dst: string): void;
|
|
10
|
+
/** Copy bundled skills from templates/skills/ to ~/.curie-agent/skills/. Skips existing skill dirs. */
|
|
11
|
+
export declare function copyInitSkills(templatesDir: string): void;
|
|
12
|
+
/** Get the ~/.curie-agent/ directory, creating it if needed. */
|
|
13
|
+
export declare function getCurieDir(): string;
|
|
14
|
+
/** Resolve the bundled templates directory relative to this module. */
|
|
15
|
+
export declare function resolveTemplatesDir(): string | null;
|
|
16
|
+
//# sourceMappingURL=template-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-utils.d.ts","sourceRoot":"","sources":["../../src/template-utils.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAI/E;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,YAAY,GACjB,IAAI,CAYN;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAcrE;AAED,uGAAuG;AACvG,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAiBzD;AAED,gEAAgE;AAChE,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAQnD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
const PLACEHOLDER_RE = /\{\{(\w+)\}\}/g;
|
|
5
|
+
/** Replace {{PLACEHOLDER}} tokens in template content. */
|
|
6
|
+
export function interpolateTemplate(content, data) {
|
|
7
|
+
return content.replace(PLACEHOLDER_RE, (_match, key) => {
|
|
8
|
+
return data[key] ?? _match;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
/** Read a template file, interpolate placeholders, write to target directory. */
|
|
12
|
+
export function copyTemplateFile(sourceDir, filename, targetDir, data) {
|
|
13
|
+
const src = path.join(sourceDir, filename);
|
|
14
|
+
if (!fs.existsSync(src))
|
|
15
|
+
return;
|
|
16
|
+
const content = fs.readFileSync(src, 'utf-8');
|
|
17
|
+
const interpolated = interpolateTemplate(content, data);
|
|
18
|
+
const dest = path.join(targetDir, filename);
|
|
19
|
+
if (!fs.existsSync(targetDir)) {
|
|
20
|
+
fs.mkdirSync(targetDir, { recursive: true, mode: 0o700 });
|
|
21
|
+
}
|
|
22
|
+
fs.writeFileSync(dest, interpolated, 'utf-8');
|
|
23
|
+
}
|
|
24
|
+
/** Recursively copy a directory, skipping if destination already exists. */
|
|
25
|
+
export function copyDirectoryRecursive(src, dst) {
|
|
26
|
+
if (fs.existsSync(dst))
|
|
27
|
+
return;
|
|
28
|
+
fs.mkdirSync(dst, { recursive: true });
|
|
29
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
30
|
+
const srcPath = path.join(src, entry.name);
|
|
31
|
+
const dstPath = path.join(dst, entry.name);
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
copyDirectoryRecursive(srcPath, dstPath);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
fs.copyFileSync(srcPath, dstPath);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Copy bundled skills from templates/skills/ to ~/.curie-agent/skills/. Skips existing skill dirs. */
|
|
41
|
+
export function copyInitSkills(templatesDir) {
|
|
42
|
+
const curieDir = path.join(os.homedir(), '.curie-agent');
|
|
43
|
+
const sourceSkills = path.join(templatesDir, 'skills');
|
|
44
|
+
const destSkills = path.join(curieDir, 'skills');
|
|
45
|
+
if (!fs.existsSync(sourceSkills))
|
|
46
|
+
return;
|
|
47
|
+
fs.mkdirSync(destSkills, { recursive: true });
|
|
48
|
+
for (const entry of fs.readdirSync(sourceSkills, { withFileTypes: true })) {
|
|
49
|
+
if (entry.isDirectory()) {
|
|
50
|
+
copyDirectoryRecursive(path.join(sourceSkills, entry.name), path.join(destSkills, entry.name));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Get the ~/.curie-agent/ directory, creating it if needed. */
|
|
55
|
+
export function getCurieDir() {
|
|
56
|
+
const dir = path.join(os.homedir(), '.curie-agent');
|
|
57
|
+
if (!fs.existsSync(dir)) {
|
|
58
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
59
|
+
}
|
|
60
|
+
return dir;
|
|
61
|
+
}
|
|
62
|
+
/** Resolve the bundled templates directory relative to this module. */
|
|
63
|
+
export function resolveTemplatesDir() {
|
|
64
|
+
const myDir = path.dirname(new URL(import.meta.url).pathname);
|
|
65
|
+
for (const offset of ['../templates', '../../templates']) {
|
|
66
|
+
const candidate = path.resolve(myDir, offset);
|
|
67
|
+
if (fs.existsSync(candidate))
|
|
68
|
+
return candidate;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=template-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-utils.js","sourceRoot":"","sources":["../../src/template-utils.ts"],"names":[],"mappings":"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"}
|