@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 @@
|
|
|
1
|
+
{"version":3,"file":"recurrence-manager.d.ts","sourceRoot":"","sources":["../../src/engine/recurrence-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACtF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAG9C,KAAK,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAG,gBAAgB,CAAC,CAAC;AAE7F,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,iBAAiB,CAAqB;gBAElC,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,cAAc;IAK1E,mBAAmB,CACjB,QAAQ,EAAE,UAAU,EACpB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,IAAI,EACT,UAAU,EAAE,IAAI,GACf;QAAE,QAAQ,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,kBAAkB,EAAE,CAAA;KAAE;IA0BpE,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,GAAG,kBAAkB,EAAE;IAQxF,aAAa,CAAC,aAAa,EAAE,IAAI,GAAG,kBAAkB,EAAE;IAkBxD,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAcpD,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAoB9E,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI;IAyBnD,OAAO,CAAC,4BAA4B;IAmDpC,OAAO,CAAC,SAAS;CAOlB"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { rrulestr } from "rrule";
|
|
2
|
+
import { ValidationError, NotFoundError, InvalidStateError } from "../models/errors.js";
|
|
3
|
+
export class RecurrenceManager {
|
|
4
|
+
recurrenceRepo;
|
|
5
|
+
taskRepo;
|
|
6
|
+
currentHorizonEnd = null;
|
|
7
|
+
constructor(recurrenceRepo, taskRepo) {
|
|
8
|
+
this.recurrenceRepo = recurrenceRepo;
|
|
9
|
+
this.taskRepo = taskRepo;
|
|
10
|
+
}
|
|
11
|
+
createRecurringTask(taskData, rruleString, now, horizonEnd) {
|
|
12
|
+
// Validate RRULE before creating anything
|
|
13
|
+
this.parseRule(rruleString, now);
|
|
14
|
+
const template = this.recurrenceRepo.createTemplate({
|
|
15
|
+
taskData: {
|
|
16
|
+
title: taskData.title,
|
|
17
|
+
description: taskData.description,
|
|
18
|
+
duration: taskData.duration,
|
|
19
|
+
deadline: taskData.deadline,
|
|
20
|
+
priority: taskData.priority,
|
|
21
|
+
category: taskData.category,
|
|
22
|
+
tags: taskData.tags,
|
|
23
|
+
},
|
|
24
|
+
rrule: rruleString,
|
|
25
|
+
});
|
|
26
|
+
const instances = this.generateInstancesForTemplate(template, now, horizonEnd);
|
|
27
|
+
if (!this.currentHorizonEnd || horizonEnd > this.currentHorizonEnd) {
|
|
28
|
+
this.currentHorizonEnd = horizonEnd;
|
|
29
|
+
}
|
|
30
|
+
return { template, instances };
|
|
31
|
+
}
|
|
32
|
+
generateInstances(templateId, now, horizonEnd) {
|
|
33
|
+
const template = this.recurrenceRepo.getTemplate(templateId);
|
|
34
|
+
if (!template) {
|
|
35
|
+
throw new NotFoundError("RecurrenceTemplate", templateId);
|
|
36
|
+
}
|
|
37
|
+
return this.generateInstancesForTemplate(template, now, horizonEnd);
|
|
38
|
+
}
|
|
39
|
+
expandHorizon(newHorizonEnd) {
|
|
40
|
+
if (this.currentHorizonEnd && newHorizonEnd <= this.currentHorizonEnd) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const templates = this.recurrenceRepo.getActiveTemplates();
|
|
44
|
+
const allNew = [];
|
|
45
|
+
for (const template of templates) {
|
|
46
|
+
const dtstart = new Date(template.createdAt);
|
|
47
|
+
const instances = this.generateInstancesForTemplate(template, dtstart, newHorizonEnd);
|
|
48
|
+
allNew.push(...instances);
|
|
49
|
+
}
|
|
50
|
+
this.currentHorizonEnd = newHorizonEnd;
|
|
51
|
+
return allNew;
|
|
52
|
+
}
|
|
53
|
+
skipInstance(templateId, date) {
|
|
54
|
+
const instances = this.recurrenceRepo.getInstances(templateId, date, date);
|
|
55
|
+
for (const inst of instances) {
|
|
56
|
+
if (inst.scheduledDate === date) {
|
|
57
|
+
this.taskRepo.updateStatus(inst.taskId, "cancelled");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
this.recurrenceRepo.addException(templateId, date, {
|
|
61
|
+
type: "skip",
|
|
62
|
+
overrides: null,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
modifyInstance(templateId, date, updates) {
|
|
66
|
+
const instances = this.recurrenceRepo.getInstances(templateId, date, date);
|
|
67
|
+
const instance = instances.find((i) => i.scheduledDate === date);
|
|
68
|
+
if (!instance) {
|
|
69
|
+
throw new NotFoundError("RecurrenceInstance", `${templateId}:${date}`);
|
|
70
|
+
}
|
|
71
|
+
const task = this.taskRepo.findById(instance.taskId);
|
|
72
|
+
if (task && task.status === "completed") {
|
|
73
|
+
throw new InvalidStateError("Cannot modify a completed instance");
|
|
74
|
+
}
|
|
75
|
+
this.taskRepo.update(instance.taskId, updates);
|
|
76
|
+
this.recurrenceRepo.addException(templateId, date, {
|
|
77
|
+
type: "modify",
|
|
78
|
+
overrides: updates,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
deleteTemplate(templateId, now) {
|
|
82
|
+
const template = this.recurrenceRepo.getTemplate(templateId);
|
|
83
|
+
if (!template) {
|
|
84
|
+
throw new NotFoundError("RecurrenceTemplate", templateId);
|
|
85
|
+
}
|
|
86
|
+
const farFuture = new Date(now);
|
|
87
|
+
farFuture.setFullYear(farFuture.getFullYear() + 10);
|
|
88
|
+
const instances = this.recurrenceRepo.getInstances(templateId, now.toISOString().slice(0, 10), farFuture.toISOString().slice(0, 10));
|
|
89
|
+
for (const inst of instances) {
|
|
90
|
+
const task = this.taskRepo.findById(inst.taskId);
|
|
91
|
+
if (task && task.status !== "completed" && task.status !== "cancelled") {
|
|
92
|
+
this.taskRepo.updateStatus(inst.taskId, "cancelled");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
this.recurrenceRepo.deleteTemplate(templateId);
|
|
96
|
+
}
|
|
97
|
+
generateInstancesForTemplate(template, start, end) {
|
|
98
|
+
const rule = this.parseRule(template.rrule, start);
|
|
99
|
+
const dates = rule.between(start, end, true);
|
|
100
|
+
const existing = this.recurrenceRepo.getInstances(template.id, start.toISOString(), end.toISOString());
|
|
101
|
+
const existingDates = new Set(existing.map((i) => i.scheduledDate));
|
|
102
|
+
const exceptions = this.recurrenceRepo.getExceptions(template.id);
|
|
103
|
+
const skipDates = new Set(exceptions.filter((e) => e.type === "skip").map((e) => e.date));
|
|
104
|
+
const newInstances = [];
|
|
105
|
+
for (const date of dates) {
|
|
106
|
+
const dateStr = date.toISOString().slice(0, 10);
|
|
107
|
+
if (existingDates.has(dateStr) || skipDates.has(dateStr)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const task = this.taskRepo.create({
|
|
111
|
+
title: template.taskData.title,
|
|
112
|
+
description: template.taskData.description,
|
|
113
|
+
duration: template.taskData.duration,
|
|
114
|
+
deadline: template.taskData.deadline,
|
|
115
|
+
priority: template.taskData.priority,
|
|
116
|
+
category: template.taskData.category,
|
|
117
|
+
tags: template.taskData.tags,
|
|
118
|
+
isRecurring: true,
|
|
119
|
+
recurrenceTemplateId: template.id,
|
|
120
|
+
});
|
|
121
|
+
const instance = this.recurrenceRepo.createInstance({
|
|
122
|
+
templateId: template.id,
|
|
123
|
+
taskId: task.id,
|
|
124
|
+
scheduledDate: dateStr,
|
|
125
|
+
isException: false,
|
|
126
|
+
});
|
|
127
|
+
newInstances.push(instance);
|
|
128
|
+
}
|
|
129
|
+
return newInstances;
|
|
130
|
+
}
|
|
131
|
+
parseRule(rruleString, dtstart) {
|
|
132
|
+
try {
|
|
133
|
+
return rrulestr(`RRULE:${rruleString}`, { dtstart });
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
throw new ValidationError(`Invalid RRULE: ${rruleString}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=recurrence-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recurrence-manager.js","sourceRoot":"","sources":["../../src/engine/recurrence-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Scheduler } from "./scheduler.js";
|
|
2
|
+
import type { ScheduleRepository } from "../storage/schedule-repository.js";
|
|
3
|
+
import type { TaskRepository } from "../storage/task-repository.js";
|
|
4
|
+
import type { ConfigRepository } from "../storage/config-repository.js";
|
|
5
|
+
import type { RecurrenceManager } from "./recurrence-manager.js";
|
|
6
|
+
import type { ScheduleStatus } from "../models/schedule.js";
|
|
7
|
+
export declare class ReplanCoordinator {
|
|
8
|
+
private readonly scheduler;
|
|
9
|
+
private readonly scheduleRepo;
|
|
10
|
+
private readonly taskRepo;
|
|
11
|
+
private readonly configRepo;
|
|
12
|
+
private readonly recurrenceManager;
|
|
13
|
+
private dirty;
|
|
14
|
+
private replanning;
|
|
15
|
+
private pendingTimeout;
|
|
16
|
+
private awaitCallbacks;
|
|
17
|
+
constructor(scheduler: Scheduler, scheduleRepo: ScheduleRepository, taskRepo: TaskRepository, configRepo: ConfigRepository, recurrenceManager: RecurrenceManager);
|
|
18
|
+
requestReplan(): void;
|
|
19
|
+
isReplanning(): boolean;
|
|
20
|
+
getScheduleStatus(): ScheduleStatus;
|
|
21
|
+
awaitReplan(): Promise<void>;
|
|
22
|
+
private executeReplan;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=replan-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replan-coordinator.d.ts","sourceRoot":"","sources":["../../src/engine/replan-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IAEtD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAAsB;gBAG1C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,kBAAkB,EAChC,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,gBAAgB,EAC5B,iBAAiB,EAAE,iBAAiB;IAStC,aAAa,IAAI,IAAI;IAOrB,YAAY,IAAI,OAAO;IAIvB,iBAAiB,IAAI,cAAc;IAK7B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBlC,OAAO,CAAC,aAAa;CA8DtB"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
export class ReplanCoordinator {
|
|
2
|
+
scheduler;
|
|
3
|
+
scheduleRepo;
|
|
4
|
+
taskRepo;
|
|
5
|
+
configRepo;
|
|
6
|
+
recurrenceManager;
|
|
7
|
+
dirty = false;
|
|
8
|
+
replanning = false;
|
|
9
|
+
pendingTimeout = null;
|
|
10
|
+
awaitCallbacks = [];
|
|
11
|
+
constructor(scheduler, scheduleRepo, taskRepo, configRepo, recurrenceManager) {
|
|
12
|
+
this.scheduler = scheduler;
|
|
13
|
+
this.scheduleRepo = scheduleRepo;
|
|
14
|
+
this.taskRepo = taskRepo;
|
|
15
|
+
this.configRepo = configRepo;
|
|
16
|
+
this.recurrenceManager = recurrenceManager;
|
|
17
|
+
}
|
|
18
|
+
requestReplan() {
|
|
19
|
+
this.dirty = true;
|
|
20
|
+
if (this.pendingTimeout === null && !this.replanning) {
|
|
21
|
+
this.pendingTimeout = setTimeout(() => this.executeReplan(), 0);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
isReplanning() {
|
|
25
|
+
return this.replanning;
|
|
26
|
+
}
|
|
27
|
+
getScheduleStatus() {
|
|
28
|
+
if (this.replanning)
|
|
29
|
+
return "replan_in_progress";
|
|
30
|
+
return "up_to_date";
|
|
31
|
+
}
|
|
32
|
+
async awaitReplan() {
|
|
33
|
+
if (!this.dirty && !this.replanning) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!this.replanning && this.dirty) {
|
|
37
|
+
// Cancel any pending setTimeout and execute immediately
|
|
38
|
+
if (this.pendingTimeout !== null) {
|
|
39
|
+
clearTimeout(this.pendingTimeout);
|
|
40
|
+
this.pendingTimeout = null;
|
|
41
|
+
}
|
|
42
|
+
this.executeReplan();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Replan is in progress — wait for it to complete
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
this.awaitCallbacks.push(resolve);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
executeReplan() {
|
|
51
|
+
this.pendingTimeout = null;
|
|
52
|
+
if (!this.dirty)
|
|
53
|
+
return;
|
|
54
|
+
this.dirty = false;
|
|
55
|
+
this.replanning = true;
|
|
56
|
+
this.scheduleRepo.setScheduleStatus("replan_in_progress");
|
|
57
|
+
try {
|
|
58
|
+
// Step 1: Expand recurrence horizon
|
|
59
|
+
const preferences = this.configRepo.getPreferences();
|
|
60
|
+
const horizonEnd = new Date();
|
|
61
|
+
horizonEnd.setDate(horizonEnd.getDate() + preferences.schedulingHorizonWeeks * 7);
|
|
62
|
+
this.recurrenceManager.expandHorizon(horizonEnd);
|
|
63
|
+
// Step 2: Generate schedule
|
|
64
|
+
const horizonStart = new Date();
|
|
65
|
+
horizonStart.setUTCHours(0, 0, 0, 0);
|
|
66
|
+
const result = this.scheduler.generateSchedule(horizonStart, horizonEnd);
|
|
67
|
+
// Step 3: Save results
|
|
68
|
+
this.scheduleRepo.clearSchedule();
|
|
69
|
+
this.scheduleRepo.saveSchedule(result.timeBlocks);
|
|
70
|
+
// Step 4: Update task statuses — mark scheduled tasks
|
|
71
|
+
const scheduledTaskIds = new Set(result.timeBlocks.map((b) => b.taskId));
|
|
72
|
+
const atRiskIds = new Set(result.atRiskTasks.map((a) => a.taskId));
|
|
73
|
+
for (const taskId of scheduledTaskIds) {
|
|
74
|
+
if (atRiskIds.has(taskId))
|
|
75
|
+
continue; // at_risk takes precedence
|
|
76
|
+
const task = this.taskRepo.findById(taskId);
|
|
77
|
+
if (task && (task.status === "pending" || task.status === "at_risk")) {
|
|
78
|
+
this.taskRepo.updateStatus(taskId, "scheduled");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const atRisk of result.atRiskTasks) {
|
|
82
|
+
const task = this.taskRepo.findById(atRisk.taskId);
|
|
83
|
+
if (task && task.status !== "completed" && task.status !== "cancelled") {
|
|
84
|
+
this.taskRepo.updateStatus(atRisk.taskId, "at_risk");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Graceful degradation: previous schedule preserved
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
this.replanning = false;
|
|
93
|
+
this.scheduleRepo.setScheduleStatus("up_to_date");
|
|
94
|
+
// Resolve any awaitReplan promises
|
|
95
|
+
const callbacks = this.awaitCallbacks;
|
|
96
|
+
this.awaitCallbacks = [];
|
|
97
|
+
for (const callback of callbacks) {
|
|
98
|
+
callback();
|
|
99
|
+
}
|
|
100
|
+
// If dirty again (mutation during replan), schedule another
|
|
101
|
+
if (this.dirty) {
|
|
102
|
+
this.pendingTimeout = setTimeout(() => this.executeReplan(), 0);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=replan-coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replan-coordinator.js","sourceRoot":"","sources":["../../src/engine/replan-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Task } from "../models/task.js";
|
|
2
|
+
import type { TimeBlock, ScheduleResult } from "../models/schedule.js";
|
|
3
|
+
import type { Event } from "../models/event.js";
|
|
4
|
+
import type { Availability, FocusTime } from "../models/config.js";
|
|
5
|
+
import type { TaskRepository } from "../storage/task-repository.js";
|
|
6
|
+
import type { EventRepository } from "../storage/event-repository.js";
|
|
7
|
+
import type { ConfigRepository } from "../storage/config-repository.js";
|
|
8
|
+
import type { ScheduleRepository } from "../storage/schedule-repository.js";
|
|
9
|
+
import { ConflictDetector } from "./conflict-detector.js";
|
|
10
|
+
import { DependencyResolver } from "./dependency-resolver.js";
|
|
11
|
+
export interface AvailableSlot {
|
|
12
|
+
date: string;
|
|
13
|
+
startTime: string;
|
|
14
|
+
endTime: string;
|
|
15
|
+
durationMinutes: number;
|
|
16
|
+
}
|
|
17
|
+
interface SlotScore {
|
|
18
|
+
slot: AvailableSlot;
|
|
19
|
+
totalScore: number;
|
|
20
|
+
breakdown: {
|
|
21
|
+
deadlineProximity: number;
|
|
22
|
+
priority: number;
|
|
23
|
+
focusTime: number;
|
|
24
|
+
energy: number;
|
|
25
|
+
buffer: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface EnergyConfig {
|
|
29
|
+
peakEnergyStart: string;
|
|
30
|
+
peakEnergyEnd: string;
|
|
31
|
+
lowEnergyStart: string;
|
|
32
|
+
lowEnergyEnd: string;
|
|
33
|
+
}
|
|
34
|
+
export declare const DEFAULT_WEIGHTS: {
|
|
35
|
+
deadlineProximity: number;
|
|
36
|
+
priority: number;
|
|
37
|
+
focusTime: number;
|
|
38
|
+
energy: number;
|
|
39
|
+
buffer: number;
|
|
40
|
+
};
|
|
41
|
+
export declare function deadlineProximityScore(task: Task, _slot: AvailableSlot, now: Date): number;
|
|
42
|
+
export declare function priorityScore(task: Task): number;
|
|
43
|
+
export declare function focusTimeScore(task: Task, slot: AvailableSlot, focusTime: FocusTime): number;
|
|
44
|
+
export declare function energyScore(task: Task, slot: AvailableSlot, energyConfig: EnergyConfig | null): number;
|
|
45
|
+
export declare function bufferScore(slot: AvailableSlot, adjacentBlocks: TimeBlock[], bufferTimeMinutes: number): number;
|
|
46
|
+
export declare function scoreSlot(task: Task, slot: AvailableSlot, now: Date, focusTime: FocusTime, energyConfig: EnergyConfig | null, adjacentBlocks: TimeBlock[], bufferTimeMinutes: number): SlotScore;
|
|
47
|
+
export declare function buildAvailabilityMap(start: Date, end: Date, availability: Availability, events: Event[], pinnedBlocks: TimeBlock[]): AvailableSlot[];
|
|
48
|
+
interface TaskPlacement {
|
|
49
|
+
taskId: string;
|
|
50
|
+
blocks: TimeBlock[];
|
|
51
|
+
unscheduledMinutes: number;
|
|
52
|
+
}
|
|
53
|
+
export declare class Scheduler {
|
|
54
|
+
private readonly taskRepo;
|
|
55
|
+
private readonly eventRepo;
|
|
56
|
+
private readonly configRepo;
|
|
57
|
+
private readonly conflictDetector;
|
|
58
|
+
private readonly dependencyResolver;
|
|
59
|
+
private readonly scheduleRepo;
|
|
60
|
+
constructor(taskRepo: TaskRepository, eventRepo: EventRepository, configRepo: ConfigRepository, conflictDetector: ConflictDetector, dependencyResolver: DependencyResolver, scheduleRepo: ScheduleRepository);
|
|
61
|
+
generateSchedule(start: Date, end: Date): ScheduleResult;
|
|
62
|
+
}
|
|
63
|
+
export declare function placeTask(task: Task, availableSlots: AvailableSlot[], existingBlocks: TimeBlock[], now: Date, focusTime: FocusTime, energyConfig: EnergyConfig | null, bufferTimeMinutes: number, minimumBlockMinutes: number, focusMinimumBlockMinutes: number): TaskPlacement;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/engine/scheduler.ts"],"names":[],"mappings":"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"}
|