saga-mcp 1.4.0 → 1.5.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 +76 -56
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +33 -0
- package/dist/schema.js.map +1 -1
- package/dist/tools/activity.js +22 -0
- package/dist/tools/activity.js.map +1 -1
- package/dist/tools/comments.d.ts +4 -0
- package/dist/tools/comments.js +58 -0
- package/dist/tools/comments.js.map +1 -0
- package/dist/tools/dashboard.js +41 -0
- package/dist/tools/dashboard.js.map +1 -1
- package/dist/tools/export-import.js +45 -7
- package/dist/tools/export-import.js.map +1 -1
- package/dist/tools/tasks.d.ts +2 -0
- package/dist/tools/tasks.js +141 -12
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/templates.d.ts +4 -0
- package/dist/tools/templates.js +150 -0
- package/dist/tools/templates.js.map +1 -0
- package/manifest.json +16 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,14 +7,18 @@ A Jira-like project tracker MCP server for AI agents. SQLite-backed, per-project
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **Full hierarchy**: Projects > Epics > Tasks > Subtasks
|
|
10
|
+
- **Task dependencies**: Express sequencing with auto-block/unblock when deps are met
|
|
11
|
+
- **Comments**: Threaded discussions on tasks — leave breadcrumbs across sessions
|
|
12
|
+
- **Templates**: Reusable task sets with `{variable}` substitution
|
|
13
|
+
- **Dashboard**: One tool call gives full overview with natural language summary
|
|
10
14
|
- **SQLite**: Self-contained `.tracker.db` file per project — zero setup, no external database
|
|
11
15
|
- **Activity log**: Every mutation is automatically tracked with old/new values
|
|
12
|
-
- **Dashboard**: One tool call gives full project overview (stats, blocked tasks, recent changes)
|
|
13
16
|
- **Notes system**: Decisions, context, meeting notes, blockers — all searchable
|
|
14
17
|
- **Batch operations**: Create multiple subtasks or update multiple tasks in one call
|
|
15
|
-
- **
|
|
16
|
-
- **Import/export**: Full project backup and migration as JSON
|
|
18
|
+
- **31 focused tools**: With MCP safety annotations on every tool
|
|
19
|
+
- **Import/export**: Full project backup and migration as JSON (with dependencies and comments)
|
|
17
20
|
- **Source references**: Link tasks to specific code locations
|
|
21
|
+
- **Auto time tracking**: Hours computed automatically from activity log
|
|
18
22
|
- **Cross-platform**: Works on macOS, Windows, and Linux
|
|
19
23
|
|
|
20
24
|
## Quick Start
|
|
@@ -79,7 +83,7 @@ No API keys, no accounts, no external services. Everything is stored locally in
|
|
|
79
83
|
| Tool | Description | Annotations |
|
|
80
84
|
|------|-------------|-------------|
|
|
81
85
|
| `tracker_init` | Initialize tracker and create first project | `readOnly: false`, `idempotent: true` |
|
|
82
|
-
| `tracker_dashboard` | Full project overview
|
|
86
|
+
| `tracker_dashboard` | Full project overview with natural language summary | `readOnly: true` |
|
|
83
87
|
|
|
84
88
|
### Projects
|
|
85
89
|
|
|
@@ -101,10 +105,10 @@ No API keys, no accounts, no external services. Everything is stored locally in
|
|
|
101
105
|
|
|
102
106
|
| Tool | Description | Annotations |
|
|
103
107
|
|------|-------------|-------------|
|
|
104
|
-
| `task_create` | Create a task
|
|
105
|
-
| `task_list` | List/filter tasks
|
|
106
|
-
| `task_get` | Get task with subtasks and
|
|
107
|
-
| `task_update` | Update task (
|
|
108
|
+
| `task_create` | Create a task with optional dependencies | `readOnly: false` |
|
|
109
|
+
| `task_list` | List/filter tasks with dependency info | `readOnly: true` |
|
|
110
|
+
| `task_get` | Get task with subtasks, notes, comments, and dependencies | `readOnly: true` |
|
|
111
|
+
| `task_update` | Update task (auto-logs, auto-blocks/unblocks) | `readOnly: false`, `idempotent: true` |
|
|
108
112
|
| `task_batch_update` | Update multiple tasks at once | `readOnly: false`, `idempotent: true` |
|
|
109
113
|
|
|
110
114
|
### Subtasks
|
|
@@ -115,6 +119,22 @@ No API keys, no accounts, no external services. Everything is stored locally in
|
|
|
115
119
|
| `subtask_update` | Update subtask title/status | `readOnly: false`, `idempotent: true` |
|
|
116
120
|
| `subtask_delete` | Delete subtask(s) — supports batch | `destructive: true`, `idempotent: true` |
|
|
117
121
|
|
|
122
|
+
### Comments
|
|
123
|
+
|
|
124
|
+
| Tool | Description | Annotations |
|
|
125
|
+
|------|-------------|-------------|
|
|
126
|
+
| `comment_add` | Add a comment to a task (threaded discussion) | `readOnly: false` |
|
|
127
|
+
| `comment_list` | List all comments on a task | `readOnly: true` |
|
|
128
|
+
|
|
129
|
+
### Templates
|
|
130
|
+
|
|
131
|
+
| Tool | Description | Annotations |
|
|
132
|
+
|------|-------------|-------------|
|
|
133
|
+
| `template_create` | Create a reusable task template with `{variable}` placeholders | `readOnly: false` |
|
|
134
|
+
| `template_list` | List available templates | `readOnly: true` |
|
|
135
|
+
| `template_apply` | Apply template to create tasks with variable substitution | `readOnly: false` |
|
|
136
|
+
| `template_delete` | Delete a template | `destructive: true`, `idempotent: true` |
|
|
137
|
+
|
|
118
138
|
### Notes
|
|
119
139
|
|
|
120
140
|
| Tool | Description | Annotations |
|
|
@@ -136,12 +156,12 @@ No API keys, no accounts, no external services. Everything is stored locally in
|
|
|
136
156
|
|
|
137
157
|
| Tool | Description | Annotations |
|
|
138
158
|
|------|-------------|-------------|
|
|
139
|
-
| `tracker_export` | Export full project as nested JSON
|
|
159
|
+
| `tracker_export` | Export full project as nested JSON (includes dependencies and comments) | `readOnly: true` |
|
|
140
160
|
| `tracker_import` | Import project from JSON (matching export format) | `readOnly: false` |
|
|
141
161
|
|
|
142
162
|
## Usage Examples
|
|
143
163
|
|
|
144
|
-
### Example 1: Starting a
|
|
164
|
+
### Example 1: Starting a project with dependencies
|
|
145
165
|
|
|
146
166
|
**User prompt:** "Set up tracking for my new e-commerce API project"
|
|
147
167
|
|
|
@@ -149,68 +169,59 @@ No API keys, no accounts, no external services. Everything is stored locally in
|
|
|
149
169
|
```
|
|
150
170
|
tracker_init({ project_name: "E-Commerce API", project_description: "REST API for online store" })
|
|
151
171
|
epic_create({ project_id: 1, name: "Authentication", priority: "high" })
|
|
152
|
-
|
|
153
|
-
task_create({ epic_id: 1, title: "Implement JWT auth", priority: "high" })
|
|
154
|
-
task_create({ epic_id: 1, title: "Add OAuth2 Google login", priority: "medium" })
|
|
155
|
-
subtask_create({ task_id: 1, titles: ["Set up JWT library", "Create login endpoint", "Create refresh endpoint", "Add middleware"] })
|
|
172
|
+
task_create({ epic_id: 1, title: "Design auth schema", priority: "critical" })
|
|
173
|
+
task_create({ epic_id: 1, title: "Implement JWT auth", priority: "high", depends_on: [1] })
|
|
174
|
+
task_create({ epic_id: 1, title: "Add OAuth2 Google login", priority: "medium", depends_on: [2] })
|
|
156
175
|
```
|
|
157
176
|
|
|
158
|
-
**
|
|
159
|
-
|
|
160
|
-
### Example 2: Resuming work on an existing project
|
|
177
|
+
**Result:** Task 2 and 3 are auto-blocked because their dependencies aren't done yet. When task 1 is marked done, task 2 auto-unblocks.
|
|
161
178
|
|
|
162
|
-
|
|
179
|
+
### Example 2: Resuming work with dashboard summary
|
|
163
180
|
|
|
164
181
|
**Tool calls:**
|
|
165
182
|
```
|
|
166
183
|
tracker_dashboard({})
|
|
167
184
|
```
|
|
168
185
|
|
|
169
|
-
**
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
"project": { "id": 1, "name": "E-Commerce API", "status": "active" },
|
|
173
|
-
"stats": {
|
|
174
|
-
"total_epics": 2,
|
|
175
|
-
"total_tasks": 5,
|
|
176
|
-
"tasks_done": 2,
|
|
177
|
-
"tasks_in_progress": 1,
|
|
178
|
-
"tasks_blocked": 1,
|
|
179
|
-
"tasks_todo": 1,
|
|
180
|
-
"completion_pct": 40.0
|
|
181
|
-
},
|
|
182
|
-
"epics": [
|
|
183
|
-
{ "name": "Authentication", "task_count": 3, "done_count": 2, "completion_pct": 66.7 },
|
|
184
|
-
{ "name": "Product Catalog", "task_count": 2, "done_count": 0, "completion_pct": 0 }
|
|
185
|
-
],
|
|
186
|
-
"blocked_tasks": [
|
|
187
|
-
{ "id": 4, "title": "Add rate limiting", "epic_name": "Authentication" }
|
|
188
|
-
],
|
|
189
|
-
"recent_activity": [...],
|
|
190
|
-
"recent_notes": [...]
|
|
191
|
-
}
|
|
186
|
+
**Response includes a natural language summary:**
|
|
187
|
+
```
|
|
188
|
+
"E-Commerce API: 5 tasks across 2 epics. 40% complete. Active: Authentication (2/3 done). Next up: Product Catalog (2 tasks). 1 blocked task(s)."
|
|
192
189
|
```
|
|
193
190
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
### Example 3: Recording a decision and marking tasks done
|
|
191
|
+
Plus the full structured data (stats, epics, blocked tasks, overdue tasks, activity, notes).
|
|
197
192
|
|
|
198
|
-
|
|
193
|
+
### Example 3: Using templates for repeated workflows
|
|
199
194
|
|
|
200
|
-
**
|
|
195
|
+
**Create a template:**
|
|
201
196
|
```
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
197
|
+
template_create({
|
|
198
|
+
name: "feature_workflow",
|
|
199
|
+
description: "Standard feature implementation",
|
|
200
|
+
tasks: [
|
|
201
|
+
{ "title": "Design {feature} API", "priority": "critical", "estimated_hours": 2 },
|
|
202
|
+
{ "title": "Implement {feature}", "priority": "high", "estimated_hours": 8 },
|
|
203
|
+
{ "title": "Write tests for {feature}", "priority": "high", "estimated_hours": 4 },
|
|
204
|
+
{ "title": "Document {feature}", "priority": "medium", "estimated_hours": 1 }
|
|
205
|
+
]
|
|
209
206
|
})
|
|
210
|
-
task_batch_update({ ids: [8, 9], status: "done" })
|
|
211
207
|
```
|
|
212
208
|
|
|
213
|
-
**
|
|
209
|
+
**Apply it:**
|
|
210
|
+
```
|
|
211
|
+
template_apply({ template_id: 1, epic_id: 2, variables: { "feature": "user auth" } })
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Creates 4 tasks: "Design user auth API", "Implement user auth", "Write tests for user auth", "Document user auth".
|
|
215
|
+
|
|
216
|
+
### Example 4: Task comments as decision trail
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
comment_add({ task_id: 5, content: "Investigated root cause: CORS headers missing on preflight" })
|
|
220
|
+
comment_add({ task_id: 5, content: "Fixed by adding OPTIONS handler. Tested with curl." })
|
|
221
|
+
task_update({ id: 5, status: "done" })
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Comments persist across sessions — next time an agent calls `task_get(5)`, it sees the full discussion thread.
|
|
214
225
|
|
|
215
226
|
## How It Works
|
|
216
227
|
|
|
@@ -222,9 +233,18 @@ saga-mcp stores everything in a single SQLite file (`.tracker.db`) per project.
|
|
|
222
233
|
Project
|
|
223
234
|
└── Epic (feature/workstream)
|
|
224
235
|
└── Task (unit of work)
|
|
225
|
-
|
|
236
|
+
├── Subtask (checklist item)
|
|
237
|
+
├── Comment (discussion thread)
|
|
238
|
+
└── Dependencies (blocked by other tasks)
|
|
226
239
|
```
|
|
227
240
|
|
|
241
|
+
### Task Dependencies
|
|
242
|
+
|
|
243
|
+
Tasks can depend on other tasks. When you set `depends_on: [2, 3]` on a task:
|
|
244
|
+
- The task is auto-blocked if any dependency isn't `done`
|
|
245
|
+
- When a dependency is marked `done`, downstream tasks are re-evaluated
|
|
246
|
+
- If all dependencies are met, the blocked task auto-unblocks to `todo`
|
|
247
|
+
|
|
228
248
|
### Note Types
|
|
229
249
|
|
|
230
250
|
Notes replace scattered markdown files. Each note has a type:
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,8 @@ import { definitions as noteDefs, handlers as noteHandlers } from './tools/notes
|
|
|
10
10
|
import { definitions as dashboardDefs, handlers as dashboardHandlers } from './tools/dashboard.js';
|
|
11
11
|
import { definitions as searchDefs, handlers as searchHandlers } from './tools/search.js';
|
|
12
12
|
import { definitions as activityDefs, handlers as activityHandlers } from './tools/activity.js';
|
|
13
|
+
import { definitions as commentDefs, handlers as commentHandlers } from './tools/comments.js';
|
|
14
|
+
import { definitions as templateDefs, handlers as templateHandlers } from './tools/templates.js';
|
|
13
15
|
import { definitions as exportImportDefs, handlers as exportImportHandlers } from './tools/export-import.js';
|
|
14
16
|
import { closeDb } from './db.js';
|
|
15
17
|
const ALL_TOOLS = [
|
|
@@ -18,6 +20,8 @@ const ALL_TOOLS = [
|
|
|
18
20
|
...taskDefs,
|
|
19
21
|
...subtaskDefs,
|
|
20
22
|
...noteDefs,
|
|
23
|
+
...commentDefs,
|
|
24
|
+
...templateDefs,
|
|
21
25
|
...dashboardDefs,
|
|
22
26
|
...searchDefs,
|
|
23
27
|
...activityDefs,
|
|
@@ -29,6 +33,8 @@ const ALL_HANDLERS = {
|
|
|
29
33
|
...taskHandlers,
|
|
30
34
|
...subtaskHandlers,
|
|
31
35
|
...noteHandlers,
|
|
36
|
+
...commentHandlers,
|
|
37
|
+
...templateHandlers,
|
|
32
38
|
...dashboardHandlers,
|
|
33
39
|
...searchHandlers,
|
|
34
40
|
...activityHandlers,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,WAAW,IAAI,WAAW,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,WAAW,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,WAAW,IAAI,WAAW,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,IAAI,QAAQ,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACnG,OAAO,EAAE,WAAW,IAAI,UAAU,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC7G,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,SAAS,GAAW;IACxB,GAAG,WAAW;IACd,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,WAAW;IACd,GAAG,QAAQ;IACX,GAAG,aAAa;IAChB,GAAG,UAAU;IACb,GAAG,YAAY;IACf,GAAG,gBAAgB;CACpB,CAAC;AAEF,MAAM,YAAY,GAA+D;IAC/E,GAAG,eAAe;IAClB,GAAG,YAAY;IACf,GAAG,YAAY;IACf,GAAG,eAAe;IAClB,GAAG,YAAY;IACf,GAAG,iBAAiB;IACpB,GAAG,cAAc;IACjB,GAAG,gBAAgB;IACnB,GAAG,oBAAoB;CACxB,CAAC;AAEF,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,EACrC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;AAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACnC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;iBACzE;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;AACvD,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,EAAE,CAAC;IACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SCHEMA_SQL = "\n-- Core hierarchy: projects > epics > tasks > subtasks\n\nCREATE TABLE IF NOT EXISTS projects (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'active'\n CHECK (status IN ('active', 'on_hold', 'completed', 'archived')),\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS epics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'planned'\n CHECK (status IN ('planned', 'in_progress', 'completed', 'cancelled')),\n priority TEXT NOT NULL DEFAULT 'medium'\n CHECK (priority IN ('low', 'medium', 'high', 'critical')),\n sort_order INTEGER NOT NULL DEFAULT 0,\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS tasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n epic_id INTEGER NOT NULL REFERENCES epics(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'todo'\n CHECK (status IN ('todo', 'in_progress', 'review', 'done', 'blocked')),\n priority TEXT NOT NULL DEFAULT 'medium'\n CHECK (priority IN ('low', 'medium', 'high', 'critical')),\n sort_order INTEGER NOT NULL DEFAULT 0,\n assigned_to TEXT,\n estimated_hours REAL,\n actual_hours REAL,\n due_date TEXT,\n source_ref TEXT,\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS subtasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'todo'\n CHECK (status IN ('todo', 'in_progress', 'done')),\n sort_order INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Unified notes (replaces summaries + status_updates + context)\n\nCREATE TABLE IF NOT EXISTS notes (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n note_type TEXT NOT NULL DEFAULT 'general'\n CHECK (note_type IN (\n 'general', 'decision', 'context', 'meeting',\n 'technical', 'blocker', 'progress', 'release'\n )),\n related_entity_type TEXT CHECK (related_entity_type IN ('project', 'epic', 'task') OR related_entity_type IS NULL),\n related_entity_id INTEGER,\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Automatic activity log\n\nCREATE TABLE IF NOT EXISTS activity_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity_type TEXT NOT NULL,\n entity_id INTEGER NOT NULL,\n action TEXT NOT NULL,\n field_name TEXT,\n old_value TEXT,\n new_value TEXT,\n summary TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes\n\nCREATE INDEX IF NOT EXISTS idx_epics_project_id ON epics(project_id);\nCREATE INDEX IF NOT EXISTS idx_tasks_epic_id ON tasks(epic_id);\nCREATE INDEX IF NOT EXISTS idx_subtasks_task_id ON subtasks(task_id);\n\nCREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);\nCREATE INDEX IF NOT EXISTS idx_epics_status ON epics(status);\nCREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\nCREATE INDEX IF NOT EXISTS idx_subtasks_status ON subtasks(status);\n\nCREATE INDEX IF NOT EXISTS idx_epics_priority ON epics(priority);\nCREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);\n\nCREATE INDEX IF NOT EXISTS idx_epics_sort ON epics(project_id, sort_order);\nCREATE INDEX IF NOT EXISTS idx_tasks_sort ON tasks(epic_id, sort_order);\nCREATE INDEX IF NOT EXISTS idx_subtasks_sort ON subtasks(task_id, sort_order);\n\nCREATE INDEX IF NOT EXISTS idx_notes_type ON notes(note_type);\nCREATE INDEX IF NOT EXISTS idx_notes_entity ON notes(related_entity_type, related_entity_id);\nCREATE INDEX IF NOT EXISTS idx_notes_created ON notes(created_at DESC);\n\nCREATE INDEX IF NOT EXISTS idx_activity_entity ON activity_log(entity_type, entity_id);\nCREATE INDEX IF NOT EXISTS idx_activity_created ON activity_log(created_at DESC);\nCREATE INDEX IF NOT EXISTS idx_activity_action ON activity_log(action);\n\nCREATE INDEX IF NOT EXISTS idx_tasks_assigned ON tasks(assigned_to);\nCREATE INDEX IF NOT EXISTS idx_tasks_due ON tasks(due_date);\n";
|
|
1
|
+
export declare const SCHEMA_SQL = "\n-- Core hierarchy: projects > epics > tasks > subtasks\n\nCREATE TABLE IF NOT EXISTS projects (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'active'\n CHECK (status IN ('active', 'on_hold', 'completed', 'archived')),\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS epics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n name TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'planned'\n CHECK (status IN ('planned', 'in_progress', 'completed', 'cancelled')),\n priority TEXT NOT NULL DEFAULT 'medium'\n CHECK (priority IN ('low', 'medium', 'high', 'critical')),\n sort_order INTEGER NOT NULL DEFAULT 0,\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS tasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n epic_id INTEGER NOT NULL REFERENCES epics(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'todo'\n CHECK (status IN ('todo', 'in_progress', 'review', 'done', 'blocked')),\n priority TEXT NOT NULL DEFAULT 'medium'\n CHECK (priority IN ('low', 'medium', 'high', 'critical')),\n sort_order INTEGER NOT NULL DEFAULT 0,\n assigned_to TEXT,\n estimated_hours REAL,\n actual_hours REAL,\n due_date TEXT,\n source_ref TEXT,\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\nCREATE TABLE IF NOT EXISTS subtasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n title TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'todo'\n CHECK (status IN ('todo', 'in_progress', 'done')),\n sort_order INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Task dependencies (junction table)\n\nCREATE TABLE IF NOT EXISTS task_dependencies (\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n depends_on_task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n PRIMARY KEY (task_id, depends_on_task_id)\n);\n\n-- Comments (threaded discussions on tasks)\n\nCREATE TABLE IF NOT EXISTS comments (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,\n author TEXT,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Task templates\n\nCREATE TABLE IF NOT EXISTS templates (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL UNIQUE,\n description TEXT,\n template_data TEXT NOT NULL DEFAULT '[]',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Unified notes (replaces summaries + status_updates + context)\n\nCREATE TABLE IF NOT EXISTS notes (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n note_type TEXT NOT NULL DEFAULT 'general'\n CHECK (note_type IN (\n 'general', 'decision', 'context', 'meeting',\n 'technical', 'blocker', 'progress', 'release'\n )),\n related_entity_type TEXT CHECK (related_entity_type IN ('project', 'epic', 'task') OR related_entity_type IS NULL),\n related_entity_id INTEGER,\n tags TEXT NOT NULL DEFAULT '[]',\n metadata TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Automatic activity log\n\nCREATE TABLE IF NOT EXISTS activity_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity_type TEXT NOT NULL,\n entity_id INTEGER NOT NULL,\n action TEXT NOT NULL,\n field_name TEXT,\n old_value TEXT,\n new_value TEXT,\n summary TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Indexes\n\nCREATE INDEX IF NOT EXISTS idx_epics_project_id ON epics(project_id);\nCREATE INDEX IF NOT EXISTS idx_tasks_epic_id ON tasks(epic_id);\nCREATE INDEX IF NOT EXISTS idx_subtasks_task_id ON subtasks(task_id);\n\nCREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);\nCREATE INDEX IF NOT EXISTS idx_epics_status ON epics(status);\nCREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\nCREATE INDEX IF NOT EXISTS idx_subtasks_status ON subtasks(status);\n\nCREATE INDEX IF NOT EXISTS idx_epics_priority ON epics(priority);\nCREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);\n\nCREATE INDEX IF NOT EXISTS idx_epics_sort ON epics(project_id, sort_order);\nCREATE INDEX IF NOT EXISTS idx_tasks_sort ON tasks(epic_id, sort_order);\nCREATE INDEX IF NOT EXISTS idx_subtasks_sort ON subtasks(task_id, sort_order);\n\nCREATE INDEX IF NOT EXISTS idx_notes_type ON notes(note_type);\nCREATE INDEX IF NOT EXISTS idx_notes_entity ON notes(related_entity_type, related_entity_id);\nCREATE INDEX IF NOT EXISTS idx_notes_created ON notes(created_at DESC);\n\nCREATE INDEX IF NOT EXISTS idx_activity_entity ON activity_log(entity_type, entity_id);\nCREATE INDEX IF NOT EXISTS idx_activity_created ON activity_log(created_at DESC);\nCREATE INDEX IF NOT EXISTS idx_activity_action ON activity_log(action);\n\nCREATE INDEX IF NOT EXISTS idx_tasks_assigned ON tasks(assigned_to);\nCREATE INDEX IF NOT EXISTS idx_tasks_due ON tasks(due_date);\n\nCREATE INDEX IF NOT EXISTS idx_task_deps_depends ON task_dependencies(depends_on_task_id);\nCREATE INDEX IF NOT EXISTS idx_comments_task ON comments(task_id);\n";
|
package/dist/schema.js
CHANGED
|
@@ -61,6 +61,36 @@ CREATE TABLE IF NOT EXISTS subtasks (
|
|
|
61
61
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
62
62
|
);
|
|
63
63
|
|
|
64
|
+
-- Task dependencies (junction table)
|
|
65
|
+
|
|
66
|
+
CREATE TABLE IF NOT EXISTS task_dependencies (
|
|
67
|
+
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
68
|
+
depends_on_task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
69
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
70
|
+
PRIMARY KEY (task_id, depends_on_task_id)
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
-- Comments (threaded discussions on tasks)
|
|
74
|
+
|
|
75
|
+
CREATE TABLE IF NOT EXISTS comments (
|
|
76
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
77
|
+
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
78
|
+
author TEXT,
|
|
79
|
+
content TEXT NOT NULL,
|
|
80
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
-- Task templates
|
|
84
|
+
|
|
85
|
+
CREATE TABLE IF NOT EXISTS templates (
|
|
86
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
87
|
+
name TEXT NOT NULL UNIQUE,
|
|
88
|
+
description TEXT,
|
|
89
|
+
template_data TEXT NOT NULL DEFAULT '[]',
|
|
90
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
91
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
92
|
+
);
|
|
93
|
+
|
|
64
94
|
-- Unified notes (replaces summaries + status_updates + context)
|
|
65
95
|
|
|
66
96
|
CREATE TABLE IF NOT EXISTS notes (
|
|
@@ -122,5 +152,8 @@ CREATE INDEX IF NOT EXISTS idx_activity_action ON activity_log(action);
|
|
|
122
152
|
|
|
123
153
|
CREATE INDEX IF NOT EXISTS idx_tasks_assigned ON tasks(assigned_to);
|
|
124
154
|
CREATE INDEX IF NOT EXISTS idx_tasks_due ON tasks(due_date);
|
|
155
|
+
|
|
156
|
+
CREATE INDEX IF NOT EXISTS idx_task_deps_depends ON task_dependencies(depends_on_task_id);
|
|
157
|
+
CREATE INDEX IF NOT EXISTS idx_comments_task ON comments(task_id);
|
|
125
158
|
`;
|
|
126
159
|
//# sourceMappingURL=schema.js.map
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6JzB,CAAC"}
|
package/dist/tools/activity.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getDb } from '../db.js';
|
|
2
2
|
import { logActivity } from '../helpers/activity-logger.js';
|
|
3
|
+
import { reevaluateDownstream } from './tasks.js';
|
|
3
4
|
export const definitions = [
|
|
4
5
|
{
|
|
5
6
|
name: 'activity_log',
|
|
@@ -166,6 +167,27 @@ function handleTaskBatchUpdate(args) {
|
|
|
166
167
|
if (priority && oldRow.priority !== priority) {
|
|
167
168
|
logActivity(db, 'task', id, 'updated', 'priority', oldRow.priority, priority, `Task '${newRow.title}' priority: ${oldRow.priority} -> ${priority}`);
|
|
168
169
|
}
|
|
170
|
+
// Auto time tracking
|
|
171
|
+
if (status === 'done' && oldRow.status !== 'done' && !newRow.actual_hours) {
|
|
172
|
+
const startEntry = db.prepare(`SELECT created_at FROM activity_log
|
|
173
|
+
WHERE entity_type = 'task' AND entity_id = ? AND action = 'status_changed'
|
|
174
|
+
AND field_name = 'status' AND new_value = 'in_progress'
|
|
175
|
+
ORDER BY created_at DESC LIMIT 1`).get(id);
|
|
176
|
+
if (startEntry) {
|
|
177
|
+
const startMs = new Date(startEntry.created_at + 'Z').getTime();
|
|
178
|
+
const nowMs = Date.now();
|
|
179
|
+
const hours = Math.round(((nowMs - startMs) / 3_600_000) * 10) / 10;
|
|
180
|
+
if (hours > 0) {
|
|
181
|
+
db.prepare('UPDATE tasks SET actual_hours = ? WHERE id = ?').run(hours, id);
|
|
182
|
+
newRow.actual_hours = hours;
|
|
183
|
+
logActivity(db, 'task', id, 'updated', 'actual_hours', null, String(hours), `Task '${newRow.title}' auto-tracked: ${hours}h`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Re-evaluate downstream dependencies when task marked done
|
|
188
|
+
if (status === 'done' && oldRow.status !== 'done') {
|
|
189
|
+
reevaluateDownstream(db, id);
|
|
190
|
+
}
|
|
169
191
|
return newRow;
|
|
170
192
|
});
|
|
171
193
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/tools/activity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/tools/activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getDb } from '../db.js';
|
|
2
|
+
import { logActivity } from '../helpers/activity-logger.js';
|
|
3
|
+
export const definitions = [
|
|
4
|
+
{
|
|
5
|
+
name: 'comment_add',
|
|
6
|
+
description: 'Add a comment to a task. Comments create a chronological discussion thread — useful for leaving breadcrumbs across sessions.',
|
|
7
|
+
annotations: { title: 'Add Comment', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
task_id: { type: 'integer', description: 'Task ID to comment on' },
|
|
12
|
+
content: { type: 'string', description: 'Comment text' },
|
|
13
|
+
author: { type: 'string', description: 'Author name (optional)' },
|
|
14
|
+
},
|
|
15
|
+
required: ['task_id', 'content'],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'comment_list',
|
|
20
|
+
description: 'List all comments on a task in chronological order.',
|
|
21
|
+
annotations: { title: 'List Comments', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
task_id: { type: 'integer', description: 'Task ID' },
|
|
26
|
+
},
|
|
27
|
+
required: ['task_id'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
function handleCommentAdd(args) {
|
|
32
|
+
const db = getDb();
|
|
33
|
+
const taskId = args.task_id;
|
|
34
|
+
const content = args.content;
|
|
35
|
+
const author = args.author ?? null;
|
|
36
|
+
// Verify task exists
|
|
37
|
+
const task = db.prepare('SELECT id, title FROM tasks WHERE id = ?').get(taskId);
|
|
38
|
+
if (!task)
|
|
39
|
+
throw new Error(`Task ${taskId} not found`);
|
|
40
|
+
const comment = db
|
|
41
|
+
.prepare('INSERT INTO comments (task_id, author, content) VALUES (?, ?, ?) RETURNING *')
|
|
42
|
+
.get(taskId, author, content);
|
|
43
|
+
const row = comment;
|
|
44
|
+
logActivity(db, 'comment', row.id, 'created', null, null, null, `Comment added to task '${task.title}'${author ? ` by ${author}` : ''}`);
|
|
45
|
+
return comment;
|
|
46
|
+
}
|
|
47
|
+
function handleCommentList(args) {
|
|
48
|
+
const db = getDb();
|
|
49
|
+
const taskId = args.task_id;
|
|
50
|
+
return db
|
|
51
|
+
.prepare('SELECT * FROM comments WHERE task_id = ? ORDER BY created_at ASC')
|
|
52
|
+
.all(taskId);
|
|
53
|
+
}
|
|
54
|
+
export const handlers = {
|
|
55
|
+
comment_add: handleCommentAdd,
|
|
56
|
+
comment_list: handleCommentList,
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=comments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/tools/comments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAG5D,MAAM,CAAC,MAAM,WAAW,GAAW;IACjC;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,8HAA8H;QAChI,WAAW,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;QAC/H,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBAClE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;gBACxD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE;aAClE;YACD,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;SACjC;KACF;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,qDAAqD;QAClE,WAAW,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;QAC/H,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE;aACrD;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;CACF,CAAC;AAEF,SAAS,gBAAgB,CAAC,IAA6B;IACrD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAiB,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;IACvC,MAAM,MAAM,GAAI,IAAI,CAAC,MAAiB,IAAI,IAAI,CAAC;IAE/C,qBAAqB;IACrB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,CAAC,MAAM,CAA8C,CAAC;IAC7H,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,YAAY,CAAC,CAAC;IAEvD,MAAM,OAAO,GAAG,EAAE;SACf,OAAO,CAAC,8EAA8E,CAAC;SACvF,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAEhC,MAAM,GAAG,GAAG,OAAkC,CAAC;IAC/C,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,EAAY,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EACtE,0BAA0B,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAE3E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA6B;IACtD,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAiB,CAAC;IAEtC,OAAO,EAAE;SACN,OAAO,CAAC,kEAAkE,CAAC;SAC3E,GAAG,CAAC,MAAM,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAgC;IACnD,WAAW,EAAE,gBAAgB;IAC7B,YAAY,EAAE,iBAAiB;CAChC,CAAC"}
|
package/dist/tools/dashboard.js
CHANGED
|
@@ -96,6 +96,15 @@ function handleDashboard(args) {
|
|
|
96
96
|
CASE t.priority WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 ELSE 3 END
|
|
97
97
|
`)
|
|
98
98
|
.all(projectId);
|
|
99
|
+
// Overdue tasks
|
|
100
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
101
|
+
const overdueTasks = db
|
|
102
|
+
.prepare(`SELECT t.id, t.title, t.due_date, t.priority, e.name as epic_name
|
|
103
|
+
FROM tasks t
|
|
104
|
+
JOIN epics e ON e.id = t.epic_id
|
|
105
|
+
WHERE e.project_id = ? AND t.due_date < ? AND t.status NOT IN ('done')
|
|
106
|
+
ORDER BY t.due_date ASC`)
|
|
107
|
+
.all(projectId, today);
|
|
99
108
|
// Recent activity (last 10)
|
|
100
109
|
const recentActivity = db
|
|
101
110
|
.prepare('SELECT summary, action, entity_type, entity_id, created_at FROM activity_log ORDER BY created_at DESC LIMIT 10')
|
|
@@ -104,11 +113,43 @@ function handleDashboard(args) {
|
|
|
104
113
|
const recentNotes = db
|
|
105
114
|
.prepare('SELECT id, title, note_type, created_at FROM notes ORDER BY created_at DESC LIMIT 5')
|
|
106
115
|
.all();
|
|
116
|
+
// Generate natural language summary
|
|
117
|
+
const s = stats;
|
|
118
|
+
const p = project;
|
|
119
|
+
const epicList = epics;
|
|
120
|
+
const summaryParts = [];
|
|
121
|
+
summaryParts.push(`${p.name}: ${s.total_tasks} tasks across ${s.total_epics} epics. ${s.completion_pct}% complete.`);
|
|
122
|
+
const activeEpics = epicList.filter((e) => e.status === 'in_progress');
|
|
123
|
+
if (activeEpics.length > 0) {
|
|
124
|
+
const activeStr = activeEpics
|
|
125
|
+
.map((e) => `${e.name} (${e.done_count}/${e.task_count} done)`)
|
|
126
|
+
.join(', ');
|
|
127
|
+
summaryParts.push(`Active: ${activeStr}.`);
|
|
128
|
+
}
|
|
129
|
+
const nextEpic = epicList.find((e) => e.status === 'planned');
|
|
130
|
+
if (nextEpic) {
|
|
131
|
+
summaryParts.push(`Next up: ${nextEpic.name} (${nextEpic.task_count} tasks).`);
|
|
132
|
+
}
|
|
133
|
+
if (s.tasks_blocked > 0) {
|
|
134
|
+
summaryParts.push(`${s.tasks_blocked} blocked task(s).`);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
summaryParts.push('No blocked tasks.');
|
|
138
|
+
}
|
|
139
|
+
if (overdueTasks.length > 0) {
|
|
140
|
+
summaryParts.push(`${overdueTasks.length} overdue task(s).`);
|
|
141
|
+
}
|
|
142
|
+
if (s.tasks_in_progress > 0) {
|
|
143
|
+
summaryParts.push(`${s.tasks_in_progress} in progress.`);
|
|
144
|
+
}
|
|
145
|
+
const summary = summaryParts.join(' ');
|
|
107
146
|
return {
|
|
147
|
+
summary,
|
|
108
148
|
project,
|
|
109
149
|
stats,
|
|
110
150
|
epics,
|
|
111
151
|
blocked_tasks: blockedTasks,
|
|
152
|
+
overdue_tasks: overdueTasks,
|
|
112
153
|
recent_activity: recentActivity,
|
|
113
154
|
recent_notes: recentNotes,
|
|
114
155
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/tools/dashboard.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/tools/dashboard.ts"],"names":[],"mappings":"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"}
|