@fbdo/smart-agentic-calendar 0.1.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/README.md +195 -0
- package/dist/analytics/allocation.d.ts +9 -0
- package/dist/analytics/allocation.d.ts.map +1 -0
- package/dist/analytics/allocation.js +27 -0
- package/dist/analytics/allocation.js.map +1 -0
- package/dist/analytics/analytics-engine.d.ts +17 -0
- package/dist/analytics/analytics-engine.d.ts.map +1 -0
- package/dist/analytics/analytics-engine.js +33 -0
- package/dist/analytics/analytics-engine.js.map +1 -0
- package/dist/analytics/estimation.d.ts +9 -0
- package/dist/analytics/estimation.d.ts.map +1 -0
- package/dist/analytics/estimation.js +74 -0
- package/dist/analytics/estimation.js.map +1 -0
- package/dist/analytics/health.d.ts +14 -0
- package/dist/analytics/health.d.ts.map +1 -0
- package/dist/analytics/health.js +146 -0
- package/dist/analytics/health.js.map +1 -0
- package/dist/analytics/period.d.ts +9 -0
- package/dist/analytics/period.d.ts.map +1 -0
- package/dist/analytics/period.js +41 -0
- package/dist/analytics/period.js.map +1 -0
- package/dist/analytics/productivity.d.ts +9 -0
- package/dist/analytics/productivity.d.ts.map +1 -0
- package/dist/analytics/productivity.js +34 -0
- package/dist/analytics/productivity.js.map +1 -0
- package/dist/common/constants.d.ts +13 -0
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/constants.js +19 -0
- package/dist/common/constants.js.map +1 -0
- package/dist/common/id.d.ts +2 -0
- package/dist/common/id.d.ts.map +1 -0
- package/dist/common/id.js +5 -0
- package/dist/common/id.js.map +1 -0
- package/dist/common/time.d.ts +11 -0
- package/dist/common/time.d.ts.map +1 -0
- package/dist/common/time.js +67 -0
- package/dist/common/time.js.map +1 -0
- package/dist/engine/conflict-detector.d.ts +22 -0
- package/dist/engine/conflict-detector.d.ts.map +1 -0
- package/dist/engine/conflict-detector.js +194 -0
- package/dist/engine/conflict-detector.js.map +1 -0
- package/dist/engine/dependency-resolver.d.ts +8 -0
- package/dist/engine/dependency-resolver.d.ts.map +1 -0
- package/dist/engine/dependency-resolver.js +160 -0
- package/dist/engine/dependency-resolver.js.map +1 -0
- package/dist/engine/recurrence-manager.d.ts +24 -0
- package/dist/engine/recurrence-manager.d.ts.map +1 -0
- package/dist/engine/recurrence-manager.js +140 -0
- package/dist/engine/recurrence-manager.js.map +1 -0
- package/dist/engine/replan-coordinator.d.ts +24 -0
- package/dist/engine/replan-coordinator.d.ts.map +1 -0
- package/dist/engine/replan-coordinator.js +107 -0
- package/dist/engine/replan-coordinator.js.map +1 -0
- package/dist/engine/scheduler.d.ts +65 -0
- package/dist/engine/scheduler.d.ts.map +1 -0
- package/dist/engine/scheduler.js +368 -0
- package/dist/engine/scheduler.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +25 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +421 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/analytics-tools.d.ts +45 -0
- package/dist/mcp/tools/analytics-tools.d.ts.map +1 -0
- package/dist/mcp/tools/analytics-tools.js +27 -0
- package/dist/mcp/tools/analytics-tools.js.map +1 -0
- package/dist/mcp/tools/config-tools.d.ts +55 -0
- package/dist/mcp/tools/config-tools.d.ts.map +1 -0
- package/dist/mcp/tools/config-tools.js +47 -0
- package/dist/mcp/tools/config-tools.js.map +1 -0
- package/dist/mcp/tools/event-tools.d.ts +50 -0
- package/dist/mcp/tools/event-tools.d.ts.map +1 -0
- package/dist/mcp/tools/event-tools.js +48 -0
- package/dist/mcp/tools/event-tools.js.map +1 -0
- package/dist/mcp/tools/schedule-tools.d.ts +80 -0
- package/dist/mcp/tools/schedule-tools.d.ts.map +1 -0
- package/dist/mcp/tools/schedule-tools.js +103 -0
- package/dist/mcp/tools/schedule-tools.js.map +1 -0
- package/dist/mcp/tools/task-tools.d.ts +106 -0
- package/dist/mcp/tools/task-tools.d.ts.map +1 -0
- package/dist/mcp/tools/task-tools.js +161 -0
- package/dist/mcp/tools/task-tools.js.map +1 -0
- package/dist/mcp/validators.d.ts +231 -0
- package/dist/mcp/validators.d.ts.map +1 -0
- package/dist/mcp/validators.js +405 -0
- package/dist/mcp/validators.js.map +1 -0
- package/dist/models/analytics.d.ts +55 -0
- package/dist/models/analytics.d.ts.map +1 -0
- package/dist/models/analytics.js +2 -0
- package/dist/models/analytics.js.map +1 -0
- package/dist/models/config.d.ts +32 -0
- package/dist/models/config.d.ts.map +1 -0
- package/dist/models/config.js +2 -0
- package/dist/models/config.js.map +1 -0
- package/dist/models/conflict.d.ts +21 -0
- package/dist/models/conflict.d.ts.map +1 -0
- package/dist/models/conflict.js +2 -0
- package/dist/models/conflict.js.map +1 -0
- package/dist/models/dependency.d.ts +5 -0
- package/dist/models/dependency.d.ts.map +1 -0
- package/dist/models/dependency.js +2 -0
- package/dist/models/dependency.js.map +1 -0
- package/dist/models/errors.d.ts +19 -0
- package/dist/models/errors.d.ts.map +1 -0
- package/dist/models/errors.js +29 -0
- package/dist/models/errors.js.map +1 -0
- package/dist/models/event.d.ts +11 -0
- package/dist/models/event.d.ts.map +1 -0
- package/dist/models/event.js +2 -0
- package/dist/models/event.js.map +1 -0
- package/dist/models/recurrence.d.ts +22 -0
- package/dist/models/recurrence.d.ts.map +1 -0
- package/dist/models/recurrence.js +2 -0
- package/dist/models/recurrence.js.map +1 -0
- package/dist/models/schedule.d.ts +16 -0
- package/dist/models/schedule.d.ts.map +1 -0
- package/dist/models/schedule.js +2 -0
- package/dist/models/schedule.js.map +1 -0
- package/dist/models/task.d.ts +21 -0
- package/dist/models/task.d.ts.map +1 -0
- package/dist/models/task.js +9 -0
- package/dist/models/task.js.map +1 -0
- package/dist/storage/analytics-repository.d.ts +17 -0
- package/dist/storage/analytics-repository.d.ts.map +1 -0
- package/dist/storage/analytics-repository.js +99 -0
- package/dist/storage/analytics-repository.js.map +1 -0
- package/dist/storage/config-repository.d.ts +20 -0
- package/dist/storage/config-repository.d.ts.map +1 -0
- package/dist/storage/config-repository.js +145 -0
- package/dist/storage/config-repository.js.map +1 -0
- package/dist/storage/database.d.ts +6 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +160 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/event-repository.d.ts +16 -0
- package/dist/storage/event-repository.d.ts.map +1 -0
- package/dist/storage/event-repository.js +120 -0
- package/dist/storage/event-repository.js.map +1 -0
- package/dist/storage/recurrence-repository.d.ts +18 -0
- package/dist/storage/recurrence-repository.d.ts.map +1 -0
- package/dist/storage/recurrence-repository.js +99 -0
- package/dist/storage/recurrence-repository.js.map +1 -0
- package/dist/storage/schedule-repository.d.ts +13 -0
- package/dist/storage/schedule-repository.d.ts.map +1 -0
- package/dist/storage/schedule-repository.js +53 -0
- package/dist/storage/schedule-repository.js.map +1 -0
- package/dist/storage/task-repository.d.ts +29 -0
- package/dist/storage/task-repository.d.ts.map +1 -0
- package/dist/storage/task-repository.js +235 -0
- package/dist/storage/task-repository.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { generateId } from "../common/id.js";
|
|
2
|
+
import { diffMinutes, addMinutes } from "../common/time.js";
|
|
3
|
+
export const DEFAULT_WEIGHTS = {
|
|
4
|
+
deadlineProximity: 40,
|
|
5
|
+
priority: 30,
|
|
6
|
+
focusTime: 15,
|
|
7
|
+
energy: 10,
|
|
8
|
+
buffer: 5,
|
|
9
|
+
};
|
|
10
|
+
const FOCUS_TAGS = ["deep-work", "focus"];
|
|
11
|
+
const PEAK_ENERGY_TAGS = ["deep-work", "focus"];
|
|
12
|
+
const LOW_ENERGY_TAGS = ["routine", "admin"];
|
|
13
|
+
// --- Scoring functions (exported for testing) ---
|
|
14
|
+
export function deadlineProximityScore(task, _slot, now) {
|
|
15
|
+
if (!task.deadline)
|
|
16
|
+
return 0.5;
|
|
17
|
+
const deadline = new Date(task.deadline).getTime();
|
|
18
|
+
const nowMs = now.getTime();
|
|
19
|
+
if (deadline <= nowMs)
|
|
20
|
+
return 1.0; // already overdue — maximum urgency
|
|
21
|
+
// Score based on urgency: how close is the deadline relative to a 28-day horizon?
|
|
22
|
+
const hoursToDeadline = (deadline - nowMs) / 3_600_000;
|
|
23
|
+
const maxHorizonHours = 28 * 24; // 4-week scheduling horizon
|
|
24
|
+
const urgency = 1.0 - Math.min(1.0, hoursToDeadline / maxHorizonHours);
|
|
25
|
+
return Math.max(0, Math.min(1, urgency));
|
|
26
|
+
}
|
|
27
|
+
export function priorityScore(task) {
|
|
28
|
+
const scores = {
|
|
29
|
+
P1: 1.0,
|
|
30
|
+
P2: 0.75,
|
|
31
|
+
P3: 0.5,
|
|
32
|
+
P4: 0.25,
|
|
33
|
+
};
|
|
34
|
+
return scores[task.priority] ?? 0.5;
|
|
35
|
+
}
|
|
36
|
+
export function focusTimeScore(task, slot, focusTime) {
|
|
37
|
+
if (focusTime.blocks.length === 0)
|
|
38
|
+
return 0.5;
|
|
39
|
+
const isFocusTask = task.tags.some((t) => FOCUS_TAGS.includes(t.toLowerCase()));
|
|
40
|
+
const inFocusBlock = isSlotInFocusBlock(slot, focusTime);
|
|
41
|
+
if (isFocusTask && inFocusBlock)
|
|
42
|
+
return 1.0;
|
|
43
|
+
if (isFocusTask && !inFocusBlock)
|
|
44
|
+
return 0.0;
|
|
45
|
+
if (!isFocusTask && inFocusBlock)
|
|
46
|
+
return 0.2;
|
|
47
|
+
return 0.5;
|
|
48
|
+
}
|
|
49
|
+
export function energyScore(task, slot, energyConfig) {
|
|
50
|
+
if (!energyConfig)
|
|
51
|
+
return 0.5;
|
|
52
|
+
const isPeakTask = task.tags.some((t) => PEAK_ENERGY_TAGS.includes(t.toLowerCase()));
|
|
53
|
+
const isLowTask = task.tags.some((t) => LOW_ENERGY_TAGS.includes(t.toLowerCase()));
|
|
54
|
+
if (!isPeakTask && !isLowTask)
|
|
55
|
+
return 0.5;
|
|
56
|
+
const slotTime = extractTime(slot.startTime);
|
|
57
|
+
if (isPeakTask) {
|
|
58
|
+
const inPeak = isTimeInRange(slotTime, energyConfig.peakEnergyStart, energyConfig.peakEnergyEnd);
|
|
59
|
+
return inPeak ? 1.0 : 0.2;
|
|
60
|
+
}
|
|
61
|
+
if (isLowTask) {
|
|
62
|
+
const inLow = isTimeInRange(slotTime, energyConfig.lowEnergyStart, energyConfig.lowEnergyEnd);
|
|
63
|
+
return inLow ? 1.0 : 0.2;
|
|
64
|
+
}
|
|
65
|
+
return 0.5;
|
|
66
|
+
}
|
|
67
|
+
export function bufferScore(slot, adjacentBlocks, bufferTimeMinutes) {
|
|
68
|
+
let score = 1.0;
|
|
69
|
+
const slotStart = new Date(slot.startTime).getTime();
|
|
70
|
+
const slotEnd = new Date(slot.endTime).getTime();
|
|
71
|
+
const bufferMs = bufferTimeMinutes * 60_000;
|
|
72
|
+
for (const block of adjacentBlocks) {
|
|
73
|
+
const blockEnd = new Date(block.endTime).getTime();
|
|
74
|
+
const blockStart = new Date(block.startTime).getTime();
|
|
75
|
+
// Block ends just before slot starts (within buffer)
|
|
76
|
+
if (blockEnd <= slotStart && slotStart - blockEnd < bufferMs) {
|
|
77
|
+
score -= 0.5;
|
|
78
|
+
}
|
|
79
|
+
// Block starts just after slot ends (within buffer)
|
|
80
|
+
if (blockStart >= slotEnd && blockStart - slotEnd < bufferMs) {
|
|
81
|
+
score -= 0.5;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return Math.max(0, score);
|
|
85
|
+
}
|
|
86
|
+
export function scoreSlot(task, slot, now, focusTime, energyConfig, adjacentBlocks, bufferTimeMinutes) {
|
|
87
|
+
const breakdown = {
|
|
88
|
+
deadlineProximity: deadlineProximityScore(task, slot, now),
|
|
89
|
+
priority: priorityScore(task),
|
|
90
|
+
focusTime: focusTimeScore(task, slot, focusTime),
|
|
91
|
+
energy: energyScore(task, slot, energyConfig),
|
|
92
|
+
buffer: bufferScore(slot, adjacentBlocks, bufferTimeMinutes),
|
|
93
|
+
};
|
|
94
|
+
const totalScore = DEFAULT_WEIGHTS.deadlineProximity * breakdown.deadlineProximity +
|
|
95
|
+
DEFAULT_WEIGHTS.priority * breakdown.priority +
|
|
96
|
+
DEFAULT_WEIGHTS.focusTime * breakdown.focusTime +
|
|
97
|
+
DEFAULT_WEIGHTS.energy * breakdown.energy +
|
|
98
|
+
DEFAULT_WEIGHTS.buffer * breakdown.buffer;
|
|
99
|
+
return { slot, totalScore, breakdown };
|
|
100
|
+
}
|
|
101
|
+
// --- Availability map ---
|
|
102
|
+
export function buildAvailabilityMap(start, end, availability, events, pinnedBlocks) {
|
|
103
|
+
const slots = [];
|
|
104
|
+
const current = new Date(start);
|
|
105
|
+
while (current < end) {
|
|
106
|
+
const dayOfWeek = current.getUTCDay();
|
|
107
|
+
const dateStr = current.toISOString().slice(0, 10);
|
|
108
|
+
// Check for all-day events blocking this day
|
|
109
|
+
const allDayBlock = events.some((e) => e.isAllDay && e.date === dateStr);
|
|
110
|
+
if (!allDayBlock) {
|
|
111
|
+
// Find availability windows for this day
|
|
112
|
+
const windows = availability.windows.filter((w) => w.day === dayOfWeek);
|
|
113
|
+
for (const window of windows) {
|
|
114
|
+
const windowStart = `${dateStr}T${window.startTime}:00.000Z`;
|
|
115
|
+
const windowEnd = `${dateStr}T${window.endTime}:00.000Z`;
|
|
116
|
+
// Collect all blockers (events + pinned blocks) for this day
|
|
117
|
+
const blockers = collectBlockers(dateStr, windowStart, windowEnd, events, pinnedBlocks);
|
|
118
|
+
// Subtract blockers from the availability window
|
|
119
|
+
const freeSlots = subtractBlockers(windowStart, windowEnd, blockers);
|
|
120
|
+
for (const free of freeSlots) {
|
|
121
|
+
const durationMinutes = diffMinutes(free.start, free.end);
|
|
122
|
+
if (durationMinutes > 0) {
|
|
123
|
+
slots.push({
|
|
124
|
+
date: dateStr,
|
|
125
|
+
startTime: free.start,
|
|
126
|
+
endTime: free.end,
|
|
127
|
+
durationMinutes,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Move to next day
|
|
134
|
+
current.setUTCDate(current.getUTCDate() + 1);
|
|
135
|
+
}
|
|
136
|
+
return slots;
|
|
137
|
+
}
|
|
138
|
+
export class Scheduler {
|
|
139
|
+
taskRepo;
|
|
140
|
+
eventRepo;
|
|
141
|
+
configRepo;
|
|
142
|
+
conflictDetector;
|
|
143
|
+
dependencyResolver;
|
|
144
|
+
scheduleRepo;
|
|
145
|
+
constructor(taskRepo, eventRepo, configRepo, conflictDetector, dependencyResolver, scheduleRepo) {
|
|
146
|
+
this.taskRepo = taskRepo;
|
|
147
|
+
this.eventRepo = eventRepo;
|
|
148
|
+
this.configRepo = configRepo;
|
|
149
|
+
this.conflictDetector = conflictDetector;
|
|
150
|
+
this.dependencyResolver = dependencyResolver;
|
|
151
|
+
this.scheduleRepo = scheduleRepo;
|
|
152
|
+
}
|
|
153
|
+
generateSchedule(start, end) {
|
|
154
|
+
const config = this.configRepo.getFullConfig();
|
|
155
|
+
const now = new Date();
|
|
156
|
+
// 1. Load inputs
|
|
157
|
+
const allTasks = this.taskRepo.findAll();
|
|
158
|
+
const pendingTasks = allTasks.filter((t) => t.status === "pending" || t.status === "scheduled" || t.status === "at_risk");
|
|
159
|
+
const events = this.eventRepo.findInRange(start.toISOString(), end.toISOString());
|
|
160
|
+
// Get pinned blocks (completed/in-progress tasks)
|
|
161
|
+
const existingBlocks = this.scheduleRepo.getSchedule(start.toISOString(), end.toISOString());
|
|
162
|
+
const completedTaskIds = new Set(allTasks.filter((t) => t.status === "completed").map((t) => t.id));
|
|
163
|
+
const pinnedBlocks = existingBlocks.filter((b) => completedTaskIds.has(b.taskId));
|
|
164
|
+
// Load dependencies
|
|
165
|
+
const dependencies = [];
|
|
166
|
+
for (const task of pendingTasks) {
|
|
167
|
+
const deps = this.taskRepo.getDependencies(task.id);
|
|
168
|
+
for (const dep of deps) {
|
|
169
|
+
dependencies.push({ taskId: task.id, dependsOnId: dep.id });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// 2. Build availability map
|
|
173
|
+
const availableSlots = buildAvailabilityMap(start, end, config.availability, events, pinnedBlocks);
|
|
174
|
+
// 3. Filter out blocked tasks and order remaining
|
|
175
|
+
const blockedTasks = this.dependencyResolver.getBlockedTasks(pendingTasks, dependencies);
|
|
176
|
+
const blockedIds = new Set(blockedTasks.map((t) => t.id));
|
|
177
|
+
const schedulableTasks = pendingTasks.filter((t) => !blockedIds.has(t.id));
|
|
178
|
+
const schedulableIds = new Set(schedulableTasks.map((t) => t.id));
|
|
179
|
+
const orderedTasks = this.dependencyResolver.topologicalSort(schedulableTasks, dependencies.filter((d) => schedulableIds.has(d.taskId) && schedulableIds.has(d.dependsOnId)));
|
|
180
|
+
// 4. Place each task
|
|
181
|
+
const allTimeBlocks = [...pinnedBlocks];
|
|
182
|
+
const remainingSlots = [...availableSlots];
|
|
183
|
+
const atRiskTasks = [];
|
|
184
|
+
for (const task of orderedTasks) {
|
|
185
|
+
const placement = placeTask(task, remainingSlots, allTimeBlocks, now, config.focusTime, null, // energy config — extracted from preferences if set
|
|
186
|
+
config.preferences.bufferTimeMinutes, config.preferences.minimumBlockMinutes, config.focusTime.minimumBlockMinutes);
|
|
187
|
+
allTimeBlocks.push(...placement.blocks);
|
|
188
|
+
// Remove used slot space
|
|
189
|
+
for (const block of placement.blocks) {
|
|
190
|
+
consumeSlotSpace(remainingSlots, block);
|
|
191
|
+
}
|
|
192
|
+
if (placement.unscheduledMinutes > 0) {
|
|
193
|
+
atRiskTasks.push({
|
|
194
|
+
taskId: task.id,
|
|
195
|
+
reason: `insufficient time: ${placement.unscheduledMinutes} minutes unscheduled`,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Add blocked tasks as at-risk
|
|
200
|
+
for (const task of blockedTasks) {
|
|
201
|
+
atRiskTasks.push({
|
|
202
|
+
taskId: task.id,
|
|
203
|
+
reason: "blocked by incomplete dependencies",
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
// 5. Run conflict detection
|
|
207
|
+
const newBlocks = allTimeBlocks.filter((b) => !pinnedBlocks.includes(b));
|
|
208
|
+
const conflicts = this.conflictDetector.detectConflicts(pendingTasks, newBlocks, config.availability, dependencies, now);
|
|
209
|
+
return {
|
|
210
|
+
timeBlocks: allTimeBlocks.filter((b) => !pinnedBlocks.includes(b)),
|
|
211
|
+
conflicts,
|
|
212
|
+
atRiskTasks,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// --- Task placement ---
|
|
217
|
+
function adjustForTrailingBlock(blockDuration, remainingMinutes, minimumBlockMinutes) {
|
|
218
|
+
const leftover = remainingMinutes - blockDuration;
|
|
219
|
+
if (leftover > 0 && leftover < minimumBlockMinutes) {
|
|
220
|
+
const adjusted = remainingMinutes - minimumBlockMinutes;
|
|
221
|
+
return adjusted >= minimumBlockMinutes ? adjusted : remainingMinutes;
|
|
222
|
+
}
|
|
223
|
+
return blockDuration;
|
|
224
|
+
}
|
|
225
|
+
export function placeTask(task, availableSlots, existingBlocks, now, focusTime, energyConfig, bufferTimeMinutes, minimumBlockMinutes, focusMinimumBlockMinutes) {
|
|
226
|
+
let remainingMinutes = task.duration;
|
|
227
|
+
const blocks = [];
|
|
228
|
+
let blockIndex = 0;
|
|
229
|
+
// Score all available slots
|
|
230
|
+
const scoredSlots = availableSlots
|
|
231
|
+
.filter((s) => s.durationMinutes >= minimumBlockMinutes)
|
|
232
|
+
.map((slot) => scoreSlot(task, slot, now, focusTime, energyConfig, existingBlocks, bufferTimeMinutes))
|
|
233
|
+
.sort((a, b) => b.totalScore - a.totalScore);
|
|
234
|
+
// Apply focus time fragmentation prevention
|
|
235
|
+
const isFocusTask = task.tags.some((t) => FOCUS_TAGS.includes(t.toLowerCase()));
|
|
236
|
+
for (const scored of scoredSlots) {
|
|
237
|
+
if (remainingMinutes <= 0)
|
|
238
|
+
break;
|
|
239
|
+
const slot = scored.slot;
|
|
240
|
+
// Focus fragmentation prevention: don't place short non-focus tasks in focus blocks
|
|
241
|
+
if (!isFocusTask && isSlotInFocusBlock(slot, focusTime)) {
|
|
242
|
+
if (task.duration < focusMinimumBlockMinutes) {
|
|
243
|
+
continue; // Skip focus block for short non-focus tasks
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const rawDuration = Math.min(remainingMinutes, slot.durationMinutes);
|
|
247
|
+
const blockDuration = adjustForTrailingBlock(rawDuration, remainingMinutes, minimumBlockMinutes);
|
|
248
|
+
blocks.push({
|
|
249
|
+
id: generateId(),
|
|
250
|
+
taskId: task.id,
|
|
251
|
+
startTime: slot.startTime,
|
|
252
|
+
endTime: addMinutes(slot.startTime, blockDuration),
|
|
253
|
+
date: slot.date,
|
|
254
|
+
blockIndex,
|
|
255
|
+
totalBlocks: 0, // Updated below
|
|
256
|
+
});
|
|
257
|
+
remainingMinutes -= blockDuration;
|
|
258
|
+
blockIndex++;
|
|
259
|
+
}
|
|
260
|
+
// Update totalBlocks
|
|
261
|
+
for (const block of blocks) {
|
|
262
|
+
block.totalBlocks = blocks.length;
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
taskId: task.id,
|
|
266
|
+
blocks,
|
|
267
|
+
unscheduledMinutes: Math.max(0, remainingMinutes),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
// --- Helpers ---
|
|
271
|
+
function isSlotInFocusBlock(slot, focusTime) {
|
|
272
|
+
const slotDate = new Date(slot.startTime);
|
|
273
|
+
const dayOfWeek = slotDate.getUTCDay();
|
|
274
|
+
const slotTimeStr = extractTime(slot.startTime);
|
|
275
|
+
return focusTime.blocks.some((fb) => fb.day === dayOfWeek && slotTimeStr >= fb.startTime && slotTimeStr < fb.endTime);
|
|
276
|
+
}
|
|
277
|
+
function extractTime(isoString) {
|
|
278
|
+
return isoString.slice(11, 16);
|
|
279
|
+
}
|
|
280
|
+
function isTimeInRange(time, start, end) {
|
|
281
|
+
return time >= start && time < end;
|
|
282
|
+
}
|
|
283
|
+
function clipToWindow(start, end, windowStart, windowEnd) {
|
|
284
|
+
if (start >= windowEnd || end <= windowStart)
|
|
285
|
+
return null;
|
|
286
|
+
return {
|
|
287
|
+
start: start < windowStart ? windowStart : start,
|
|
288
|
+
end: end > windowEnd ? windowEnd : end,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function collectBlockers(_dateStr, windowStart, windowEnd, events, pinnedBlocks) {
|
|
292
|
+
const blockers = [];
|
|
293
|
+
for (const event of events) {
|
|
294
|
+
if (event.isAllDay || !event.startTime || !event.endTime)
|
|
295
|
+
continue;
|
|
296
|
+
const clipped = clipToWindow(event.startTime, event.endTime, windowStart, windowEnd);
|
|
297
|
+
if (clipped)
|
|
298
|
+
blockers.push(clipped);
|
|
299
|
+
}
|
|
300
|
+
for (const block of pinnedBlocks) {
|
|
301
|
+
const clipped = clipToWindow(block.startTime, block.endTime, windowStart, windowEnd);
|
|
302
|
+
if (clipped)
|
|
303
|
+
blockers.push(clipped);
|
|
304
|
+
}
|
|
305
|
+
blockers.sort((a, b) => a.start.localeCompare(b.start));
|
|
306
|
+
return blockers;
|
|
307
|
+
}
|
|
308
|
+
function subtractBlockers(windowStart, windowEnd, blockers) {
|
|
309
|
+
const freeSlots = [];
|
|
310
|
+
let currentStart = windowStart;
|
|
311
|
+
for (const blocker of blockers) {
|
|
312
|
+
if (blocker.start > currentStart) {
|
|
313
|
+
freeSlots.push({ start: currentStart, end: blocker.start });
|
|
314
|
+
}
|
|
315
|
+
if (blocker.end > currentStart) {
|
|
316
|
+
currentStart = blocker.end;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (currentStart < windowEnd) {
|
|
320
|
+
freeSlots.push({ start: currentStart, end: windowEnd });
|
|
321
|
+
}
|
|
322
|
+
return freeSlots;
|
|
323
|
+
}
|
|
324
|
+
function splitSlotAroundBlock(slot, blockStart, blockEnd, blockStartTime, blockEndTime) {
|
|
325
|
+
const slotStart = new Date(slot.startTime).getTime();
|
|
326
|
+
const slotEnd = new Date(slot.endTime).getTime();
|
|
327
|
+
const remaining = [];
|
|
328
|
+
if (blockStart > slotStart) {
|
|
329
|
+
const beforeDuration = (blockStart - slotStart) / 60_000;
|
|
330
|
+
if (beforeDuration > 0) {
|
|
331
|
+
remaining.push({
|
|
332
|
+
date: slot.date,
|
|
333
|
+
startTime: slot.startTime,
|
|
334
|
+
endTime: blockStartTime,
|
|
335
|
+
durationMinutes: beforeDuration,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (blockEnd < slotEnd) {
|
|
340
|
+
const afterDuration = (slotEnd - blockEnd) / 60_000;
|
|
341
|
+
if (afterDuration > 0) {
|
|
342
|
+
remaining.push({
|
|
343
|
+
date: slot.date,
|
|
344
|
+
startTime: blockEndTime,
|
|
345
|
+
endTime: slot.endTime,
|
|
346
|
+
durationMinutes: afterDuration,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return remaining;
|
|
351
|
+
}
|
|
352
|
+
function consumeSlotSpace(slots, block) {
|
|
353
|
+
const blockStart = new Date(block.startTime).getTime();
|
|
354
|
+
const blockEnd = new Date(block.endTime).getTime();
|
|
355
|
+
for (let i = slots.length - 1; i >= 0; i--) {
|
|
356
|
+
const slot = slots[i];
|
|
357
|
+
const slotStart = new Date(slot.startTime).getTime();
|
|
358
|
+
const slotEnd = new Date(slot.endTime).getTime();
|
|
359
|
+
if (blockStart < slotEnd && blockEnd > slotStart) {
|
|
360
|
+
slots.splice(i, 1);
|
|
361
|
+
const remaining = splitSlotAroundBlock(slot, blockStart, blockEnd, block.startTime, block.endTime);
|
|
362
|
+
for (const r of remaining) {
|
|
363
|
+
slots.push(r);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/engine/scheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Database } from "./storage/database.js";
|
|
3
|
+
import { TaskTools } from "./mcp/tools/task-tools.js";
|
|
4
|
+
import { EventTools } from "./mcp/tools/event-tools.js";
|
|
5
|
+
import { ScheduleTools } from "./mcp/tools/schedule-tools.js";
|
|
6
|
+
import { AnalyticsTools } from "./mcp/tools/analytics-tools.js";
|
|
7
|
+
import { ConfigTools } from "./mcp/tools/config-tools.js";
|
|
8
|
+
import { McpServer } from "./mcp/server.js";
|
|
9
|
+
export declare function getDbPath(): string;
|
|
10
|
+
export declare function createApp(dbPath: string): {
|
|
11
|
+
server: McpServer;
|
|
12
|
+
database: Database;
|
|
13
|
+
taskTools: TaskTools;
|
|
14
|
+
eventTools: EventTools;
|
|
15
|
+
scheduleTools: ScheduleTools;
|
|
16
|
+
analyticsTools: AnalyticsTools;
|
|
17
|
+
configTools: ConfigTools;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAajD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM;;;;;;;;EAiEvC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Database } from "./storage/database.js";
|
|
3
|
+
import { TaskRepository } from "./storage/task-repository.js";
|
|
4
|
+
import { EventRepository } from "./storage/event-repository.js";
|
|
5
|
+
import { ConfigRepository } from "./storage/config-repository.js";
|
|
6
|
+
import { ScheduleRepository } from "./storage/schedule-repository.js";
|
|
7
|
+
import { AnalyticsRepository } from "./storage/analytics-repository.js";
|
|
8
|
+
import { RecurrenceRepository } from "./storage/recurrence-repository.js";
|
|
9
|
+
import { DependencyResolver } from "./engine/dependency-resolver.js";
|
|
10
|
+
import { ConflictDetector } from "./engine/conflict-detector.js";
|
|
11
|
+
import { Scheduler } from "./engine/scheduler.js";
|
|
12
|
+
import { RecurrenceManager } from "./engine/recurrence-manager.js";
|
|
13
|
+
import { ReplanCoordinator } from "./engine/replan-coordinator.js";
|
|
14
|
+
import { AnalyticsEngine } from "./analytics/analytics-engine.js";
|
|
15
|
+
import { TaskTools } from "./mcp/tools/task-tools.js";
|
|
16
|
+
import { EventTools } from "./mcp/tools/event-tools.js";
|
|
17
|
+
import { ScheduleTools } from "./mcp/tools/schedule-tools.js";
|
|
18
|
+
import { AnalyticsTools } from "./mcp/tools/analytics-tools.js";
|
|
19
|
+
import { ConfigTools } from "./mcp/tools/config-tools.js";
|
|
20
|
+
import { McpServer } from "./mcp/server.js";
|
|
21
|
+
export function getDbPath() {
|
|
22
|
+
return process.env.CALENDAR_DB_PATH ?? "./calendar.db";
|
|
23
|
+
}
|
|
24
|
+
export function createApp(dbPath) {
|
|
25
|
+
// 1. Database
|
|
26
|
+
const database = new Database(dbPath);
|
|
27
|
+
// 2. Repositories
|
|
28
|
+
const taskRepo = new TaskRepository(database);
|
|
29
|
+
const eventRepo = new EventRepository(database);
|
|
30
|
+
const configRepo = new ConfigRepository(database);
|
|
31
|
+
const scheduleRepo = new ScheduleRepository(database);
|
|
32
|
+
const analyticsRepo = new AnalyticsRepository(database);
|
|
33
|
+
const recurrenceRepo = new RecurrenceRepository(database);
|
|
34
|
+
// 3. Engine components
|
|
35
|
+
const dependencyResolver = new DependencyResolver();
|
|
36
|
+
const conflictDetector = new ConflictDetector();
|
|
37
|
+
const scheduler = new Scheduler(taskRepo, eventRepo, configRepo, conflictDetector, dependencyResolver, scheduleRepo);
|
|
38
|
+
const recurrenceManager = new RecurrenceManager(recurrenceRepo, taskRepo);
|
|
39
|
+
const replanCoordinator = new ReplanCoordinator(scheduler, scheduleRepo, taskRepo, configRepo, recurrenceManager);
|
|
40
|
+
// 4. Analytics
|
|
41
|
+
const analyticsEngine = new AnalyticsEngine(analyticsRepo, taskRepo, scheduleRepo, configRepo);
|
|
42
|
+
// 5. MCP Tool handlers
|
|
43
|
+
const taskTools = new TaskTools(taskRepo, recurrenceManager, dependencyResolver, replanCoordinator);
|
|
44
|
+
const eventTools = new EventTools(eventRepo, replanCoordinator);
|
|
45
|
+
const scheduleTools = new ScheduleTools(scheduleRepo, taskRepo, configRepo, replanCoordinator, conflictDetector);
|
|
46
|
+
const analyticsTools = new AnalyticsTools(analyticsEngine);
|
|
47
|
+
const configTools = new ConfigTools(configRepo, replanCoordinator);
|
|
48
|
+
// 6. MCP Server
|
|
49
|
+
const server = new McpServer(taskTools, eventTools, scheduleTools, analyticsTools, configTools);
|
|
50
|
+
return {
|
|
51
|
+
server,
|
|
52
|
+
database,
|
|
53
|
+
taskTools,
|
|
54
|
+
eventTools,
|
|
55
|
+
scheduleTools,
|
|
56
|
+
analyticsTools,
|
|
57
|
+
configTools,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Entry point — start the server when run directly (not imported by tests)
|
|
61
|
+
if (process.env.NODE_ENV !== "test" && !process.env.VITEST) {
|
|
62
|
+
const dbPath = getDbPath();
|
|
63
|
+
const { server } = createApp(dbPath);
|
|
64
|
+
server.start().catch((error) => {
|
|
65
|
+
process.stderr.write(`Fatal: ${error}\n`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TaskTools } from "./tools/task-tools.js";
|
|
2
|
+
import type { EventTools } from "./tools/event-tools.js";
|
|
3
|
+
import type { ScheduleTools } from "./tools/schedule-tools.js";
|
|
4
|
+
import type { AnalyticsTools } from "./tools/analytics-tools.js";
|
|
5
|
+
import type { ConfigTools } from "./tools/config-tools.js";
|
|
6
|
+
export declare function wrapToolHandler(handler: (input: Record<string, unknown>) => unknown): (input: Record<string, unknown>) => Promise<{
|
|
7
|
+
content: {
|
|
8
|
+
type: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}[];
|
|
11
|
+
isError?: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
export declare class McpServer {
|
|
14
|
+
private readonly tools;
|
|
15
|
+
constructor(taskTools: TaskTools, eventTools: EventTools, scheduleTools: ScheduleTools, analyticsTools: AnalyticsTools, configTools: ConfigTools);
|
|
16
|
+
getToolNames(): string[];
|
|
17
|
+
start(): Promise<void>;
|
|
18
|
+
private register;
|
|
19
|
+
private registerTaskTools;
|
|
20
|
+
private registerEventTools;
|
|
21
|
+
private registerScheduleTools;
|
|
22
|
+
private registerAnalyticsTools;
|
|
23
|
+
private registerConfigTools;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAa3D,wBAAgB,eAAe,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GAAG,CACrF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,OAAO,CAAC;IACX,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC,CAoCD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;gBAGzD,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,WAAW;IAS1B,YAAY,IAAI,MAAM,EAAE;IAIlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4C5B,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,iBAAiB;IAuHzB,OAAO,CAAC,kBAAkB;IAiE1B,OAAO,CAAC,qBAAqB;IAiC7B,OAAO,CAAC,sBAAsB;IA8D9B,OAAO,CAAC,mBAAmB;CAuF5B"}
|