@fbdo/smart-agentic-calendar 0.1.1 → 0.1.3
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 +143 -58
- package/dist/analytics/analytics-engine.d.ts +3 -1
- package/dist/analytics/analytics-engine.d.ts.map +1 -1
- package/dist/analytics/analytics-engine.js +3 -1
- package/dist/analytics/analytics-engine.js.map +1 -1
- package/dist/common/logger.d.ts +30 -0
- package/dist/common/logger.d.ts.map +1 -0
- package/dist/common/logger.js +74 -0
- package/dist/common/logger.js.map +1 -0
- package/dist/engine/conflict-detector.d.ts +3 -0
- package/dist/engine/conflict-detector.d.ts.map +1 -1
- package/dist/engine/conflict-detector.js +4 -0
- package/dist/engine/conflict-detector.js.map +1 -1
- package/dist/engine/dependency-resolver.d.ts +3 -0
- package/dist/engine/dependency-resolver.d.ts.map +1 -1
- package/dist/engine/dependency-resolver.js +8 -1
- package/dist/engine/dependency-resolver.js.map +1 -1
- package/dist/engine/recurrence-manager.d.ts +3 -1
- package/dist/engine/recurrence-manager.d.ts.map +1 -1
- package/dist/engine/recurrence-manager.js +3 -1
- package/dist/engine/recurrence-manager.js.map +1 -1
- package/dist/engine/replan-coordinator.d.ts +3 -1
- package/dist/engine/replan-coordinator.d.ts.map +1 -1
- package/dist/engine/replan-coordinator.js +14 -2
- package/dist/engine/replan-coordinator.js.map +1 -1
- package/dist/engine/scheduler.d.ts +3 -1
- package/dist/engine/scheduler.d.ts.map +1 -1
- package/dist/engine/scheduler.js +15 -2
- package/dist/engine/scheduler.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -23
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +5 -3
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +76 -20
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/analytics-tools.d.ts +3 -1
- package/dist/mcp/tools/analytics-tools.d.ts.map +1 -1
- package/dist/mcp/tools/analytics-tools.js +3 -1
- package/dist/mcp/tools/analytics-tools.js.map +1 -1
- package/dist/mcp/tools/config-tools.d.ts +3 -1
- package/dist/mcp/tools/config-tools.d.ts.map +1 -1
- package/dist/mcp/tools/config-tools.js +3 -1
- package/dist/mcp/tools/config-tools.js.map +1 -1
- package/dist/mcp/tools/event-tools.d.ts +3 -1
- package/dist/mcp/tools/event-tools.d.ts.map +1 -1
- package/dist/mcp/tools/event-tools.js +3 -1
- package/dist/mcp/tools/event-tools.js.map +1 -1
- package/dist/mcp/tools/schedule-tools.d.ts +3 -1
- package/dist/mcp/tools/schedule-tools.d.ts.map +1 -1
- package/dist/mcp/tools/schedule-tools.js +3 -1
- package/dist/mcp/tools/schedule-tools.js.map +1 -1
- package/dist/mcp/tools/task-tools.d.ts +3 -1
- package/dist/mcp/tools/task-tools.d.ts.map +1 -1
- package/dist/mcp/tools/task-tools.js +3 -1
- package/dist/mcp/tools/task-tools.js.map +1 -1
- package/dist/storage/analytics-repository.d.ts +3 -1
- package/dist/storage/analytics-repository.d.ts.map +1 -1
- package/dist/storage/analytics-repository.js +3 -1
- package/dist/storage/analytics-repository.js.map +1 -1
- package/dist/storage/config-repository.d.ts +3 -1
- package/dist/storage/config-repository.d.ts.map +1 -1
- package/dist/storage/config-repository.js +3 -1
- package/dist/storage/config-repository.js.map +1 -1
- package/dist/storage/database.d.ts +3 -1
- package/dist/storage/database.d.ts.map +1 -1
- package/dist/storage/database.js +5 -1
- package/dist/storage/database.js.map +1 -1
- package/dist/storage/event-repository.d.ts +3 -1
- package/dist/storage/event-repository.d.ts.map +1 -1
- package/dist/storage/event-repository.js +3 -1
- package/dist/storage/event-repository.js.map +1 -1
- package/dist/storage/recurrence-repository.d.ts +3 -1
- package/dist/storage/recurrence-repository.d.ts.map +1 -1
- package/dist/storage/recurrence-repository.js +3 -1
- package/dist/storage/recurrence-repository.js.map +1 -1
- package/dist/storage/schedule-repository.d.ts +3 -1
- package/dist/storage/schedule-repository.d.ts.map +1 -1
- package/dist/storage/schedule-repository.js +3 -1
- package/dist/storage/schedule-repository.js.map +1 -1
- package/dist/storage/task-repository.d.ts +3 -1
- package/dist/storage/task-repository.d.ts.map +1 -1
- package/dist/storage/task-repository.js +3 -1
- package/dist/storage/task-repository.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
A local-first smart calendar MCP server for AI agents. Inspired by [Reclaim.ai](https://reclaim.ai/) and [Motion](https://www.usemotion.com/), it automatically re-plans tasks, recalculates the schedule, and helps AI agents act as personal scheduling assistants.
|
|
4
4
|
|
|
5
|
+
## Is This For You?
|
|
6
|
+
|
|
7
|
+
This project was designed with a specific set of trade-offs. Understanding them will help you decide if it fits your needs.
|
|
8
|
+
|
|
9
|
+
### What it is
|
|
10
|
+
|
|
11
|
+
- **A personal, single-user scheduling assistant.** One person, one calendar, one local database. Your data never leaves your machine.
|
|
12
|
+
- **An MCP server, not an app.** There is no web UI, no CLI dashboard, no REST API. The interface is an AI agent (like Claude) that calls structured tools over stdio. The agent *is* the UI.
|
|
13
|
+
- **A deterministic constraint solver, not machine learning.** The scheduler uses hard constraints (availability, deadlines, dependencies, events) and weighted soft constraints (priority, focus time alignment, energy matching, buffer gaps) to place tasks. It produces the same output given the same input — no training data, no model drift, no black box.
|
|
14
|
+
- **Optimized for a small task set.** The algorithm targets **< 500ms replan latency with up to ~200 active tasks**. It does a full reschedule of all flexible tasks on every change rather than incremental patching, which keeps the logic simple and deterministic. This works well for a personal workload but would not scale to thousands of tasks.
|
|
15
|
+
- **Local-first with SQLite.** All state lives in a single SQLite file using synchronous I/O (better-sqlite3). No network calls, no cloud services, no container infrastructure. Portable and private.
|
|
16
|
+
- **Background replanning with instant tool responses.** Mutations (create, update, delete) return immediately and trigger an async replan via `setImmediate`. Multiple rapid changes are debounced into a single replan cycle. Read tools report a `schedule_status` field so the agent knows if the schedule is stale.
|
|
17
|
+
|
|
18
|
+
### What it is not
|
|
19
|
+
|
|
20
|
+
- **Not a team or shared calendar.** There is no multi-tenancy, no user accounts, no access control. If you need shared scheduling across a team, this is not the right tool.
|
|
21
|
+
- **Not a Google/Outlook integration.** It does not sync with external calendar providers (Google Calendar, Outlook, CalDAV). Events are created directly through the MCP tools. External calendar sync is a potential v2 feature, not a v1 goal.
|
|
22
|
+
- **Not a web service.** There is no HTTP/SSE transport, no hosted version, no API gateway. It runs as a local Node.js process communicating over stdio.
|
|
23
|
+
- **Not an enterprise scheduler.** The full-reschedule approach and single-process SQLite architecture are deliberately simple. There is no caching layer (SQLite is fast enough locally), no distributed locking, no horizontal scaling. The design favors correctness and simplicity over throughput.
|
|
24
|
+
- **Not a learning system.** The scheduler does not learn from your habits or adjust weights over time. Priorities, deadlines, and constraints are explicit inputs — the algorithm is transparent and predictable.
|
|
25
|
+
|
|
5
26
|
## What It Does
|
|
6
27
|
|
|
7
28
|
- **Time-blocking scheduler** that assigns specific time slots to tasks based on deadlines, durations, and priorities (P1-P4)
|
|
@@ -14,74 +35,18 @@ A local-first smart calendar MCP server for AI agents. Inspired by [Reclaim.ai](
|
|
|
14
35
|
- **Conflict detection** that identifies at-risk tasks and suggests deprioritizations
|
|
15
36
|
- **Analytics** — completion rates, schedule health, estimation accuracy, time allocation by category
|
|
16
37
|
|
|
17
|
-
## Architecture
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
src/
|
|
21
|
-
models/ Domain types (Task, Event, TimeBlock, Config, etc.)
|
|
22
|
-
common/ Shared utilities (ID generation, time functions, constants)
|
|
23
|
-
storage/ SQLite database layer (better-sqlite3)
|
|
24
|
-
engine/ Scheduling engine, replanning, conflict detection, recurrence
|
|
25
|
-
analytics/ Productivity stats, schedule health, estimation accuracy
|
|
26
|
-
mcp/ MCP server and tool handlers
|
|
27
|
-
index.ts Composition root and entry point
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Single-user, single-process, local-first. All data stored in a local SQLite database with no external service dependencies.
|
|
31
|
-
|
|
32
|
-
## Tech Stack
|
|
33
|
-
|
|
34
|
-
| Component | Choice |
|
|
35
|
-
|-----------|--------|
|
|
36
|
-
| Language | TypeScript (strict mode) |
|
|
37
|
-
| Runtime | Node.js >= 20 |
|
|
38
|
-
| Storage | SQLite via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) |
|
|
39
|
-
| MCP Transport | stdio |
|
|
40
|
-
| Test Runner | [Vitest](https://vitest.dev/) |
|
|
41
|
-
| Scheduling | Constraint satisfaction algorithm |
|
|
42
|
-
|
|
43
|
-
## Getting Started
|
|
44
|
-
|
|
45
|
-
### Prerequisites
|
|
46
|
-
|
|
47
|
-
- Node.js >= 20
|
|
48
|
-
|
|
49
|
-
### Install and Build
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npm install
|
|
53
|
-
npm run build
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
This compiles TypeScript to `dist/` and produces the runnable server at `dist/index.js`.
|
|
57
|
-
|
|
58
|
-
### Test
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
npm test # run all tests (578 tests)
|
|
62
|
-
npm run test:watch # watch mode
|
|
63
|
-
npm run test:coverage # with coverage
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### Quality Checks
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
npm run lint # eslint
|
|
70
|
-
npm run format:check # prettier
|
|
71
|
-
npm run quality # all checks (lint, format, duplication, unused code, dependency rules, security)
|
|
72
|
-
```
|
|
73
|
-
|
|
74
38
|
## Connecting to an MCP-Compatible Agent
|
|
75
39
|
|
|
76
40
|
This server communicates over **stdio** using the [Model Context Protocol](https://modelcontextprotocol.io/). Any MCP-compatible client can connect to it by spawning the server as a subprocess.
|
|
77
41
|
|
|
78
42
|
### Configuration
|
|
79
43
|
|
|
80
|
-
The server accepts
|
|
44
|
+
The server accepts the following environment variables:
|
|
81
45
|
|
|
82
46
|
| Variable | Default | Description |
|
|
83
47
|
|----------|---------|-------------|
|
|
84
48
|
| `CALENDAR_DB_PATH` | `./calendar.db` | Path to the SQLite database file |
|
|
49
|
+
| `LOG_LEVEL` | `warning` | Minimum severity for stderr output (see [Logging](#logging)) |
|
|
85
50
|
|
|
86
51
|
### Claude Desktop
|
|
87
52
|
|
|
@@ -153,6 +118,71 @@ CALENDAR_DB_PATH=/path/to/calendar.db npx -y @fbdo/smart-agentic-calendar
|
|
|
153
118
|
|
|
154
119
|
The server reads JSON-RPC messages from stdin and writes responses to stdout. Diagnostic messages go to stderr.
|
|
155
120
|
|
|
121
|
+
## Logging
|
|
122
|
+
|
|
123
|
+
The server has two independent logging channels, each with its own level filtering:
|
|
124
|
+
|
|
125
|
+
### stderr (for operators and developers)
|
|
126
|
+
|
|
127
|
+
Controlled by the `LOG_LEVEL` environment variable. Set it to any [RFC 5424 syslog level](https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1):
|
|
128
|
+
|
|
129
|
+
| Level | Severity | What you'll see |
|
|
130
|
+
|-------|----------|----------------|
|
|
131
|
+
| `debug` | 0 | Everything — slot scoring, task ordering, DB operations |
|
|
132
|
+
| `info` | 1 | Significant operations — replan completed, server started, migrations applied |
|
|
133
|
+
| `notice` | 2 | Noteworthy but normal — graceful degradation after replan failure |
|
|
134
|
+
| `warning` | 3 | Potential issues — at-risk tasks, unknown tool invocations **(default)** |
|
|
135
|
+
| `error` | 4 | Handled failures — unexpected errors in tool execution |
|
|
136
|
+
| `critical` | 5 | Severe failures |
|
|
137
|
+
| `alert` | 6 | Immediate action required |
|
|
138
|
+
| `emergency` | 7 | System unusable — fatal startup errors |
|
|
139
|
+
|
|
140
|
+
**Examples:**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Full diagnostics (all log output to stderr)
|
|
144
|
+
LOG_LEVEL=debug npx -y @fbdo/smart-agentic-calendar
|
|
145
|
+
|
|
146
|
+
# Only errors and above
|
|
147
|
+
LOG_LEVEL=error npx -y @fbdo/smart-agentic-calendar
|
|
148
|
+
|
|
149
|
+
# Default (warning and above) — quiet operation
|
|
150
|
+
npx -y @fbdo/smart-agentic-calendar
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
In your MCP client config, add `LOG_LEVEL` to the `env` block:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"mcpServers": {
|
|
158
|
+
"smart-agentic-calendar": {
|
|
159
|
+
"command": "npx",
|
|
160
|
+
"args": ["-y", "@fbdo/smart-agentic-calendar"],
|
|
161
|
+
"env": {
|
|
162
|
+
"CALENDAR_DB_PATH": "/path/to/calendar.db",
|
|
163
|
+
"LOG_LEVEL": "debug"
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### MCP protocol (for AI agents and MCP hosts)
|
|
171
|
+
|
|
172
|
+
The server advertises the MCP `logging` capability. MCP clients can control which log messages they receive by sending a `logging/setLevel` request — the SDK filters automatically. Log messages are sent as `notifications/message` with structured data:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"level": "info",
|
|
177
|
+
"logger": "replan",
|
|
178
|
+
"data": { "event": "replan_complete", "blocksCount": 12 }
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The `logger` field identifies the component: `database`, `scheduler`, `replan`, `conflicts`, `dependencies`, `recurrence`, `tools`, `mcp`.
|
|
183
|
+
|
|
184
|
+
The two channels are independent — the MCP client can request `debug` while stderr stays at `warning`, or vice versa.
|
|
185
|
+
|
|
156
186
|
## MCP Tools
|
|
157
187
|
|
|
158
188
|
### Task Management
|
|
@@ -186,10 +216,65 @@ The server reads JSON-RPC messages from stdin and writes responses to stdout. Di
|
|
|
186
216
|
- `set_preferences` — buffer time, default priority, scheduling horizon, minimum block size
|
|
187
217
|
- `get_preferences` — retrieve current configuration
|
|
188
218
|
|
|
219
|
+
## Architecture
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
src/
|
|
223
|
+
models/ Domain types (Task, Event, TimeBlock, Config, etc.)
|
|
224
|
+
common/ Shared utilities (ID generation, time functions, constants)
|
|
225
|
+
storage/ SQLite database layer (better-sqlite3)
|
|
226
|
+
engine/ Scheduling engine, replanning, conflict detection, recurrence
|
|
227
|
+
analytics/ Productivity stats, schedule health, estimation accuracy
|
|
228
|
+
mcp/ MCP server and tool handlers
|
|
229
|
+
index.ts Composition root and entry point
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Single-user, single-process, local-first. All data stored in a local SQLite database with no external service dependencies.
|
|
233
|
+
|
|
234
|
+
## Tech Stack
|
|
235
|
+
|
|
236
|
+
| Component | Choice |
|
|
237
|
+
|-----------|--------|
|
|
238
|
+
| Language | TypeScript (strict mode) |
|
|
239
|
+
| Runtime | Node.js >= 20 |
|
|
240
|
+
| Storage | SQLite via [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) |
|
|
241
|
+
| MCP Transport | stdio |
|
|
242
|
+
| Test Runner | [Vitest](https://vitest.dev/) |
|
|
243
|
+
| Scheduling | Constraint satisfaction algorithm |
|
|
244
|
+
|
|
189
245
|
## Development
|
|
190
246
|
|
|
191
247
|
This project follows **test-driven development** (red-green-refactor) with a healthy test pyramid and dependency injection for testability. Property-based tests are used for pure scheduling functions and serialization round-trips.
|
|
192
248
|
|
|
249
|
+
### Prerequisites
|
|
250
|
+
|
|
251
|
+
- Node.js >= 20
|
|
252
|
+
|
|
253
|
+
### Install and Build
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm install
|
|
257
|
+
npm run build
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
This compiles TypeScript to `dist/` and produces the runnable server at `dist/index.js`.
|
|
261
|
+
|
|
262
|
+
### Test
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
npm test # run all tests (578 tests)
|
|
266
|
+
npm run test:watch # watch mode
|
|
267
|
+
npm run test:coverage # with coverage
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Quality Checks
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
npm run lint # eslint
|
|
274
|
+
npm run format:check # prettier
|
|
275
|
+
npm run quality # all checks (lint, format, duplication, unused code, dependency rules, security)
|
|
276
|
+
```
|
|
277
|
+
|
|
193
278
|
## License
|
|
194
279
|
|
|
195
280
|
MIT
|
|
@@ -3,12 +3,14 @@ import type { TaskRepository } from "../storage/task-repository.js";
|
|
|
3
3
|
import type { ScheduleRepository } from "../storage/schedule-repository.js";
|
|
4
4
|
import type { ConfigRepository } from "../storage/config-repository.js";
|
|
5
5
|
import type { ProductivityStats, ScheduleHealth, EstimationAccuracy, TimeAllocation } from "../models/analytics.js";
|
|
6
|
+
import type { Logger } from "../common/logger.js";
|
|
6
7
|
export declare class AnalyticsEngine {
|
|
7
8
|
private readonly productivity;
|
|
8
9
|
private readonly health;
|
|
9
10
|
private readonly estimation;
|
|
10
11
|
private readonly allocation;
|
|
11
|
-
|
|
12
|
+
private readonly logger;
|
|
13
|
+
constructor(analyticsRepo: AnalyticsRepository, taskRepo: TaskRepository, scheduleRepo: ScheduleRepository, configRepo: ConfigRepository, logger: Logger);
|
|
12
14
|
getProductivityStats(period: string, referenceDate?: Date): ProductivityStats;
|
|
13
15
|
getScheduleHealth(referenceDate?: Date): ScheduleHealth;
|
|
14
16
|
getEstimationAccuracy(period: string, referenceDate?: Date): EstimationAccuracy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics-engine.d.ts","sourceRoot":"","sources":["../../src/analytics/analytics-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACf,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"analytics-engine.d.ts","sourceRoot":"","sources":["../../src/analytics/analytics-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAOlD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,aAAa,EAAE,mBAAmB,EAClC,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,kBAAkB,EAChC,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EAAE,MAAM;IAShB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,IAAI,GAAG,iBAAiB;IAK7E,iBAAiB,CAAC,aAAa,CAAC,EAAE,IAAI,GAAG,cAAc;IAIvD,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,IAAI,GAAG,kBAAkB;IAK/E,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,IAAI,GAAG,cAAc;CAIxE"}
|
|
@@ -8,11 +8,13 @@ export class AnalyticsEngine {
|
|
|
8
8
|
health;
|
|
9
9
|
estimation;
|
|
10
10
|
allocation;
|
|
11
|
-
|
|
11
|
+
logger;
|
|
12
|
+
constructor(analyticsRepo, taskRepo, scheduleRepo, configRepo, logger) {
|
|
12
13
|
this.productivity = new ProductivityCalculator(analyticsRepo);
|
|
13
14
|
this.health = new HealthCalculator(analyticsRepo, taskRepo, scheduleRepo, configRepo);
|
|
14
15
|
this.estimation = new EstimationCalculator(analyticsRepo);
|
|
15
16
|
this.allocation = new AllocationCalculator(analyticsRepo);
|
|
17
|
+
this.logger = logger;
|
|
16
18
|
}
|
|
17
19
|
getProductivityStats(period, referenceDate) {
|
|
18
20
|
validatePeriod(period);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics-engine.js","sourceRoot":"","sources":["../../src/analytics/analytics-engine.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"analytics-engine.js","sourceRoot":"","sources":["../../src/analytics/analytics-engine.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,OAAO,eAAe;IACT,YAAY,CAAyB;IACrC,MAAM,CAAmB;IACzB,UAAU,CAAuB;IACjC,UAAU,CAAuB;IACjC,MAAM,CAAS;IAEhC,YACE,aAAkC,EAClC,QAAwB,EACxB,YAAgC,EAChC,UAA4B,EAC5B,MAAc;QAEd,IAAI,CAAC,YAAY,GAAG,IAAI,sBAAsB,CAAC,aAAa,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,IAAI,gBAAgB,CAAC,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;QACtF,IAAI,CAAC,UAAU,GAAG,IAAI,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,GAAG,IAAI,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,oBAAoB,CAAC,MAAc,EAAE,aAAoB;QACvD,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC1D,CAAC;IAED,iBAAiB,CAAC,aAAoB;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,CAAC;IAED,qBAAqB,CAAC,MAAc,EAAE,aAAoB;QACxD,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;IAED,iBAAiB,CAAC,MAAc,EAAE,aAAoB;QACpD,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type LoggingLevel = "debug" | "info" | "notice" | "warning" | "error" | "critical" | "alert" | "emergency";
|
|
2
|
+
export declare const LOG_LEVEL_SEVERITY: Record<LoggingLevel, number>;
|
|
3
|
+
export interface Logger {
|
|
4
|
+
debug(logger: string, data: unknown): void;
|
|
5
|
+
info(logger: string, data: unknown): void;
|
|
6
|
+
notice(logger: string, data: unknown): void;
|
|
7
|
+
warning(logger: string, data: unknown): void;
|
|
8
|
+
error(logger: string, data: unknown): void;
|
|
9
|
+
critical(logger: string, data: unknown): void;
|
|
10
|
+
alert(logger: string, data: unknown): void;
|
|
11
|
+
emergency(logger: string, data: unknown): void;
|
|
12
|
+
}
|
|
13
|
+
export type LogTransport = (level: LoggingLevel, logger: string, data: unknown) => void;
|
|
14
|
+
export declare class AppLogger implements Logger {
|
|
15
|
+
private readonly transports;
|
|
16
|
+
constructor(transports: LogTransport[]);
|
|
17
|
+
addTransport(transport: LogTransport): void;
|
|
18
|
+
debug(logger: string, data: unknown): void;
|
|
19
|
+
info(logger: string, data: unknown): void;
|
|
20
|
+
notice(logger: string, data: unknown): void;
|
|
21
|
+
warning(logger: string, data: unknown): void;
|
|
22
|
+
error(logger: string, data: unknown): void;
|
|
23
|
+
critical(logger: string, data: unknown): void;
|
|
24
|
+
alert(logger: string, data: unknown): void;
|
|
25
|
+
emergency(logger: string, data: unknown): void;
|
|
26
|
+
private emit;
|
|
27
|
+
}
|
|
28
|
+
export declare function createStderrTransport(minLevel: LoggingLevel): LogTransport;
|
|
29
|
+
export declare function createNoOpLogger(): Logger;
|
|
30
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/common/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,OAAO,GACP,MAAM,GACN,QAAQ,GACR,SAAS,GACT,OAAO,GACP,UAAU,GACV,OAAO,GACP,WAAW,CAAC;AAEhB,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAS3D,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;CAChD;AAGD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AAExF,qBAAa,SAAU,YAAW,MAAM;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;gBAEhC,UAAU,EAAE,YAAY,EAAE;IAItC,YAAY,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAI3C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI1C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAIzC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI3C,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI5C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI1C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI7C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI1C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAI9C,OAAO,CAAC,IAAI;CAKb;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CAQ1E;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAczC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export const LOG_LEVEL_SEVERITY = {
|
|
2
|
+
debug: 0,
|
|
3
|
+
info: 1,
|
|
4
|
+
notice: 2,
|
|
5
|
+
warning: 3,
|
|
6
|
+
error: 4,
|
|
7
|
+
critical: 5,
|
|
8
|
+
alert: 6,
|
|
9
|
+
emergency: 7,
|
|
10
|
+
};
|
|
11
|
+
export class AppLogger {
|
|
12
|
+
transports;
|
|
13
|
+
constructor(transports) {
|
|
14
|
+
this.transports = [...transports];
|
|
15
|
+
}
|
|
16
|
+
addTransport(transport) {
|
|
17
|
+
this.transports.push(transport);
|
|
18
|
+
}
|
|
19
|
+
debug(logger, data) {
|
|
20
|
+
this.emit("debug", logger, data);
|
|
21
|
+
}
|
|
22
|
+
info(logger, data) {
|
|
23
|
+
this.emit("info", logger, data);
|
|
24
|
+
}
|
|
25
|
+
notice(logger, data) {
|
|
26
|
+
this.emit("notice", logger, data);
|
|
27
|
+
}
|
|
28
|
+
warning(logger, data) {
|
|
29
|
+
this.emit("warning", logger, data);
|
|
30
|
+
}
|
|
31
|
+
error(logger, data) {
|
|
32
|
+
this.emit("error", logger, data);
|
|
33
|
+
}
|
|
34
|
+
critical(logger, data) {
|
|
35
|
+
this.emit("critical", logger, data);
|
|
36
|
+
}
|
|
37
|
+
alert(logger, data) {
|
|
38
|
+
this.emit("alert", logger, data);
|
|
39
|
+
}
|
|
40
|
+
emergency(logger, data) {
|
|
41
|
+
this.emit("emergency", logger, data);
|
|
42
|
+
}
|
|
43
|
+
emit(level, logger, data) {
|
|
44
|
+
for (const transport of this.transports) {
|
|
45
|
+
transport(level, logger, data);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function createStderrTransport(minLevel) {
|
|
50
|
+
const minSeverity = LOG_LEVEL_SEVERITY[minLevel];
|
|
51
|
+
return (level, logger, data) => {
|
|
52
|
+
if (LOG_LEVEL_SEVERITY[level] < minSeverity)
|
|
53
|
+
return;
|
|
54
|
+
const timestamp = new Date().toISOString();
|
|
55
|
+
const message = typeof data === "string" ? data : JSON.stringify(data);
|
|
56
|
+
process.stderr.write(`${timestamp} [${level.toUpperCase()}] [${logger}] ${message}\n`);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function createNoOpLogger() {
|
|
60
|
+
const noop = () => {
|
|
61
|
+
// Intentionally empty - no-op logger
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
debug: noop,
|
|
65
|
+
info: noop,
|
|
66
|
+
notice: noop,
|
|
67
|
+
warning: noop,
|
|
68
|
+
error: noop,
|
|
69
|
+
critical: noop,
|
|
70
|
+
alert: noop,
|
|
71
|
+
emergency: noop,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/common/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import type { TimeBlock } from "../models/schedule.js";
|
|
|
3
3
|
import type { Availability } from "../models/config.js";
|
|
4
4
|
import type { Conflict, DeprioritizationSuggestion } from "../models/conflict.js";
|
|
5
5
|
import type { DependencyEdge } from "../models/dependency.js";
|
|
6
|
+
import type { Logger } from "../common/logger.js";
|
|
6
7
|
interface CompetingTask {
|
|
7
8
|
taskId: string;
|
|
8
9
|
priority: TaskPriority;
|
|
@@ -10,6 +11,8 @@ interface CompetingTask {
|
|
|
10
11
|
scheduledMinutes: number;
|
|
11
12
|
}
|
|
12
13
|
export declare class ConflictDetector {
|
|
14
|
+
private readonly logger;
|
|
15
|
+
constructor(logger: Logger);
|
|
13
16
|
detectConflicts(tasks: Task[], timeBlocks: TimeBlock[], _availability: Availability, dependencies: DependencyEdge[], now: Date): Conflict[];
|
|
14
17
|
suggestDeprioritizations(atRiskTask: Task, competingTasks: CompetingTask[], requiredMinutes: number): DeprioritizationSuggestion[];
|
|
15
18
|
findCompetingTasks(atRiskTask: Task, timeBlocks: TimeBlock[], allTasks: Task[]): CompetingTask[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-detector.d.ts","sourceRoot":"","sources":["../../src/engine/conflict-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"conflict-detector.d.ts","sourceRoot":"","sources":["../../src/engine/conflict-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAUlD,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,MAAM;IAG1B,eAAe,CACb,KAAK,EAAE,IAAI,EAAE,EACb,UAAU,EAAE,SAAS,EAAE,EACvB,aAAa,EAAE,YAAY,EAC3B,YAAY,EAAE,cAAc,EAAE,EAC9B,GAAG,EAAE,IAAI,GACR,QAAQ,EAAE;IA2Eb,wBAAwB,CACtB,UAAU,EAAE,IAAI,EAChB,cAAc,EAAE,aAAa,EAAE,EAC/B,eAAe,EAAE,MAAM,GACtB,0BAA0B,EAAE;IAmC/B,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE;IAqChG,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,qCAAqC;IAO7C,OAAO,CAAC,8BAA8B;IAqCtC,OAAO,CAAC,qBAAqB;CA8B9B"}
|
|
@@ -6,6 +6,10 @@ const PRIORITY_RANK = {
|
|
|
6
6
|
P4: 4,
|
|
7
7
|
};
|
|
8
8
|
export class ConflictDetector {
|
|
9
|
+
logger;
|
|
10
|
+
constructor(logger) {
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
}
|
|
9
13
|
detectConflicts(tasks, timeBlocks, _availability, dependencies, now) {
|
|
10
14
|
const conflicts = [];
|
|
11
15
|
for (const task of tasks) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conflict-detector.js","sourceRoot":"","sources":["../../src/engine/conflict-detector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conflict-detector.js","sourceRoot":"","sources":["../../src/engine/conflict-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Task } from "../models/task.js";
|
|
2
2
|
import type { DependencyEdge } from "../models/dependency.js";
|
|
3
|
+
import type { Logger } from "../common/logger.js";
|
|
3
4
|
export declare class DependencyResolver {
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(logger: Logger);
|
|
4
7
|
validateNoCycles(taskId: string, dependsOnId: string, existingDeps: DependencyEdge[]): boolean;
|
|
5
8
|
topologicalSort(tasks: Task[], dependencies: DependencyEdge[]): Task[];
|
|
6
9
|
getBlockedTasks(tasks: Task[], dependencies: DependencyEdge[]): Task[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-resolver.d.ts","sourceRoot":"","sources":["../../src/engine/dependency-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"dependency-resolver.d.ts","sourceRoot":"","sources":["../../src/engine/dependency-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA2ElD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,MAAM;IAI1B,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,OAAO;IAyD9F,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE;IAqCtE,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE;CAqBvE"}
|
|
@@ -58,6 +58,10 @@ function insertSorted(queue, task) {
|
|
|
58
58
|
queue.splice(insertIdx, 0, task);
|
|
59
59
|
}
|
|
60
60
|
export class DependencyResolver {
|
|
61
|
+
logger;
|
|
62
|
+
constructor(logger) {
|
|
63
|
+
this.logger = logger;
|
|
64
|
+
}
|
|
61
65
|
validateNoCycles(taskId, dependsOnId, existingDeps) {
|
|
62
66
|
if (taskId === dependsOnId) {
|
|
63
67
|
throw new ValidationError("a task cannot depend on itself");
|
|
@@ -94,7 +98,9 @@ export class DependencyResolver {
|
|
|
94
98
|
while (stack.length > 0) {
|
|
95
99
|
const current = stack.pop();
|
|
96
100
|
if (current === taskId) {
|
|
97
|
-
|
|
101
|
+
const cycle = [taskId, ...path, current];
|
|
102
|
+
this.logger.warning("dependencies", { event: "cycle_detected", cycle });
|
|
103
|
+
throw new CircularDependencyError(cycle);
|
|
98
104
|
}
|
|
99
105
|
if (visited.has(current)) {
|
|
100
106
|
continue;
|
|
@@ -134,6 +140,7 @@ export class DependencyResolver {
|
|
|
134
140
|
}
|
|
135
141
|
if (result.length < tasks.length) {
|
|
136
142
|
const remainingIds = tasks.filter((t) => !result.includes(t)).map((t) => t.id);
|
|
143
|
+
this.logger.warning("dependencies", { event: "cycle_detected", cycle: remainingIds });
|
|
137
144
|
throw new CircularDependencyError(remainingIds);
|
|
138
145
|
}
|
|
139
146
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../src/engine/dependency-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dependency-resolver.js","sourceRoot":"","sources":["../../src/engine/dependency-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,14 @@ import type { RecurrenceRepository } from "../storage/recurrence-repository.js";
|
|
|
2
2
|
import type { TaskRepository } from "../storage/task-repository.js";
|
|
3
3
|
import type { RecurrenceTemplate, RecurrenceInstance } from "../models/recurrence.js";
|
|
4
4
|
import type { Task } from "../models/task.js";
|
|
5
|
+
import type { Logger } from "../common/logger.js";
|
|
5
6
|
type TaskFields = Omit<Task, "id" | "createdAt" | "updatedAt" | "status" | "actualDuration">;
|
|
6
7
|
export declare class RecurrenceManager {
|
|
7
8
|
private readonly recurrenceRepo;
|
|
8
9
|
private readonly taskRepo;
|
|
10
|
+
private readonly logger;
|
|
9
11
|
private currentHorizonEnd;
|
|
10
|
-
constructor(recurrenceRepo: RecurrenceRepository, taskRepo: TaskRepository);
|
|
12
|
+
constructor(recurrenceRepo: RecurrenceRepository, taskRepo: TaskRepository, logger: Logger);
|
|
11
13
|
createRecurringTask(taskData: TaskFields, rruleString: string, now: Date, horizonEnd: Date): {
|
|
12
14
|
template: RecurrenceTemplate;
|
|
13
15
|
instances: RecurrenceInstance[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recurrence-manager.d.ts","sourceRoot":"","sources":["../../src/engine/recurrence-manager.ts"],"names":[],"mappings":"AAIA,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;
|
|
1
|
+
{"version":3,"file":"recurrence-manager.d.ts","sourceRoot":"","sources":["../../src/engine/recurrence-manager.ts"],"names":[],"mappings":"AAIA,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;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,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,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,iBAAiB,CAAqB;gBAElC,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM;IAM1F,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"}
|
|
@@ -4,10 +4,12 @@ import { ValidationError, NotFoundError, InvalidStateError } from "../models/err
|
|
|
4
4
|
export class RecurrenceManager {
|
|
5
5
|
recurrenceRepo;
|
|
6
6
|
taskRepo;
|
|
7
|
+
logger;
|
|
7
8
|
currentHorizonEnd = null;
|
|
8
|
-
constructor(recurrenceRepo, taskRepo) {
|
|
9
|
+
constructor(recurrenceRepo, taskRepo, logger) {
|
|
9
10
|
this.recurrenceRepo = recurrenceRepo;
|
|
10
11
|
this.taskRepo = taskRepo;
|
|
12
|
+
this.logger = logger;
|
|
11
13
|
}
|
|
12
14
|
createRecurringTask(taskData, rruleString, now, horizonEnd) {
|
|
13
15
|
// Validate RRULE before creating anything
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recurrence-manager.js","sourceRoot":"","sources":["../../src/engine/recurrence-manager.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,OAAO,CAAC;AAG7B,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"recurrence-manager.js","sourceRoot":"","sources":["../../src/engine/recurrence-manager.ts"],"names":[],"mappings":"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"}
|