@standardbeagle/dart-query 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +427 -0
- package/TOOLS.md +2148 -0
- package/dist/api/dartClient.d.ts +123 -0
- package/dist/api/dartClient.d.ts.map +1 -0
- package/dist/api/dartClient.js +436 -0
- package/dist/api/dartClient.js.map +1 -0
- package/dist/batch/batchOperations.d.ts +14 -0
- package/dist/batch/batchOperations.d.ts.map +1 -0
- package/dist/batch/batchOperations.js +65 -0
- package/dist/batch/batchOperations.js.map +1 -0
- package/dist/cache/configCache.d.ts +20 -0
- package/dist/cache/configCache.d.ts.map +1 -0
- package/dist/cache/configCache.js +59 -0
- package/dist/cache/configCache.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1120 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/csv.d.ts +44 -0
- package/dist/parsers/csv.d.ts.map +1 -0
- package/dist/parsers/csv.js +574 -0
- package/dist/parsers/csv.js.map +1 -0
- package/dist/parsers/dartql.d.ts +104 -0
- package/dist/parsers/dartql.d.ts.map +1 -0
- package/dist/parsers/dartql.js +889 -0
- package/dist/parsers/dartql.js.map +1 -0
- package/dist/tools/add_task_comment.d.ts +3 -0
- package/dist/tools/add_task_comment.d.ts.map +1 -0
- package/dist/tools/add_task_comment.js +43 -0
- package/dist/tools/add_task_comment.js.map +1 -0
- package/dist/tools/add_time_tracking.d.ts +3 -0
- package/dist/tools/add_time_tracking.d.ts.map +1 -0
- package/dist/tools/add_time_tracking.js +52 -0
- package/dist/tools/add_time_tracking.js.map +1 -0
- package/dist/tools/attach_url.d.ts +3 -0
- package/dist/tools/attach_url.d.ts.map +1 -0
- package/dist/tools/attach_url.js +38 -0
- package/dist/tools/attach_url.js.map +1 -0
- package/dist/tools/batch_delete_tasks.d.ts +3 -0
- package/dist/tools/batch_delete_tasks.d.ts.map +1 -0
- package/dist/tools/batch_delete_tasks.js +125 -0
- package/dist/tools/batch_delete_tasks.js.map +1 -0
- package/dist/tools/batch_update_tasks.d.ts +3 -0
- package/dist/tools/batch_update_tasks.d.ts.map +1 -0
- package/dist/tools/batch_update_tasks.js +327 -0
- package/dist/tools/batch_update_tasks.js.map +1 -0
- package/dist/tools/create_doc.d.ts +3 -0
- package/dist/tools/create_doc.d.ts.map +1 -0
- package/dist/tools/create_doc.js +65 -0
- package/dist/tools/create_doc.js.map +1 -0
- package/dist/tools/create_task.d.ts +3 -0
- package/dist/tools/create_task.d.ts.map +1 -0
- package/dist/tools/create_task.js +143 -0
- package/dist/tools/create_task.js.map +1 -0
- package/dist/tools/delete_doc.d.ts +3 -0
- package/dist/tools/delete_doc.d.ts.map +1 -0
- package/dist/tools/delete_doc.js +35 -0
- package/dist/tools/delete_doc.js.map +1 -0
- package/dist/tools/delete_task.d.ts +3 -0
- package/dist/tools/delete_task.d.ts.map +1 -0
- package/dist/tools/delete_task.js +35 -0
- package/dist/tools/delete_task.js.map +1 -0
- package/dist/tools/get_batch_status.d.ts +3 -0
- package/dist/tools/get_batch_status.d.ts.map +1 -0
- package/dist/tools/get_batch_status.js +24 -0
- package/dist/tools/get_batch_status.js.map +1 -0
- package/dist/tools/get_config.d.ts +3 -0
- package/dist/tools/get_config.d.ts.map +1 -0
- package/dist/tools/get_config.js +74 -0
- package/dist/tools/get_config.js.map +1 -0
- package/dist/tools/get_dartboard.d.ts +3 -0
- package/dist/tools/get_dartboard.d.ts.map +1 -0
- package/dist/tools/get_dartboard.js +43 -0
- package/dist/tools/get_dartboard.js.map +1 -0
- package/dist/tools/get_doc.d.ts +3 -0
- package/dist/tools/get_doc.d.ts.map +1 -0
- package/dist/tools/get_doc.js +34 -0
- package/dist/tools/get_doc.js.map +1 -0
- package/dist/tools/get_folder.d.ts +3 -0
- package/dist/tools/get_folder.d.ts.map +1 -0
- package/dist/tools/get_folder.js +45 -0
- package/dist/tools/get_folder.js.map +1 -0
- package/dist/tools/get_task.d.ts +3 -0
- package/dist/tools/get_task.d.ts.map +1 -0
- package/dist/tools/get_task.js +109 -0
- package/dist/tools/get_task.js.map +1 -0
- package/dist/tools/import_tasks_csv.d.ts +3 -0
- package/dist/tools/import_tasks_csv.d.ts.map +1 -0
- package/dist/tools/import_tasks_csv.js +218 -0
- package/dist/tools/import_tasks_csv.js.map +1 -0
- package/dist/tools/info.d.ts +3 -0
- package/dist/tools/info.d.ts.map +1 -0
- package/dist/tools/info.js +474 -0
- package/dist/tools/info.js.map +1 -0
- package/dist/tools/list_comments.d.ts +3 -0
- package/dist/tools/list_comments.d.ts.map +1 -0
- package/dist/tools/list_comments.js +46 -0
- package/dist/tools/list_comments.js.map +1 -0
- package/dist/tools/list_docs.d.ts +3 -0
- package/dist/tools/list_docs.d.ts.map +1 -0
- package/dist/tools/list_docs.js +101 -0
- package/dist/tools/list_docs.js.map +1 -0
- package/dist/tools/list_tasks.d.ts +3 -0
- package/dist/tools/list_tasks.d.ts.map +1 -0
- package/dist/tools/list_tasks.js +325 -0
- package/dist/tools/list_tasks.js.map +1 -0
- package/dist/tools/move_task.d.ts +3 -0
- package/dist/tools/move_task.d.ts.map +1 -0
- package/dist/tools/move_task.js +44 -0
- package/dist/tools/move_task.js.map +1 -0
- package/dist/tools/search_tasks.d.ts +3 -0
- package/dist/tools/search_tasks.d.ts.map +1 -0
- package/dist/tools/search_tasks.js +227 -0
- package/dist/tools/search_tasks.js.map +1 -0
- package/dist/tools/update_doc.d.ts +3 -0
- package/dist/tools/update_doc.d.ts.map +1 -0
- package/dist/tools/update_doc.js +102 -0
- package/dist/tools/update_doc.js.map +1 -0
- package/dist/tools/update_task.d.ts +3 -0
- package/dist/tools/update_task.d.ts.map +1 -0
- package/dist/tools/update_task.js +241 -0
- package/dist/tools/update_task.js.map +1 -0
- package/dist/types/index.d.ts +529 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +65 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +72 -0
package/TOOLS.md
ADDED
|
@@ -0,0 +1,2148 @@
|
|
|
1
|
+
# dart-query Tools Documentation
|
|
2
|
+
|
|
3
|
+
**Complete reference for all MCP tools, parameters, workflows, and use cases.**
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Tool Groups Overview](#tool-groups-overview)
|
|
8
|
+
- [Discovery Tools](#discovery-tools)
|
|
9
|
+
- [Configuration Tools](#configuration-tools)
|
|
10
|
+
- [Task CRUD Operations](#task-crud-operations)
|
|
11
|
+
- [Task Query Operations](#task-query-operations)
|
|
12
|
+
- [Batch Operations](#batch-operations)
|
|
13
|
+
- [CSV Import](#csv-import)
|
|
14
|
+
- [Document Management](#document-management)
|
|
15
|
+
- [DartQL Reference](#dartql-reference)
|
|
16
|
+
- [Error Handling](#error-handling)
|
|
17
|
+
- [Performance Optimization](#performance-optimization)
|
|
18
|
+
- [Common Workflows](#common-workflows)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Tool Groups Overview
|
|
23
|
+
|
|
24
|
+
dart-query organizes 18 tools into 7 functional groups:
|
|
25
|
+
|
|
26
|
+
| Group | Tools | Purpose |
|
|
27
|
+
|-------|-------|---------|
|
|
28
|
+
| **discovery** | `info` | Progressive capability discovery |
|
|
29
|
+
| **config** | `get_config` | Workspace configuration |
|
|
30
|
+
| **task-crud** | 5 tools | Single task operations (create, get, update, delete, comment) |
|
|
31
|
+
| **task-query** | 2 tools | Search and filter tasks (list, search) |
|
|
32
|
+
| **task-batch** | 3 tools | Bulk operations (batch update, batch delete, status) |
|
|
33
|
+
| **import** | 1 tool | CSV bulk import |
|
|
34
|
+
| **doc-crud** | 5 tools | Document management (create, get, update, delete, list) |
|
|
35
|
+
|
|
36
|
+
**Token Budget Summary:**
|
|
37
|
+
- Discovery: ~150 tokens (overview)
|
|
38
|
+
- Config: ~400 tokens
|
|
39
|
+
- CRUD: ~200-300 tokens per operation
|
|
40
|
+
- Batch: ~400 tokens (summary, not full data)
|
|
41
|
+
- Import: ~500 tokens
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Discovery Tools
|
|
46
|
+
|
|
47
|
+
### `info` - Progressive Capability Discovery
|
|
48
|
+
|
|
49
|
+
**Purpose:** Explore dart-query capabilities without loading all schemas. Start here.
|
|
50
|
+
|
|
51
|
+
**Input Schema:**
|
|
52
|
+
```typescript
|
|
53
|
+
{
|
|
54
|
+
level?: 'overview' | 'group' | 'tool' // default: 'overview'
|
|
55
|
+
target?: string // group name or tool name
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Output Schema:**
|
|
60
|
+
```typescript
|
|
61
|
+
{
|
|
62
|
+
level: string // echoed back
|
|
63
|
+
content: string // formatted documentation
|
|
64
|
+
next_steps: string[] // suggested follow-up queries
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Examples:**
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Get overview of all tool groups
|
|
72
|
+
info()
|
|
73
|
+
// → Shows sparse table with 7 tool groups
|
|
74
|
+
|
|
75
|
+
// Explore batch operations
|
|
76
|
+
info({ level: 'group', target: 'task-batch' })
|
|
77
|
+
// → Shows 3 batch operation tools with descriptions
|
|
78
|
+
|
|
79
|
+
// Get full documentation for a specific tool
|
|
80
|
+
info({ level: 'tool', target: 'batch_update_tasks' })
|
|
81
|
+
// → Shows complete schema, examples, DartQL syntax guide
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Token Budget:** ~150 tokens (overview), ~200 tokens (group), ~500 tokens (tool)
|
|
85
|
+
|
|
86
|
+
**Performance:** Instant (no API calls)
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Configuration Tools
|
|
91
|
+
|
|
92
|
+
### `get_config` - Workspace Configuration
|
|
93
|
+
|
|
94
|
+
**Purpose:** Retrieve workspace configuration including dartboards, assignees, statuses, tags, priorities, sizes, and folders. **Always call this before creating tasks or importing CSV.**
|
|
95
|
+
|
|
96
|
+
**Input Schema:**
|
|
97
|
+
```typescript
|
|
98
|
+
{
|
|
99
|
+
cache_bust?: boolean // default: false, force refresh cache
|
|
100
|
+
include?: string[] // limit to specific sections
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Valid `include` values:**
|
|
105
|
+
- `"assignees"` - User list with emails
|
|
106
|
+
- `"dartboards"` - Board names (Personal/test, Engineering/backend, etc.)
|
|
107
|
+
- `"statuses"` - Status names (To Do, Doing, Done, etc.)
|
|
108
|
+
- `"tags"` - Tag names
|
|
109
|
+
- `"priorities"` - Priority values ("critical", "high", "medium", "low")
|
|
110
|
+
- `"sizes"` - Size values ("xs", "small", "medium", "large", "xl")
|
|
111
|
+
- `"folders"` - Document folder names
|
|
112
|
+
|
|
113
|
+
**Output Schema:**
|
|
114
|
+
```typescript
|
|
115
|
+
{
|
|
116
|
+
assignees: Array<{
|
|
117
|
+
dart_id: string
|
|
118
|
+
name: string
|
|
119
|
+
email: string
|
|
120
|
+
role?: string
|
|
121
|
+
}>
|
|
122
|
+
|
|
123
|
+
dartboards: string[] // e.g., ["Personal/test", "Engineering/backend"]
|
|
124
|
+
statuses: string[] // e.g., ["To Do", "Doing", "Done"]
|
|
125
|
+
tags: string[] // e.g., ["bug", "feature", "urgent"]
|
|
126
|
+
priorities: string[] // e.g., ["critical", "high", "medium", "low"]
|
|
127
|
+
sizes: string[] // e.g., ["xs", "small", "medium", "large", "xl"]
|
|
128
|
+
folders: string[] // doc folder names
|
|
129
|
+
|
|
130
|
+
cached_at: string // ISO8601 timestamp
|
|
131
|
+
cache_ttl_seconds: number // 300 (5 minutes)
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Examples:**
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// Get full workspace config (cached for 5 minutes)
|
|
139
|
+
get_config()
|
|
140
|
+
|
|
141
|
+
// Get only dartboards and assignees (token-efficient)
|
|
142
|
+
get_config({ include: ["dartboards", "assignees"] })
|
|
143
|
+
|
|
144
|
+
// Force refresh cached config
|
|
145
|
+
get_config({ cache_bust: true })
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Use Cases:**
|
|
149
|
+
- Validate dartboard names before creating tasks
|
|
150
|
+
- Get assignee emails for CSV import
|
|
151
|
+
- Check available statuses, tags, priorities, sizes
|
|
152
|
+
- Discover valid reference values for batch updates
|
|
153
|
+
|
|
154
|
+
**Token Budget:** ~400 tokens for full config
|
|
155
|
+
|
|
156
|
+
**Performance:** Fast (cached) / Medium (API call on cache miss)
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Task CRUD Operations
|
|
161
|
+
|
|
162
|
+
### `create_task` - Create Single Task
|
|
163
|
+
|
|
164
|
+
**Purpose:** Create a new task with all metadata.
|
|
165
|
+
|
|
166
|
+
**Input Schema:**
|
|
167
|
+
```typescript
|
|
168
|
+
{
|
|
169
|
+
title: string // REQUIRED, max 500 chars
|
|
170
|
+
dartboard: string // REQUIRED, dartboard name
|
|
171
|
+
description?: string // optional description
|
|
172
|
+
status?: string // e.g., "To Do", "Doing"
|
|
173
|
+
priority?: string // "critical", "high", "medium", "low"
|
|
174
|
+
size?: string // "xs", "small", "medium", "large", "xl"
|
|
175
|
+
assignees?: string[] // email addresses or names
|
|
176
|
+
tags?: string[] // tag names
|
|
177
|
+
due_at?: string // ISO8601 date (e.g., "2026-02-01T00:00:00Z")
|
|
178
|
+
start_at?: string // ISO8601 date
|
|
179
|
+
parent_task?: string // parent task dart_id
|
|
180
|
+
|
|
181
|
+
// Relationship fields (arrays of dart_id strings)
|
|
182
|
+
subtask_ids?: string[] // IDs of subtask (child) tasks
|
|
183
|
+
blocker_ids?: string[] // IDs of tasks that block this task
|
|
184
|
+
blocking_ids?: string[] // IDs of tasks blocked by this task
|
|
185
|
+
duplicate_ids?: string[] // IDs of duplicate tasks
|
|
186
|
+
related_ids?: string[] // IDs of related tasks
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Output Schema:**
|
|
191
|
+
```typescript
|
|
192
|
+
{
|
|
193
|
+
dart_id: string // unique task ID
|
|
194
|
+
title: string
|
|
195
|
+
description?: string
|
|
196
|
+
status?: string
|
|
197
|
+
priority?: string
|
|
198
|
+
size?: string
|
|
199
|
+
assignees?: string[]
|
|
200
|
+
tags?: string[]
|
|
201
|
+
dartboard: string
|
|
202
|
+
due_at?: string
|
|
203
|
+
start_at?: string
|
|
204
|
+
completed_at?: string
|
|
205
|
+
created_at: string
|
|
206
|
+
updated_at: string
|
|
207
|
+
parent_task?: string
|
|
208
|
+
url?: string // web UI link
|
|
209
|
+
|
|
210
|
+
// Relationship fields
|
|
211
|
+
subtask_ids?: string[] // IDs of subtask (child) tasks
|
|
212
|
+
blocker_ids?: string[] // IDs of tasks that block this task
|
|
213
|
+
blocking_ids?: string[] // IDs of tasks blocked by this task
|
|
214
|
+
duplicate_ids?: string[] // IDs of duplicate tasks
|
|
215
|
+
related_ids?: string[] // IDs of related tasks
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Examples:**
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Minimal task
|
|
223
|
+
create_task({
|
|
224
|
+
title: "Fix authentication bug",
|
|
225
|
+
dartboard: "Engineering/backend"
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
// Full task with all metadata
|
|
229
|
+
create_task({
|
|
230
|
+
title: "Implement OAuth2 login",
|
|
231
|
+
dartboard: "Engineering/backend",
|
|
232
|
+
description: "Add Google and GitHub OAuth providers",
|
|
233
|
+
status: "To Do",
|
|
234
|
+
priority: "high",
|
|
235
|
+
size: "large",
|
|
236
|
+
assignees: ["engineer@company.com"],
|
|
237
|
+
tags: ["feature", "auth"],
|
|
238
|
+
due_at: "2026-02-15T00:00:00Z"
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
// Task with relationships - creating a task that is blocked by another
|
|
242
|
+
create_task({
|
|
243
|
+
title: "Deploy OAuth2 to production",
|
|
244
|
+
dartboard: "Engineering/backend",
|
|
245
|
+
priority: "high",
|
|
246
|
+
blocker_ids: ["duid_oauth_impl"] // blocked by the OAuth implementation task
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
// Task with multiple relationships
|
|
250
|
+
create_task({
|
|
251
|
+
title: "Update user documentation",
|
|
252
|
+
dartboard: "Documentation",
|
|
253
|
+
related_ids: ["duid_oauth_impl", "duid_api_docs"],
|
|
254
|
+
blocking_ids: ["duid_release_v2"] // this task blocks the v2 release
|
|
255
|
+
})
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Errors:**
|
|
259
|
+
- `ValidationError`: Title empty, dartboard not found, invalid priority/size
|
|
260
|
+
- `DartAPIError`: Network errors, authentication failures
|
|
261
|
+
|
|
262
|
+
**Token Budget:** ~300 tokens
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### `get_task` - Retrieve Single Task
|
|
267
|
+
|
|
268
|
+
**Purpose:** Get full details of an existing task by its `dart_id`.
|
|
269
|
+
|
|
270
|
+
**Input Schema:**
|
|
271
|
+
```typescript
|
|
272
|
+
{
|
|
273
|
+
dart_id: string // REQUIRED
|
|
274
|
+
detail_level?: 'minimal' | 'standard' | 'full' // default: 'standard'
|
|
275
|
+
include_relationships?: boolean // default: true, include relationship data
|
|
276
|
+
expand_relationships?: boolean // default: false, include titles of related tasks
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Output Schema:**
|
|
281
|
+
```typescript
|
|
282
|
+
{
|
|
283
|
+
// Core task fields (same as create_task output)
|
|
284
|
+
dart_id: string
|
|
285
|
+
title: string
|
|
286
|
+
description?: string
|
|
287
|
+
status?: string
|
|
288
|
+
priority?: string
|
|
289
|
+
size?: string
|
|
290
|
+
assignees?: string[]
|
|
291
|
+
tags?: string[]
|
|
292
|
+
dartboard: string
|
|
293
|
+
due_at?: string
|
|
294
|
+
start_at?: string
|
|
295
|
+
completed_at?: string
|
|
296
|
+
created_at: string
|
|
297
|
+
updated_at: string
|
|
298
|
+
parent_task?: string
|
|
299
|
+
url?: string
|
|
300
|
+
|
|
301
|
+
// Relationship IDs (when include_relationships=true)
|
|
302
|
+
subtask_ids?: string[]
|
|
303
|
+
blocker_ids?: string[]
|
|
304
|
+
blocking_ids?: string[]
|
|
305
|
+
duplicate_ids?: string[]
|
|
306
|
+
related_ids?: string[]
|
|
307
|
+
|
|
308
|
+
// Relationship counts (always included when include_relationships=true)
|
|
309
|
+
relationship_counts?: {
|
|
310
|
+
subtasks: number
|
|
311
|
+
blockers: number
|
|
312
|
+
blocking: number
|
|
313
|
+
duplicates: number
|
|
314
|
+
related: number
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Expanded relationships (when expand_relationships=true)
|
|
318
|
+
expanded_relationships?: {
|
|
319
|
+
subtasks?: Array<{ dart_id: string, title: string }>
|
|
320
|
+
blockers?: Array<{ dart_id: string, title: string }>
|
|
321
|
+
blocking?: Array<{ dart_id: string, title: string }>
|
|
322
|
+
duplicates?: Array<{ dart_id: string, title: string }>
|
|
323
|
+
related?: Array<{ dart_id: string, title: string }>
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Examples:**
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// Get full task details with relationships
|
|
332
|
+
get_task({ dart_id: "duid_task123" })
|
|
333
|
+
// Returns:
|
|
334
|
+
// {
|
|
335
|
+
// dart_id: "duid_task123",
|
|
336
|
+
// title: "Implement OAuth2",
|
|
337
|
+
// blocker_ids: ["duid_design_review"],
|
|
338
|
+
// blocking_ids: ["duid_deploy_prod"],
|
|
339
|
+
// relationship_counts: { subtasks: 0, blockers: 1, blocking: 1, duplicates: 0, related: 0 }
|
|
340
|
+
// }
|
|
341
|
+
|
|
342
|
+
// Get minimal details (fewer tokens)
|
|
343
|
+
get_task({ dart_id: "duid_task123", detail_level: "minimal" })
|
|
344
|
+
|
|
345
|
+
// Exclude relationship data for smaller response
|
|
346
|
+
get_task({ dart_id: "duid_task123", include_relationships: false })
|
|
347
|
+
|
|
348
|
+
// Get expanded relationships with task titles (useful for display)
|
|
349
|
+
get_task({ dart_id: "duid_task123", expand_relationships: true })
|
|
350
|
+
// Returns:
|
|
351
|
+
// {
|
|
352
|
+
// dart_id: "duid_task123",
|
|
353
|
+
// title: "Implement OAuth2",
|
|
354
|
+
// blocker_ids: ["duid_design_review"],
|
|
355
|
+
// expanded_relationships: {
|
|
356
|
+
// blockers: [{ dart_id: "duid_design_review", title: "Design review meeting" }],
|
|
357
|
+
// blocking: [{ dart_id: "duid_deploy_prod", title: "Deploy to production" }]
|
|
358
|
+
// }
|
|
359
|
+
// }
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Token Budget:** ~200 tokens (minimal), ~300 tokens (standard), ~400+ tokens (with expanded relationships)
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
### `update_task` - Update Single Task
|
|
367
|
+
|
|
368
|
+
**Purpose:** Update one or more fields of an existing task.
|
|
369
|
+
|
|
370
|
+
**Input Schema:**
|
|
371
|
+
```typescript
|
|
372
|
+
{
|
|
373
|
+
dart_id: string // REQUIRED
|
|
374
|
+
updates: { // REQUIRED, at least one field
|
|
375
|
+
title?: string
|
|
376
|
+
description?: string
|
|
377
|
+
status?: string
|
|
378
|
+
priority?: string
|
|
379
|
+
size?: string
|
|
380
|
+
assignees?: string[]
|
|
381
|
+
tags?: string[]
|
|
382
|
+
dartboard?: string
|
|
383
|
+
due_at?: string
|
|
384
|
+
start_at?: string
|
|
385
|
+
parent_task?: string
|
|
386
|
+
|
|
387
|
+
// Relationship fields (arrays of dart_id strings)
|
|
388
|
+
subtask_ids?: string[] // IDs of subtask (child) tasks
|
|
389
|
+
blocker_ids?: string[] // IDs of tasks that block this task
|
|
390
|
+
blocking_ids?: string[] // IDs of tasks blocked by this task
|
|
391
|
+
duplicate_ids?: string[] // IDs of duplicate tasks
|
|
392
|
+
related_ids?: string[] // IDs of related tasks
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**Relationship Update Semantics:**
|
|
398
|
+
- **Full replacement**: Providing a relationship array replaces ALL existing values
|
|
399
|
+
- **Empty array `[]`**: Clears all relationships of that type
|
|
400
|
+
- **Omitting field**: Leaves existing relationships unchanged
|
|
401
|
+
|
|
402
|
+
**Output Schema:** Same as `get_task` (updated task)
|
|
403
|
+
|
|
404
|
+
**Examples:**
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Update status only
|
|
408
|
+
update_task({
|
|
409
|
+
dart_id: "duid_task123",
|
|
410
|
+
updates: { status: "Doing" }
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
// Update multiple fields
|
|
414
|
+
update_task({
|
|
415
|
+
dart_id: "duid_task123",
|
|
416
|
+
updates: {
|
|
417
|
+
status: "Doing",
|
|
418
|
+
priority: "critical",
|
|
419
|
+
assignees: ["john@company.com"]
|
|
420
|
+
}
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
// Add blockers to a task (replaces any existing blockers)
|
|
424
|
+
update_task({
|
|
425
|
+
dart_id: "duid_deploy_task",
|
|
426
|
+
updates: {
|
|
427
|
+
blocker_ids: ["duid_testing", "duid_code_review"]
|
|
428
|
+
}
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
// Clear all blockers (task is no longer blocked)
|
|
432
|
+
update_task({
|
|
433
|
+
dart_id: "duid_deploy_task",
|
|
434
|
+
updates: {
|
|
435
|
+
blocker_ids: [] // empty array clears all blockers
|
|
436
|
+
}
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
// Link related tasks
|
|
440
|
+
update_task({
|
|
441
|
+
dart_id: "duid_task123",
|
|
442
|
+
updates: {
|
|
443
|
+
related_ids: ["duid_task456", "duid_task789"]
|
|
444
|
+
}
|
|
445
|
+
})
|
|
446
|
+
|
|
447
|
+
// Mark tasks as duplicates
|
|
448
|
+
update_task({
|
|
449
|
+
dart_id: "duid_original",
|
|
450
|
+
updates: {
|
|
451
|
+
duplicate_ids: ["duid_dup1", "duid_dup2"]
|
|
452
|
+
}
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
// Add subtasks to a parent task
|
|
456
|
+
update_task({
|
|
457
|
+
dart_id: "duid_parent_feature",
|
|
458
|
+
updates: {
|
|
459
|
+
subtask_ids: ["duid_subtask1", "duid_subtask2", "duid_subtask3"]
|
|
460
|
+
}
|
|
461
|
+
})
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Important:** To add a single relationship without losing existing ones, first retrieve the current task with `get_task`, then include all existing IDs plus the new one in the update.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
### `delete_task` - Move Task to Trash
|
|
469
|
+
|
|
470
|
+
**Purpose:** Move a task to trash (recoverable from Dart web UI).
|
|
471
|
+
|
|
472
|
+
**Input Schema:**
|
|
473
|
+
```typescript
|
|
474
|
+
{
|
|
475
|
+
dart_id: string // REQUIRED
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
**Output Schema:**
|
|
480
|
+
```typescript
|
|
481
|
+
{
|
|
482
|
+
success: boolean
|
|
483
|
+
dart_id: string
|
|
484
|
+
message: string
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Examples:**
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
delete_task({ dart_id: "duid_task123" })
|
|
492
|
+
// → Task moved to trash, recoverable from web UI
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Note:** Tasks are NOT permanently deleted - they move to trash and can be restored via Dart web UI.
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
### `add_task_comment` - Add Comment to Task
|
|
500
|
+
|
|
501
|
+
**Purpose:** Add a text comment to an existing task.
|
|
502
|
+
|
|
503
|
+
**Input Schema:**
|
|
504
|
+
```typescript
|
|
505
|
+
{
|
|
506
|
+
dart_id: string // REQUIRED
|
|
507
|
+
comment: string // REQUIRED, comment text
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Output Schema:**
|
|
512
|
+
```typescript
|
|
513
|
+
{
|
|
514
|
+
success: boolean
|
|
515
|
+
comment_id: string
|
|
516
|
+
dart_id: string
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Examples:**
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
add_task_comment({
|
|
524
|
+
dart_id: "duid_task123",
|
|
525
|
+
comment: "Reviewed by security team - approved for deployment"
|
|
526
|
+
})
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Task Query Operations
|
|
532
|
+
|
|
533
|
+
### `list_tasks` - Filter and List Tasks
|
|
534
|
+
|
|
535
|
+
**Purpose:** List tasks with optional filtering by assignee, status, dartboard, priority, tags, due dates, and relationships.
|
|
536
|
+
|
|
537
|
+
**Input Schema:**
|
|
538
|
+
```typescript
|
|
539
|
+
{
|
|
540
|
+
assignee?: string // email or name
|
|
541
|
+
status?: string // status name
|
|
542
|
+
dartboard?: string // dartboard name
|
|
543
|
+
priority?: string // "critical", "high", "medium", "low"
|
|
544
|
+
tags?: string[] // array of tag names
|
|
545
|
+
due_before?: string // ISO8601 date
|
|
546
|
+
due_after?: string // ISO8601 date
|
|
547
|
+
limit?: number // max results, default 100
|
|
548
|
+
offset?: number // pagination offset, default 0
|
|
549
|
+
detail_level?: 'minimal' | 'standard' | 'full' // default: 'standard'
|
|
550
|
+
|
|
551
|
+
// Relationship filters
|
|
552
|
+
has_parent?: boolean // filter tasks that have/don't have a parent
|
|
553
|
+
has_subtasks?: boolean // filter tasks that have/don't have subtasks
|
|
554
|
+
has_blockers?: boolean // filter tasks that are/aren't blocked
|
|
555
|
+
is_blocking?: boolean // filter tasks that are/aren't blocking others
|
|
556
|
+
blocked_by?: string // filter tasks blocked by specific dart_id
|
|
557
|
+
blocking?: string // filter tasks blocking specific dart_id
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Output Schema:**
|
|
562
|
+
```typescript
|
|
563
|
+
{
|
|
564
|
+
tasks: DartTask[] // array of task objects (includes relationship fields)
|
|
565
|
+
total: number // total matching tasks
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Examples:**
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
// List all tasks (max 100)
|
|
573
|
+
list_tasks()
|
|
574
|
+
|
|
575
|
+
// List high-priority tasks in Engineering dartboard
|
|
576
|
+
list_tasks({
|
|
577
|
+
dartboard: "Engineering/backend",
|
|
578
|
+
priority: "high"
|
|
579
|
+
})
|
|
580
|
+
|
|
581
|
+
// List overdue tasks
|
|
582
|
+
list_tasks({
|
|
583
|
+
due_before: "2026-01-18T00:00:00Z"
|
|
584
|
+
})
|
|
585
|
+
|
|
586
|
+
// List tasks by assignee with minimal details
|
|
587
|
+
list_tasks({
|
|
588
|
+
assignee: "john@company.com",
|
|
589
|
+
detail_level: "minimal"
|
|
590
|
+
})
|
|
591
|
+
|
|
592
|
+
// Pagination (get next 100 tasks)
|
|
593
|
+
list_tasks({ limit: 100, offset: 100 })
|
|
594
|
+
|
|
595
|
+
// List all blocked tasks (tasks that have blockers)
|
|
596
|
+
list_tasks({
|
|
597
|
+
has_blockers: true
|
|
598
|
+
})
|
|
599
|
+
|
|
600
|
+
// List all tasks that are blocking other tasks
|
|
601
|
+
list_tasks({
|
|
602
|
+
is_blocking: true
|
|
603
|
+
})
|
|
604
|
+
|
|
605
|
+
// List parent tasks only (tasks that have subtasks)
|
|
606
|
+
list_tasks({
|
|
607
|
+
has_subtasks: true
|
|
608
|
+
})
|
|
609
|
+
|
|
610
|
+
// List leaf tasks only (tasks without subtasks)
|
|
611
|
+
list_tasks({
|
|
612
|
+
has_subtasks: false
|
|
613
|
+
})
|
|
614
|
+
|
|
615
|
+
// List tasks blocked by a specific task
|
|
616
|
+
list_tasks({
|
|
617
|
+
blocked_by: "duid_release_blocker"
|
|
618
|
+
})
|
|
619
|
+
|
|
620
|
+
// List tasks that a specific task is blocking
|
|
621
|
+
list_tasks({
|
|
622
|
+
blocking: "duid_deployment_task"
|
|
623
|
+
})
|
|
624
|
+
|
|
625
|
+
// Combine relationship filters with other filters
|
|
626
|
+
list_tasks({
|
|
627
|
+
dartboard: "Engineering/backend",
|
|
628
|
+
has_blockers: true,
|
|
629
|
+
priority: "high"
|
|
630
|
+
})
|
|
631
|
+
// Returns high-priority blocked tasks in the Engineering dartboard
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**Performance Note:** Relationship filters require client-side filtering and may be slower on large datasets. Consider using DartQL queries with `batch_update_tasks` for complex relationship queries.
|
|
635
|
+
|
|
636
|
+
**Token Budget:** Variable based on result count (~200 tokens per 10 tasks)
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
### `search_tasks` - Full-Text Search
|
|
641
|
+
|
|
642
|
+
**Purpose:** Search tasks by keywords with relevance ranking.
|
|
643
|
+
|
|
644
|
+
**Input Schema:**
|
|
645
|
+
```typescript
|
|
646
|
+
{
|
|
647
|
+
query: string // REQUIRED, search keywords
|
|
648
|
+
dartboard?: string // filter to specific dartboard
|
|
649
|
+
limit?: number // max results, default 20
|
|
650
|
+
offset?: number // pagination offset, default 0
|
|
651
|
+
}
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
**Output Schema:**
|
|
655
|
+
```typescript
|
|
656
|
+
{
|
|
657
|
+
results: DartTask[] // ranked by relevance
|
|
658
|
+
total: number
|
|
659
|
+
query: string // echoed back
|
|
660
|
+
}
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**Examples:**
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
// Multi-term search
|
|
667
|
+
search_tasks({ query: "authentication security oauth" })
|
|
668
|
+
|
|
669
|
+
// Phrase search with dartboard filter
|
|
670
|
+
search_tasks({
|
|
671
|
+
query: "error handling database",
|
|
672
|
+
dartboard: "Engineering/backend"
|
|
673
|
+
})
|
|
674
|
+
|
|
675
|
+
// Pagination
|
|
676
|
+
search_tasks({
|
|
677
|
+
query: "bug fix",
|
|
678
|
+
limit: 20,
|
|
679
|
+
offset: 20
|
|
680
|
+
})
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
**How Search Works:**
|
|
684
|
+
- Searches task titles and descriptions
|
|
685
|
+
- Ranks by relevance score (TF-IDF)
|
|
686
|
+
- Returns matches ordered by score (highest first)
|
|
687
|
+
|
|
688
|
+
**Token Budget:** Variable (~300 tokens per 10 results)
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
## Batch Operations
|
|
693
|
+
|
|
694
|
+
**CRITICAL SAFETY RULES:**
|
|
695
|
+
1. **ALWAYS use `dry_run: true` first** to preview matching tasks
|
|
696
|
+
2. **Review preview before executing** - verify selector is correct
|
|
697
|
+
3. **Test with small dataset first** (< 10 tasks) before large batches
|
|
698
|
+
4. **Have rollback plan** - tasks go to trash, recoverable via web UI
|
|
699
|
+
|
|
700
|
+
### `batch_update_tasks` - Bulk Update with DartQL
|
|
701
|
+
|
|
702
|
+
**Purpose:** Update multiple tasks matching a DartQL selector expression (SQL-like WHERE syntax).
|
|
703
|
+
|
|
704
|
+
**Input Schema:**
|
|
705
|
+
```typescript
|
|
706
|
+
{
|
|
707
|
+
selector: string // REQUIRED, DartQL WHERE clause
|
|
708
|
+
updates: { // REQUIRED, fields to update
|
|
709
|
+
title?: string
|
|
710
|
+
description?: string
|
|
711
|
+
status?: string
|
|
712
|
+
priority?: string
|
|
713
|
+
size?: string
|
|
714
|
+
assignees?: string[]
|
|
715
|
+
tags?: string[]
|
|
716
|
+
dartboard?: string
|
|
717
|
+
due_at?: string
|
|
718
|
+
start_at?: string
|
|
719
|
+
|
|
720
|
+
// Relationship fields (arrays of dart_id strings)
|
|
721
|
+
subtask_ids?: string[] // IDs of subtask (child) tasks
|
|
722
|
+
blocker_ids?: string[] // IDs of tasks that block this task
|
|
723
|
+
blocking_ids?: string[] // IDs of tasks blocked by this task
|
|
724
|
+
duplicate_ids?: string[] // IDs of duplicate tasks
|
|
725
|
+
related_ids?: string[] // IDs of related tasks
|
|
726
|
+
}
|
|
727
|
+
dry_run?: boolean // default: false (RECOMMENDED: use true first!)
|
|
728
|
+
concurrency?: number // default: 5, range 1-20
|
|
729
|
+
}
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
**Relationship Update Semantics:**
|
|
733
|
+
- **Full replacement**: Providing a relationship array replaces ALL existing values for ALL matched tasks
|
|
734
|
+
- **Empty array `[]`**: Clears all relationships of that type on ALL matched tasks
|
|
735
|
+
- **Omitting field**: Leaves existing relationships unchanged
|
|
736
|
+
|
|
737
|
+
**Output Schema:**
|
|
738
|
+
```typescript
|
|
739
|
+
{
|
|
740
|
+
batch_operation_id: string
|
|
741
|
+
selector_matched: number // total tasks matching selector
|
|
742
|
+
dry_run: boolean
|
|
743
|
+
|
|
744
|
+
// If dry_run=true:
|
|
745
|
+
preview_tasks?: Array<{
|
|
746
|
+
dart_id: string
|
|
747
|
+
title: string
|
|
748
|
+
current_values: object // current values of fields being updated
|
|
749
|
+
new_values: object // values that will be applied (for relationships)
|
|
750
|
+
}> // max 10 tasks shown
|
|
751
|
+
|
|
752
|
+
// If dry_run=false:
|
|
753
|
+
successful_updates: number
|
|
754
|
+
failed_updates: number
|
|
755
|
+
successful_dart_ids: string[]
|
|
756
|
+
failed_items: Array<{
|
|
757
|
+
dart_id: string
|
|
758
|
+
error: string
|
|
759
|
+
reason: string
|
|
760
|
+
}>
|
|
761
|
+
execution_time_ms: number
|
|
762
|
+
}
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
**Examples:**
|
|
766
|
+
|
|
767
|
+
```typescript
|
|
768
|
+
// Step 1: ALWAYS preview first (dry_run=true by default)
|
|
769
|
+
batch_update_tasks({
|
|
770
|
+
selector: "dartboard = 'Engineering/backend' AND priority = 'high'",
|
|
771
|
+
updates: { status: "Doing" },
|
|
772
|
+
dry_run: true
|
|
773
|
+
})
|
|
774
|
+
// → Returns preview of up to 10 matching tasks
|
|
775
|
+
|
|
776
|
+
// Step 2: Review preview, verify selector matches ONLY intended tasks
|
|
777
|
+
|
|
778
|
+
// Step 3: Execute update (dry_run=false)
|
|
779
|
+
batch_update_tasks({
|
|
780
|
+
selector: "dartboard = 'Engineering/backend' AND priority = 'high'",
|
|
781
|
+
updates: { status: "Doing" },
|
|
782
|
+
dry_run: false
|
|
783
|
+
})
|
|
784
|
+
// → Updates all matching tasks
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
**Complex Examples:**
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
// Update all overdue high-priority tasks
|
|
791
|
+
batch_update_tasks({
|
|
792
|
+
selector: "due_at < '2026-01-18T00:00:00Z' AND priority = 'high' AND status != 'Done'",
|
|
793
|
+
updates: {
|
|
794
|
+
priority: "critical",
|
|
795
|
+
assignees: ["manager@company.com"]
|
|
796
|
+
},
|
|
797
|
+
dry_run: true // ALWAYS preview first!
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
// Move completed Q4 tasks to archive
|
|
801
|
+
batch_update_tasks({
|
|
802
|
+
selector: "completed_at >= '2025-10-01T00:00:00Z' AND completed_at < '2026-01-01T00:00:00Z'",
|
|
803
|
+
updates: { dartboard: "Archive/2025-Q4" },
|
|
804
|
+
dry_run: false,
|
|
805
|
+
concurrency: 10 // faster with higher concurrency
|
|
806
|
+
})
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
**Relationship Batch Examples:**
|
|
810
|
+
|
|
811
|
+
```typescript
|
|
812
|
+
// Clear all blockers from tasks in a specific dartboard
|
|
813
|
+
batch_update_tasks({
|
|
814
|
+
selector: "dartboard = 'Engineering/backend' AND blocker_ids IS NOT NULL",
|
|
815
|
+
updates: {
|
|
816
|
+
blocker_ids: [] // empty array clears all blockers
|
|
817
|
+
},
|
|
818
|
+
dry_run: true // ALWAYS preview first!
|
|
819
|
+
})
|
|
820
|
+
|
|
821
|
+
// Mark all high-priority tasks as blocking the release task
|
|
822
|
+
batch_update_tasks({
|
|
823
|
+
selector: "priority = 'critical' AND status != 'Done'",
|
|
824
|
+
updates: {
|
|
825
|
+
blocking_ids: ["duid_release_v2"]
|
|
826
|
+
},
|
|
827
|
+
dry_run: true
|
|
828
|
+
})
|
|
829
|
+
|
|
830
|
+
// Link all security-tagged tasks as related to the audit task
|
|
831
|
+
batch_update_tasks({
|
|
832
|
+
selector: "tags CONTAINS 'security'",
|
|
833
|
+
updates: {
|
|
834
|
+
related_ids: ["duid_security_audit_2026"]
|
|
835
|
+
},
|
|
836
|
+
dry_run: true
|
|
837
|
+
})
|
|
838
|
+
|
|
839
|
+
// Clear duplicate relationships from resolved tasks
|
|
840
|
+
batch_update_tasks({
|
|
841
|
+
selector: "status = 'Done' AND duplicate_ids IS NOT NULL",
|
|
842
|
+
updates: {
|
|
843
|
+
duplicate_ids: []
|
|
844
|
+
},
|
|
845
|
+
dry_run: false
|
|
846
|
+
})
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
**Important:** Batch relationship updates apply the SAME values to ALL matched tasks. Use this for scenarios like:
|
|
850
|
+
- Clearing relationships across many tasks
|
|
851
|
+
- Linking multiple tasks to a common blocker/release
|
|
852
|
+
- Resetting relationships during cleanup operations
|
|
853
|
+
|
|
854
|
+
**Token Budget:** ~400 tokens (returns summary, not full task data)
|
|
855
|
+
|
|
856
|
+
**Performance:** Depends on match count and concurrency (2-5 tasks/second typical)
|
|
857
|
+
|
|
858
|
+
---
|
|
859
|
+
|
|
860
|
+
### `batch_delete_tasks` - Bulk Delete with DartQL
|
|
861
|
+
|
|
862
|
+
**Purpose:** Delete (move to trash) multiple tasks matching a DartQL selector.
|
|
863
|
+
|
|
864
|
+
**Input Schema:**
|
|
865
|
+
```typescript
|
|
866
|
+
{
|
|
867
|
+
selector: string // REQUIRED, DartQL WHERE clause
|
|
868
|
+
dry_run?: boolean // default: false (RECOMMENDED: use true first!)
|
|
869
|
+
confirm?: boolean // REQUIRED for dry_run=false (safety flag)
|
|
870
|
+
concurrency?: number // default: 5, range 1-20
|
|
871
|
+
}
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
**Output Schema:** Same as `batch_update_tasks` (but no `preview_tasks`)
|
|
875
|
+
|
|
876
|
+
**Examples:**
|
|
877
|
+
|
|
878
|
+
```typescript
|
|
879
|
+
// Step 1: Preview (dry_run=true)
|
|
880
|
+
batch_delete_tasks({
|
|
881
|
+
selector: "dartboard = 'Personal/test' AND status = 'Done'",
|
|
882
|
+
dry_run: true
|
|
883
|
+
})
|
|
884
|
+
// → Shows count of matching tasks
|
|
885
|
+
|
|
886
|
+
// Step 2: Execute (dry_run=false with confirm=true)
|
|
887
|
+
batch_delete_tasks({
|
|
888
|
+
selector: "dartboard = 'Personal/test' AND status = 'Done'",
|
|
889
|
+
dry_run: false,
|
|
890
|
+
confirm: true // REQUIRED safety flag
|
|
891
|
+
})
|
|
892
|
+
// → Moves all matching tasks to trash
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
**SAFETY NOTES:**
|
|
896
|
+
- Tasks move to **trash**, NOT permanent deletion
|
|
897
|
+
- Recoverable via Dart web UI
|
|
898
|
+
- `confirm: true` required for dry_run=false (prevents accidental deletion)
|
|
899
|
+
- Triple-check selector specificity before executing
|
|
900
|
+
|
|
901
|
+
---
|
|
902
|
+
|
|
903
|
+
### `get_batch_status` - Check Batch Operation Status
|
|
904
|
+
|
|
905
|
+
**Purpose:** Get status of a long-running batch operation.
|
|
906
|
+
|
|
907
|
+
**Input Schema:**
|
|
908
|
+
```typescript
|
|
909
|
+
{
|
|
910
|
+
batch_operation_id: string // from batch_update_tasks or batch_delete_tasks
|
|
911
|
+
}
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
**Output Schema:**
|
|
915
|
+
```typescript
|
|
916
|
+
{
|
|
917
|
+
batch_operation_id: string
|
|
918
|
+
operation_type: 'update' | 'delete' | 'import'
|
|
919
|
+
status: 'pending' | 'in_progress' | 'completed' | 'failed'
|
|
920
|
+
total_items: number
|
|
921
|
+
successful_items: number
|
|
922
|
+
failed_items: number
|
|
923
|
+
started_at: string
|
|
924
|
+
completed_at?: string
|
|
925
|
+
}
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
**Examples:**
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
get_batch_status({ batch_operation_id: "batch_abc123" })
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
## CSV Import
|
|
937
|
+
|
|
938
|
+
### `import_tasks_csv` - Bulk Create from CSV
|
|
939
|
+
|
|
940
|
+
**Purpose:** Create hundreds of tasks from CSV data with validation, error recovery, and fuzzy matching.
|
|
941
|
+
|
|
942
|
+
**Input Schema:**
|
|
943
|
+
```typescript
|
|
944
|
+
{
|
|
945
|
+
csv_data?: string // inline CSV content (first row = headers)
|
|
946
|
+
csv_file_path?: string // OR path to CSV file
|
|
947
|
+
dartboard: string // REQUIRED, default dartboard name
|
|
948
|
+
column_mapping?: object // custom column name mappings
|
|
949
|
+
validate_only?: boolean // default: true (RECOMMENDED: validate first!)
|
|
950
|
+
continue_on_error?: boolean // default: true
|
|
951
|
+
concurrency?: number // default: 5, range 1-20
|
|
952
|
+
}
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
**CSV Column Mapping:**
|
|
956
|
+
```typescript
|
|
957
|
+
{
|
|
958
|
+
// Map custom column names to dart-query field names
|
|
959
|
+
"Task Name": "title",
|
|
960
|
+
"Assigned To": "assignee",
|
|
961
|
+
"Issue Priority": "priority",
|
|
962
|
+
"Labels": "tags"
|
|
963
|
+
}
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
**Output Schema:**
|
|
967
|
+
```typescript
|
|
968
|
+
{
|
|
969
|
+
batch_operation_id: string
|
|
970
|
+
total_rows: number
|
|
971
|
+
valid_rows: number
|
|
972
|
+
invalid_rows: number
|
|
973
|
+
|
|
974
|
+
// Validation errors (if any)
|
|
975
|
+
validation_errors: Array<{
|
|
976
|
+
row_number: number
|
|
977
|
+
errors: string[] // list of errors for this row
|
|
978
|
+
}>
|
|
979
|
+
|
|
980
|
+
// If validate_only=true:
|
|
981
|
+
preview: Array<{
|
|
982
|
+
row_number: number
|
|
983
|
+
task_preview: object // what will be created
|
|
984
|
+
}> // max 10 rows
|
|
985
|
+
|
|
986
|
+
// If validate_only=false:
|
|
987
|
+
created_tasks: number
|
|
988
|
+
failed_tasks: number
|
|
989
|
+
created_dart_ids: string[]
|
|
990
|
+
failed_items: Array<{
|
|
991
|
+
row_number: number
|
|
992
|
+
error: string
|
|
993
|
+
row_data: object
|
|
994
|
+
}>
|
|
995
|
+
|
|
996
|
+
execution_time_ms: number
|
|
997
|
+
}
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
**CSV Format Guide:**
|
|
1001
|
+
|
|
1002
|
+
**Required Columns:**
|
|
1003
|
+
- `title` - Task title (REQUIRED)
|
|
1004
|
+
|
|
1005
|
+
**Optional Columns:**
|
|
1006
|
+
- `description` - Task description
|
|
1007
|
+
- `status` - Status name (e.g., "To Do", "Doing")
|
|
1008
|
+
- `priority` - Priority string ("critical", "high", "medium", "low")
|
|
1009
|
+
- `size` - Size string ("xs", "small", "medium", "large", "xl")
|
|
1010
|
+
- `assignee` - Email address or name (singular)
|
|
1011
|
+
- `dartboard` - Override default dartboard
|
|
1012
|
+
- `tags` - Comma-separated tag names
|
|
1013
|
+
- `due_date` / `due_at` - ISO8601 date or recognizable format
|
|
1014
|
+
- `start_date` / `start_at` - ISO8601 date
|
|
1015
|
+
- `parent_task` - Parent task dart_id
|
|
1016
|
+
|
|
1017
|
+
**Relationship Columns** (comma-separated dart_id values):
|
|
1018
|
+
- `subtask_ids` / `subtasks` / `children` - Comma-separated subtask IDs
|
|
1019
|
+
- `blocker_ids` / `blockers` / `blocked_by` - Comma-separated blocker IDs
|
|
1020
|
+
- `blocking_ids` / `blocking` / `blocks` - Comma-separated blocked task IDs
|
|
1021
|
+
- `duplicate_ids` / `duplicates` - Comma-separated duplicate task IDs
|
|
1022
|
+
- `related_ids` / `related` / `related_tasks` - Comma-separated related task IDs
|
|
1023
|
+
|
|
1024
|
+
**Flexible Column Names** (case-insensitive, fuzzy matched):
|
|
1025
|
+
- `title` = `Title` = `Task Name` = `Task`
|
|
1026
|
+
- `assignee` = `Assigned To` = `Owner` = `Assignee`
|
|
1027
|
+
- `tags` = `Labels` = `Tags`
|
|
1028
|
+
- `priority` = `Priority` = `Pri`
|
|
1029
|
+
- `blocker_ids` = `blockers` = `blocked_by`
|
|
1030
|
+
- `blocking_ids` = `blocking` = `blocks`
|
|
1031
|
+
|
|
1032
|
+
**Example CSV (Basic):**
|
|
1033
|
+
|
|
1034
|
+
```csv
|
|
1035
|
+
title,description,assignee,priority,tags,due_at
|
|
1036
|
+
"Fix login bug","Users can't login after password reset",john@company.com,critical,"bug,security",2026-02-01T00:00:00Z
|
|
1037
|
+
"Update API docs","Document new authentication endpoints",writer@company.com,medium,documentation,2026-02-15T00:00:00Z
|
|
1038
|
+
"Add rate limiting","Prevent API abuse",engineer@company.com,high,"feature,security",2026-02-10T00:00:00Z
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
**Example CSV (With Relationships):**
|
|
1042
|
+
|
|
1043
|
+
```csv
|
|
1044
|
+
title,priority,blocker_ids,related_ids,tags
|
|
1045
|
+
"Deploy to production",critical,"duid_testing,duid_code_review",,deployment
|
|
1046
|
+
"Write unit tests",high,,"duid_feature_impl","testing,quality"
|
|
1047
|
+
"Code review",medium,"duid_feature_impl",,review
|
|
1048
|
+
"Feature implementation",high,,,"feature,backend"
|
|
1049
|
+
```
|
|
1050
|
+
|
|
1051
|
+
**CSV Relationship Format Notes:**
|
|
1052
|
+
- Use comma-separated dart_id values within a single cell
|
|
1053
|
+
- Wrap in quotes if values contain commas: `"duid_task1,duid_task2"`
|
|
1054
|
+
- Empty cell means no relationships of that type
|
|
1055
|
+
- All dart_id values must be in valid format (e.g., `duid_xxxxx`)
|
|
1056
|
+
|
|
1057
|
+
**Workflow:**
|
|
1058
|
+
|
|
1059
|
+
```typescript
|
|
1060
|
+
// Step 1: Get config to understand valid values
|
|
1061
|
+
get_config()
|
|
1062
|
+
// → See available dartboards, priorities, sizes, tags
|
|
1063
|
+
|
|
1064
|
+
// Step 2: Validate CSV (validate_only=true)
|
|
1065
|
+
import_tasks_csv({
|
|
1066
|
+
csv_file_path: "./tasks.csv",
|
|
1067
|
+
dartboard: "Engineering/backend",
|
|
1068
|
+
validate_only: true
|
|
1069
|
+
})
|
|
1070
|
+
// → Returns validation errors and preview of first 10 tasks
|
|
1071
|
+
|
|
1072
|
+
// Step 3: Fix any validation errors in CSV
|
|
1073
|
+
|
|
1074
|
+
// Step 4: Execute import (validate_only=false)
|
|
1075
|
+
import_tasks_csv({
|
|
1076
|
+
csv_file_path: "./tasks.csv",
|
|
1077
|
+
dartboard: "Engineering/backend",
|
|
1078
|
+
validate_only: false
|
|
1079
|
+
})
|
|
1080
|
+
// → Creates all tasks (41 tasks in 17.4s typical)
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
**Advanced Example with Column Mapping:**
|
|
1084
|
+
|
|
1085
|
+
```typescript
|
|
1086
|
+
import_tasks_csv({
|
|
1087
|
+
csv_file_path: "./jira_export.csv",
|
|
1088
|
+
dartboard: "Engineering/backend",
|
|
1089
|
+
column_mapping: {
|
|
1090
|
+
"Issue Summary": "title",
|
|
1091
|
+
"Issue Description": "description",
|
|
1092
|
+
"Assignee Email": "assignee",
|
|
1093
|
+
"Issue Priority": "priority",
|
|
1094
|
+
"Labels": "tags"
|
|
1095
|
+
},
|
|
1096
|
+
validate_only: true
|
|
1097
|
+
})
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
**Error Recovery:**
|
|
1101
|
+
|
|
1102
|
+
If > 50% of tasks fail, you'll get a rollback suggestion:
|
|
1103
|
+
|
|
1104
|
+
```
|
|
1105
|
+
WARNING: 75% of tasks failed to create. Consider deleting created tasks and fixing errors.
|
|
1106
|
+
Created task IDs: duid_task1, duid_task2, duid_task3
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
Use `batch_delete_tasks` to clean up:
|
|
1110
|
+
|
|
1111
|
+
```typescript
|
|
1112
|
+
// Delete failed import batch
|
|
1113
|
+
batch_delete_tasks({
|
|
1114
|
+
selector: "dart_id IN ('duid_task1', 'duid_task2', 'duid_task3')",
|
|
1115
|
+
dry_run: false,
|
|
1116
|
+
confirm: true
|
|
1117
|
+
})
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
**Token Budget:** ~500 tokens (returns summary + first 10 preview)
|
|
1121
|
+
|
|
1122
|
+
**Performance:** 2-4 tasks/second typical (41 tasks in 17.4s production tested)
|
|
1123
|
+
|
|
1124
|
+
---
|
|
1125
|
+
|
|
1126
|
+
## Document Management
|
|
1127
|
+
|
|
1128
|
+
dart-query includes full document (notes/docs) management. Documents are separate from tasks.
|
|
1129
|
+
|
|
1130
|
+
### `list_docs` - List Documents
|
|
1131
|
+
|
|
1132
|
+
**Input Schema:**
|
|
1133
|
+
```typescript
|
|
1134
|
+
{
|
|
1135
|
+
folder?: string // filter by folder name
|
|
1136
|
+
title_contains?: string // filter by title substring
|
|
1137
|
+
text_contains?: string // filter by content substring
|
|
1138
|
+
limit?: number // default 100
|
|
1139
|
+
offset?: number // default 0
|
|
1140
|
+
}
|
|
1141
|
+
```
|
|
1142
|
+
|
|
1143
|
+
**Output Schema:**
|
|
1144
|
+
```typescript
|
|
1145
|
+
{
|
|
1146
|
+
docs: Array<{
|
|
1147
|
+
doc_id: string
|
|
1148
|
+
title: string
|
|
1149
|
+
folder?: string
|
|
1150
|
+
created_at: string
|
|
1151
|
+
updated_at: string
|
|
1152
|
+
}>
|
|
1153
|
+
total: number
|
|
1154
|
+
}
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
### `create_doc` - Create Document
|
|
1158
|
+
|
|
1159
|
+
**Input Schema:**
|
|
1160
|
+
```typescript
|
|
1161
|
+
{
|
|
1162
|
+
title: string // REQUIRED
|
|
1163
|
+
text: string // REQUIRED, markdown content
|
|
1164
|
+
folder?: string // folder name
|
|
1165
|
+
}
|
|
1166
|
+
```
|
|
1167
|
+
|
|
1168
|
+
**Output Schema:**
|
|
1169
|
+
```typescript
|
|
1170
|
+
{
|
|
1171
|
+
doc_id: string
|
|
1172
|
+
title: string
|
|
1173
|
+
text: string
|
|
1174
|
+
folder?: string
|
|
1175
|
+
created_at: string
|
|
1176
|
+
updated_at: string
|
|
1177
|
+
url?: string
|
|
1178
|
+
}
|
|
1179
|
+
```
|
|
1180
|
+
|
|
1181
|
+
### `get_doc` - Retrieve Document
|
|
1182
|
+
|
|
1183
|
+
**Input Schema:**
|
|
1184
|
+
```typescript
|
|
1185
|
+
{
|
|
1186
|
+
doc_id: string // REQUIRED
|
|
1187
|
+
}
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
**Output Schema:** Same as `create_doc`
|
|
1191
|
+
|
|
1192
|
+
### `update_doc` - Update Document
|
|
1193
|
+
|
|
1194
|
+
**Input Schema:**
|
|
1195
|
+
```typescript
|
|
1196
|
+
{
|
|
1197
|
+
doc_id: string // REQUIRED
|
|
1198
|
+
title?: string
|
|
1199
|
+
text?: string
|
|
1200
|
+
folder?: string
|
|
1201
|
+
}
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
**Output Schema:** Same as `get_doc` (updated doc)
|
|
1205
|
+
|
|
1206
|
+
### `delete_doc` - Delete Document
|
|
1207
|
+
|
|
1208
|
+
**Input Schema:**
|
|
1209
|
+
```typescript
|
|
1210
|
+
{
|
|
1211
|
+
doc_id: string // REQUIRED
|
|
1212
|
+
}
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
**Output Schema:**
|
|
1216
|
+
```typescript
|
|
1217
|
+
{
|
|
1218
|
+
success: boolean
|
|
1219
|
+
doc_id: string
|
|
1220
|
+
}
|
|
1221
|
+
```
|
|
1222
|
+
|
|
1223
|
+
**Note:** Docs move to trash (recoverable)
|
|
1224
|
+
|
|
1225
|
+
---
|
|
1226
|
+
|
|
1227
|
+
## DartQL Reference
|
|
1228
|
+
|
|
1229
|
+
**DartQL** is a SQL-like WHERE clause syntax for batch operations.
|
|
1230
|
+
|
|
1231
|
+
### Syntax Overview
|
|
1232
|
+
|
|
1233
|
+
```sql
|
|
1234
|
+
field operator value [AND|OR field operator value ...]
|
|
1235
|
+
```
|
|
1236
|
+
|
|
1237
|
+
### Supported Operators
|
|
1238
|
+
|
|
1239
|
+
| Operator | Description | Example |
|
|
1240
|
+
|----------|-------------|---------|
|
|
1241
|
+
| `=` | Equals | `status = 'To Do'` |
|
|
1242
|
+
| `!=` | Not equals | `priority != 'low'` |
|
|
1243
|
+
| `>` | Greater than | `due_at > '2026-02-01'` |
|
|
1244
|
+
| `>=` | Greater or equal | `priority >= 'high'` |
|
|
1245
|
+
| `<` | Less than | `due_at < '2026-01-18'` |
|
|
1246
|
+
| `<=` | Less or equal | `priority <= 'medium'` |
|
|
1247
|
+
| `IN` | In list | `status IN ('To Do', 'Doing')` |
|
|
1248
|
+
| `NOT IN` | Not in list | `priority NOT IN ('low')` |
|
|
1249
|
+
| `LIKE` | Pattern match | `title LIKE '%authentication%'` |
|
|
1250
|
+
| `CONTAINS` | Array contains | `tags CONTAINS 'urgent'` |
|
|
1251
|
+
| `IS NULL` | Is null/undefined | `due_at IS NULL` |
|
|
1252
|
+
| `IS NOT NULL` | Is not null | `assignees IS NOT NULL` |
|
|
1253
|
+
| `BETWEEN` | Range | `created_at BETWEEN '2026-01-01' AND '2026-01-31'` |
|
|
1254
|
+
|
|
1255
|
+
### Logical Operators
|
|
1256
|
+
|
|
1257
|
+
| Operator | Description | Example |
|
|
1258
|
+
|----------|-------------|---------|
|
|
1259
|
+
| `AND` | Logical AND | `status = 'To Do' AND priority = 'high'` |
|
|
1260
|
+
| `OR` | Logical OR | `status = 'To Do' OR status = 'Doing'` |
|
|
1261
|
+
| `NOT` | Logical NOT | `NOT (priority = 'low')` |
|
|
1262
|
+
| `( )` | Grouping | `(status = 'To Do' OR status = 'Doing') AND priority = 'high'` |
|
|
1263
|
+
|
|
1264
|
+
### Valid Fields
|
|
1265
|
+
|
|
1266
|
+
**Core Fields:**
|
|
1267
|
+
- `status` - Task status
|
|
1268
|
+
- `priority` - Priority string
|
|
1269
|
+
- `size` - Size string
|
|
1270
|
+
- `title` - Task title
|
|
1271
|
+
- `description` - Task description
|
|
1272
|
+
- `assignee` - Assignee email
|
|
1273
|
+
- `dartboard` - Dartboard name
|
|
1274
|
+
- `tags` - Tag array
|
|
1275
|
+
- `created_at` - Creation timestamp
|
|
1276
|
+
- `updated_at` - Update timestamp
|
|
1277
|
+
- `due_at` - Due date
|
|
1278
|
+
- `start_at` - Start date
|
|
1279
|
+
- `completed_at` - Completion timestamp
|
|
1280
|
+
- `dart_id` - Task ID
|
|
1281
|
+
|
|
1282
|
+
**Relationship Fields:**
|
|
1283
|
+
- `parent_task` - Parent task ID (string)
|
|
1284
|
+
- `subtask_ids` - Subtask IDs (array)
|
|
1285
|
+
- `blocker_ids` - Blocker task IDs (array)
|
|
1286
|
+
- `blocking_ids` - Blocked task IDs (array)
|
|
1287
|
+
- `duplicate_ids` - Duplicate task IDs (array)
|
|
1288
|
+
- `related_ids` - Related task IDs (array)
|
|
1289
|
+
|
|
1290
|
+
### Examples
|
|
1291
|
+
|
|
1292
|
+
**Simple equality:**
|
|
1293
|
+
```sql
|
|
1294
|
+
status = 'To Do'
|
|
1295
|
+
dartboard = 'Engineering/backend'
|
|
1296
|
+
priority = 'high'
|
|
1297
|
+
```
|
|
1298
|
+
|
|
1299
|
+
**Multiple conditions (AND):**
|
|
1300
|
+
```sql
|
|
1301
|
+
status = 'To Do' AND priority = 'high'
|
|
1302
|
+
dartboard = 'Engineering/backend' AND assignee = 'john@company.com'
|
|
1303
|
+
```
|
|
1304
|
+
|
|
1305
|
+
**OR conditions:**
|
|
1306
|
+
```sql
|
|
1307
|
+
status = 'To Do' OR status = 'Doing'
|
|
1308
|
+
priority = 'high' OR priority = 'critical'
|
|
1309
|
+
```
|
|
1310
|
+
|
|
1311
|
+
**Range operators:**
|
|
1312
|
+
```sql
|
|
1313
|
+
due_at < '2026-01-18T00:00:00Z'
|
|
1314
|
+
due_at > '2026-02-01T00:00:00Z'
|
|
1315
|
+
```
|
|
1316
|
+
|
|
1317
|
+
**IN operator:**
|
|
1318
|
+
```sql
|
|
1319
|
+
status IN ('To Do', 'Doing', 'Blocked')
|
|
1320
|
+
priority IN ('high', 'critical')
|
|
1321
|
+
```
|
|
1322
|
+
|
|
1323
|
+
**Tag filtering:**
|
|
1324
|
+
```sql
|
|
1325
|
+
tags CONTAINS 'urgent'
|
|
1326
|
+
tags CONTAINS 'bug' AND tags CONTAINS 'security'
|
|
1327
|
+
```
|
|
1328
|
+
|
|
1329
|
+
**Pattern matching:**
|
|
1330
|
+
```sql
|
|
1331
|
+
title LIKE '%authentication%'
|
|
1332
|
+
description LIKE '%API%'
|
|
1333
|
+
```
|
|
1334
|
+
|
|
1335
|
+
**NULL checks:**
|
|
1336
|
+
```sql
|
|
1337
|
+
due_at IS NULL
|
|
1338
|
+
assignees IS NOT NULL
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1341
|
+
**Complex queries with grouping:**
|
|
1342
|
+
```sql
|
|
1343
|
+
(status = 'To Do' OR status = 'Doing') AND priority = 'high'
|
|
1344
|
+
dartboard = 'Engineering/backend' AND (priority = 'critical' OR tags CONTAINS 'urgent')
|
|
1345
|
+
```
|
|
1346
|
+
|
|
1347
|
+
**BETWEEN operator:**
|
|
1348
|
+
```sql
|
|
1349
|
+
created_at BETWEEN '2026-01-01T00:00:00Z' AND '2026-01-31T23:59:59Z'
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1352
|
+
### Relationship Query Examples
|
|
1353
|
+
|
|
1354
|
+
**Find tasks with relationships:**
|
|
1355
|
+
```sql
|
|
1356
|
+
-- Tasks that have blockers (are blocked by something)
|
|
1357
|
+
blocker_ids IS NOT NULL
|
|
1358
|
+
|
|
1359
|
+
-- Tasks that are blocking other tasks
|
|
1360
|
+
blocking_ids IS NOT NULL
|
|
1361
|
+
|
|
1362
|
+
-- Tasks with subtasks (parent tasks)
|
|
1363
|
+
subtask_ids IS NOT NULL
|
|
1364
|
+
|
|
1365
|
+
-- Leaf tasks (no subtasks)
|
|
1366
|
+
subtask_ids IS NULL
|
|
1367
|
+
|
|
1368
|
+
-- Tasks with related tasks
|
|
1369
|
+
related_ids IS NOT NULL
|
|
1370
|
+
|
|
1371
|
+
-- Tasks marked as duplicates
|
|
1372
|
+
duplicate_ids IS NOT NULL
|
|
1373
|
+
```
|
|
1374
|
+
|
|
1375
|
+
**Find tasks blocked by a specific task:**
|
|
1376
|
+
```sql
|
|
1377
|
+
-- Tasks blocked by the release blocker
|
|
1378
|
+
blocker_ids CONTAINS 'duid_release_blocker'
|
|
1379
|
+
|
|
1380
|
+
-- Tasks blocking the deployment
|
|
1381
|
+
blocking_ids CONTAINS 'duid_deployment'
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
**Find tasks related to a specific task:**
|
|
1385
|
+
```sql
|
|
1386
|
+
related_ids CONTAINS 'duid_feature_spec'
|
|
1387
|
+
```
|
|
1388
|
+
|
|
1389
|
+
**Combined relationship and field queries:**
|
|
1390
|
+
```sql
|
|
1391
|
+
-- High-priority blocked tasks
|
|
1392
|
+
blocker_ids IS NOT NULL AND priority = 'high'
|
|
1393
|
+
|
|
1394
|
+
-- Blocked tasks in Engineering dartboard
|
|
1395
|
+
dartboard = 'Engineering/backend' AND blocker_ids IS NOT NULL
|
|
1396
|
+
|
|
1397
|
+
-- Critical tasks that are blocking releases
|
|
1398
|
+
priority = 'critical' AND blocking_ids CONTAINS 'duid_release_v2'
|
|
1399
|
+
|
|
1400
|
+
-- Parent tasks with urgent tag
|
|
1401
|
+
subtask_ids IS NOT NULL AND tags CONTAINS 'urgent'
|
|
1402
|
+
|
|
1403
|
+
-- Unblocked tasks ready to start
|
|
1404
|
+
blocker_ids IS NULL AND status = 'To Do' AND priority = 'high'
|
|
1405
|
+
```
|
|
1406
|
+
|
|
1407
|
+
**Note on IS NULL for relationship arrays:**
|
|
1408
|
+
- `blocker_ids IS NULL` matches tasks with NO blockers (empty array or undefined)
|
|
1409
|
+
- `blocker_ids IS NOT NULL` matches tasks with AT LEAST ONE blocker
|
|
1410
|
+
- Empty arrays `[]` are treated as NULL for relationship fields
|
|
1411
|
+
|
|
1412
|
+
### API Filters vs. Client-Side Filtering
|
|
1413
|
+
|
|
1414
|
+
dart-query optimizes queries by using Dart API filters when possible, falling back to client-side filtering for complex queries.
|
|
1415
|
+
|
|
1416
|
+
**API-Compatible** (fast):
|
|
1417
|
+
- Simple `=` equality on: assignee, status, dartboard, priority, tags
|
|
1418
|
+
- Range operators on: due_at (`<`, `>`, `<=`, `>=`)
|
|
1419
|
+
- AND logic only
|
|
1420
|
+
|
|
1421
|
+
**Requires Client-Side Filtering** (slower):
|
|
1422
|
+
- OR logic
|
|
1423
|
+
- NOT logic
|
|
1424
|
+
- `!=` operator
|
|
1425
|
+
- `IN`, `NOT IN`, `LIKE`, `CONTAINS`, `IS NULL`, `BETWEEN`
|
|
1426
|
+
- Range operators on priority/size
|
|
1427
|
+
- Complex nested expressions
|
|
1428
|
+
|
|
1429
|
+
**Example:**
|
|
1430
|
+
|
|
1431
|
+
```typescript
|
|
1432
|
+
// API-compatible (fast)
|
|
1433
|
+
batch_update_tasks({
|
|
1434
|
+
selector: "dartboard = 'Engineering' AND priority = 'high'",
|
|
1435
|
+
updates: { status: "Doing" }
|
|
1436
|
+
})
|
|
1437
|
+
|
|
1438
|
+
// Requires client-side filtering (slower, fetches all tasks first)
|
|
1439
|
+
batch_update_tasks({
|
|
1440
|
+
selector: "status IN ('To Do', 'Doing') AND tags CONTAINS 'urgent'",
|
|
1441
|
+
updates: { priority: "critical" }
|
|
1442
|
+
})
|
|
1443
|
+
```
|
|
1444
|
+
|
|
1445
|
+
When client-side filtering is needed, you'll see a warning:
|
|
1446
|
+
|
|
1447
|
+
```
|
|
1448
|
+
Query requires client-side filtering which may impact performance.
|
|
1449
|
+
Consider using simpler queries with API-supported filters for better performance.
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
### Error Messages and Fuzzy Matching
|
|
1453
|
+
|
|
1454
|
+
DartQL provides helpful error messages with suggestions:
|
|
1455
|
+
|
|
1456
|
+
```
|
|
1457
|
+
Unknown field: 'priorty'. Did you mean 'priority'?
|
|
1458
|
+
Unknown field: 'assignees'. Did you mean 'assignee'?
|
|
1459
|
+
```
|
|
1460
|
+
|
|
1461
|
+
---
|
|
1462
|
+
|
|
1463
|
+
## Error Handling
|
|
1464
|
+
|
|
1465
|
+
### Error Types
|
|
1466
|
+
|
|
1467
|
+
**`ValidationError`** - Input validation failures
|
|
1468
|
+
```typescript
|
|
1469
|
+
{
|
|
1470
|
+
message: string
|
|
1471
|
+
field?: string // which field failed
|
|
1472
|
+
suggestions?: string[] // fuzzy match suggestions
|
|
1473
|
+
}
|
|
1474
|
+
```
|
|
1475
|
+
|
|
1476
|
+
**Common causes:**
|
|
1477
|
+
- Missing required fields
|
|
1478
|
+
- Invalid field values (priority not in config)
|
|
1479
|
+
- Invalid date formats
|
|
1480
|
+
- Empty strings where non-empty expected
|
|
1481
|
+
|
|
1482
|
+
**`DartAPIError`** - API communication errors
|
|
1483
|
+
```typescript
|
|
1484
|
+
{
|
|
1485
|
+
message: string
|
|
1486
|
+
statusCode: number // HTTP status code
|
|
1487
|
+
response?: object // API response body
|
|
1488
|
+
}
|
|
1489
|
+
```
|
|
1490
|
+
|
|
1491
|
+
**Common status codes:**
|
|
1492
|
+
- `401` - Invalid or missing DART_TOKEN
|
|
1493
|
+
- `404` - Resource not found (task, dartboard, etc.)
|
|
1494
|
+
- `429` - Rate limit exceeded
|
|
1495
|
+
- `400` - Bad request (malformed data)
|
|
1496
|
+
- `500` - Server error
|
|
1497
|
+
|
|
1498
|
+
**`DartQLParseError`** - DartQL syntax errors
|
|
1499
|
+
```typescript
|
|
1500
|
+
{
|
|
1501
|
+
message: string
|
|
1502
|
+
position: number // character position in query
|
|
1503
|
+
token: string // token that caused error
|
|
1504
|
+
}
|
|
1505
|
+
```
|
|
1506
|
+
|
|
1507
|
+
**Common causes:**
|
|
1508
|
+
- Unterminated string literals
|
|
1509
|
+
- Unknown operators
|
|
1510
|
+
- Missing parentheses
|
|
1511
|
+
- Invalid field names
|
|
1512
|
+
|
|
1513
|
+
### Error Recovery Strategies
|
|
1514
|
+
|
|
1515
|
+
**Validation Errors:**
|
|
1516
|
+
```typescript
|
|
1517
|
+
try {
|
|
1518
|
+
create_task({
|
|
1519
|
+
title: "Test task",
|
|
1520
|
+
dartboard: "Invalid Board"
|
|
1521
|
+
});
|
|
1522
|
+
} catch (error) {
|
|
1523
|
+
if (error instanceof ValidationError) {
|
|
1524
|
+
// Check suggestions
|
|
1525
|
+
if (error.suggestions && error.suggestions.length > 0) {
|
|
1526
|
+
console.log(`Did you mean: ${error.suggestions.join(', ')}?`);
|
|
1527
|
+
}
|
|
1528
|
+
// Get valid values from config
|
|
1529
|
+
const config = await get_config();
|
|
1530
|
+
console.log(`Valid dartboards: ${config.dartboards.join(', ')}`);
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
```
|
|
1534
|
+
|
|
1535
|
+
**Rate Limiting (429):**
|
|
1536
|
+
```typescript
|
|
1537
|
+
// Reduce concurrency
|
|
1538
|
+
batch_update_tasks({
|
|
1539
|
+
selector: "status = 'To Do'",
|
|
1540
|
+
updates: { priority: "high" },
|
|
1541
|
+
concurrency: 2 // Lower than default 5
|
|
1542
|
+
})
|
|
1543
|
+
```
|
|
1544
|
+
|
|
1545
|
+
dart-query has automatic retry with exponential backoff for rate limits.
|
|
1546
|
+
|
|
1547
|
+
**Network Errors:**
|
|
1548
|
+
```typescript
|
|
1549
|
+
try {
|
|
1550
|
+
const config = await get_config();
|
|
1551
|
+
} catch (error) {
|
|
1552
|
+
if (error instanceof DartAPIError && error.statusCode >= 500) {
|
|
1553
|
+
// Server error - retry after delay
|
|
1554
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
1555
|
+
const config = await get_config({ cache_bust: true });
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
```
|
|
1559
|
+
|
|
1560
|
+
**CSV Import Errors:**
|
|
1561
|
+
```typescript
|
|
1562
|
+
// Always validate first
|
|
1563
|
+
const validation = await import_tasks_csv({
|
|
1564
|
+
csv_file_path: "./tasks.csv",
|
|
1565
|
+
dartboard: "Engineering",
|
|
1566
|
+
validate_only: true
|
|
1567
|
+
});
|
|
1568
|
+
|
|
1569
|
+
if (validation.validation_errors.length > 0) {
|
|
1570
|
+
// Show all errors
|
|
1571
|
+
validation.validation_errors.forEach(err => {
|
|
1572
|
+
console.log(`Row ${err.row_number}: ${err.errors.join('; ')}`);
|
|
1573
|
+
});
|
|
1574
|
+
|
|
1575
|
+
// Fix CSV and retry
|
|
1576
|
+
} else {
|
|
1577
|
+
// Execute import
|
|
1578
|
+
const result = await import_tasks_csv({
|
|
1579
|
+
csv_file_path: "./tasks.csv",
|
|
1580
|
+
dartboard: "Engineering",
|
|
1581
|
+
validate_only: false
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1584
|
+
```
|
|
1585
|
+
|
|
1586
|
+
---
|
|
1587
|
+
|
|
1588
|
+
## Performance Optimization
|
|
1589
|
+
|
|
1590
|
+
### 1. Use Config Cache
|
|
1591
|
+
|
|
1592
|
+
```typescript
|
|
1593
|
+
// Good: Uses 5-minute cache
|
|
1594
|
+
get_config()
|
|
1595
|
+
|
|
1596
|
+
// Bad: Forces API call every time
|
|
1597
|
+
get_config({ cache_bust: true })
|
|
1598
|
+
```
|
|
1599
|
+
|
|
1600
|
+
### 2. Use Detail Levels
|
|
1601
|
+
|
|
1602
|
+
```typescript
|
|
1603
|
+
// Minimal details (fewer tokens, faster)
|
|
1604
|
+
list_tasks({ detail_level: "minimal" })
|
|
1605
|
+
|
|
1606
|
+
// Standard (default)
|
|
1607
|
+
list_tasks({ detail_level: "standard" })
|
|
1608
|
+
|
|
1609
|
+
// Full (most tokens, slowest)
|
|
1610
|
+
list_tasks({ detail_level: "full" })
|
|
1611
|
+
```
|
|
1612
|
+
|
|
1613
|
+
### 3. Optimize Batch Concurrency
|
|
1614
|
+
|
|
1615
|
+
```typescript
|
|
1616
|
+
// Too low: slow
|
|
1617
|
+
batch_update_tasks({
|
|
1618
|
+
selector: "...",
|
|
1619
|
+
updates: { ... },
|
|
1620
|
+
concurrency: 1
|
|
1621
|
+
})
|
|
1622
|
+
|
|
1623
|
+
// Default: balanced (5 concurrent)
|
|
1624
|
+
batch_update_tasks({
|
|
1625
|
+
selector: "...",
|
|
1626
|
+
updates: { ... }
|
|
1627
|
+
})
|
|
1628
|
+
|
|
1629
|
+
// Higher: faster but risks rate limits
|
|
1630
|
+
batch_update_tasks({
|
|
1631
|
+
selector: "...",
|
|
1632
|
+
updates: { ... },
|
|
1633
|
+
concurrency: 15 // Monitor for 429 errors
|
|
1634
|
+
})
|
|
1635
|
+
```
|
|
1636
|
+
|
|
1637
|
+
### 4. Use API-Compatible DartQL
|
|
1638
|
+
|
|
1639
|
+
```typescript
|
|
1640
|
+
// Fast: API-compatible
|
|
1641
|
+
selector: "dartboard = 'Engineering' AND priority = 'high'"
|
|
1642
|
+
|
|
1643
|
+
// Slow: Client-side filtering required
|
|
1644
|
+
selector: "status IN ('To Do', 'Doing') OR priority = 'critical'"
|
|
1645
|
+
```
|
|
1646
|
+
|
|
1647
|
+
### 5. Pagination for Large Result Sets
|
|
1648
|
+
|
|
1649
|
+
```typescript
|
|
1650
|
+
// Get first 100 tasks
|
|
1651
|
+
const page1 = await list_tasks({ limit: 100, offset: 0 });
|
|
1652
|
+
|
|
1653
|
+
// Get next 100 tasks
|
|
1654
|
+
const page2 = await list_tasks({ limit: 100, offset: 100 });
|
|
1655
|
+
```
|
|
1656
|
+
|
|
1657
|
+
### 6. Batch Operations vs. Individual Operations
|
|
1658
|
+
|
|
1659
|
+
```typescript
|
|
1660
|
+
// Bad: 50 individual API calls, 25,000+ tokens
|
|
1661
|
+
for (const task of tasks) {
|
|
1662
|
+
await update_task({ dart_id: task.dart_id, updates: { status: "Done" } });
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
// Good: 1 batch operation, ~400 tokens
|
|
1666
|
+
batch_update_tasks({
|
|
1667
|
+
selector: "dartboard = 'Engineering' AND priority = 'high'",
|
|
1668
|
+
updates: { status: "Done" }
|
|
1669
|
+
})
|
|
1670
|
+
```
|
|
1671
|
+
|
|
1672
|
+
**Token savings: 99%**
|
|
1673
|
+
**Time savings: 90%**
|
|
1674
|
+
**Context rot: Eliminated**
|
|
1675
|
+
|
|
1676
|
+
### 7. CSV Import vs. Individual Creates
|
|
1677
|
+
|
|
1678
|
+
```typescript
|
|
1679
|
+
// Bad: 100 create_task calls, 30,000+ tokens
|
|
1680
|
+
for (const row of csvData) {
|
|
1681
|
+
await create_task({ title: row.title, ... });
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
// Good: 1 CSV import, ~500 tokens
|
|
1685
|
+
import_tasks_csv({
|
|
1686
|
+
csv_file_path: "./tasks.csv",
|
|
1687
|
+
dartboard: "Engineering",
|
|
1688
|
+
validate_only: false
|
|
1689
|
+
})
|
|
1690
|
+
```
|
|
1691
|
+
|
|
1692
|
+
---
|
|
1693
|
+
|
|
1694
|
+
## Common Workflows
|
|
1695
|
+
|
|
1696
|
+
### Workflow 1: Create and Track Feature Development
|
|
1697
|
+
|
|
1698
|
+
```typescript
|
|
1699
|
+
// Step 1: Create parent task
|
|
1700
|
+
const parent = await create_task({
|
|
1701
|
+
title: "Implement OAuth2 authentication",
|
|
1702
|
+
dartboard: "Engineering/backend",
|
|
1703
|
+
priority: "high",
|
|
1704
|
+
size: "xl",
|
|
1705
|
+
due_at: "2026-03-01T00:00:00Z"
|
|
1706
|
+
});
|
|
1707
|
+
|
|
1708
|
+
// Step 2: Create subtasks
|
|
1709
|
+
await create_task({
|
|
1710
|
+
title: "Add Google OAuth provider",
|
|
1711
|
+
dartboard: "Engineering/backend",
|
|
1712
|
+
priority: "high",
|
|
1713
|
+
parent_task: parent.dart_id
|
|
1714
|
+
});
|
|
1715
|
+
|
|
1716
|
+
await create_task({
|
|
1717
|
+
title: "Add GitHub OAuth provider",
|
|
1718
|
+
dartboard: "Engineering/backend",
|
|
1719
|
+
priority: "high",
|
|
1720
|
+
parent_task: parent.dart_id
|
|
1721
|
+
});
|
|
1722
|
+
|
|
1723
|
+
// Step 3: Update all subtasks when starting work
|
|
1724
|
+
await batch_update_tasks({
|
|
1725
|
+
selector: `parent_task = '${parent.dart_id}'`,
|
|
1726
|
+
updates: { status: "Doing" }
|
|
1727
|
+
});
|
|
1728
|
+
```
|
|
1729
|
+
|
|
1730
|
+
### Workflow 2: Migrate Tasks from External System
|
|
1731
|
+
|
|
1732
|
+
```typescript
|
|
1733
|
+
// Step 1: Export from external system to CSV
|
|
1734
|
+
// Create CSV: jira_export.csv
|
|
1735
|
+
|
|
1736
|
+
// Step 2: Get dart-query config
|
|
1737
|
+
const config = await get_config();
|
|
1738
|
+
console.log("Available dartboards:", config.dartboards);
|
|
1739
|
+
console.log("Available priorities:", config.priorities);
|
|
1740
|
+
|
|
1741
|
+
// Step 3: Validate CSV
|
|
1742
|
+
const validation = await import_tasks_csv({
|
|
1743
|
+
csv_file_path: "./jira_export.csv",
|
|
1744
|
+
dartboard: "Engineering/backend",
|
|
1745
|
+
column_mapping: {
|
|
1746
|
+
"Issue Summary": "title",
|
|
1747
|
+
"Issue Description": "description",
|
|
1748
|
+
"Assignee Email": "assignee",
|
|
1749
|
+
"Issue Priority": "priority",
|
|
1750
|
+
"Labels": "tags"
|
|
1751
|
+
},
|
|
1752
|
+
validate_only: true
|
|
1753
|
+
});
|
|
1754
|
+
|
|
1755
|
+
if (validation.validation_errors.length > 0) {
|
|
1756
|
+
console.error("Validation errors:", validation.validation_errors);
|
|
1757
|
+
process.exit(1);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// Step 4: Execute import
|
|
1761
|
+
const result = await import_tasks_csv({
|
|
1762
|
+
csv_file_path: "./jira_export.csv",
|
|
1763
|
+
dartboard: "Engineering/backend",
|
|
1764
|
+
column_mapping: {
|
|
1765
|
+
"Issue Summary": "title",
|
|
1766
|
+
"Issue Description": "description",
|
|
1767
|
+
"Assignee Email": "assignee",
|
|
1768
|
+
"Issue Priority": "priority",
|
|
1769
|
+
"Labels": "tags"
|
|
1770
|
+
},
|
|
1771
|
+
validate_only: false
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1774
|
+
console.log(`Created ${result.created_tasks} tasks in ${result.execution_time_ms}ms`);
|
|
1775
|
+
```
|
|
1776
|
+
|
|
1777
|
+
### Workflow 3: Weekly Sprint Planning
|
|
1778
|
+
|
|
1779
|
+
```typescript
|
|
1780
|
+
// Step 1: Find all unassigned high-priority tasks
|
|
1781
|
+
const unassigned = await list_tasks({
|
|
1782
|
+
priority: "high",
|
|
1783
|
+
status: "To Do"
|
|
1784
|
+
});
|
|
1785
|
+
|
|
1786
|
+
// Step 2: Assign to team members
|
|
1787
|
+
await batch_update_tasks({
|
|
1788
|
+
selector: "priority = 'high' AND status = 'To Do' AND tags CONTAINS 'backend'",
|
|
1789
|
+
updates: { assignees: ["john@company.com"] }
|
|
1790
|
+
});
|
|
1791
|
+
|
|
1792
|
+
await batch_update_tasks({
|
|
1793
|
+
selector: "priority = 'high' AND status = 'To Do' AND tags CONTAINS 'frontend'",
|
|
1794
|
+
updates: { assignees: ["jane@company.com"] }
|
|
1795
|
+
});
|
|
1796
|
+
|
|
1797
|
+
// Step 3: Set sprint deadlines
|
|
1798
|
+
await batch_update_tasks({
|
|
1799
|
+
selector: "assignees IS NOT NULL AND status = 'To Do'",
|
|
1800
|
+
updates: { due_at: "2026-02-01T00:00:00Z" }
|
|
1801
|
+
});
|
|
1802
|
+
```
|
|
1803
|
+
|
|
1804
|
+
### Workflow 4: End of Quarter Cleanup
|
|
1805
|
+
|
|
1806
|
+
```typescript
|
|
1807
|
+
// Step 1: Archive completed tasks
|
|
1808
|
+
await batch_update_tasks({
|
|
1809
|
+
selector: "completed_at >= '2025-10-01' AND completed_at < '2026-01-01'",
|
|
1810
|
+
updates: { dartboard: "Archive/2025-Q4" },
|
|
1811
|
+
dry_run: true // Preview first
|
|
1812
|
+
});
|
|
1813
|
+
|
|
1814
|
+
// Step 2: After reviewing preview, execute
|
|
1815
|
+
await batch_update_tasks({
|
|
1816
|
+
selector: "completed_at >= '2025-10-01' AND completed_at < '2026-01-01'",
|
|
1817
|
+
updates: { dartboard: "Archive/2025-Q4" },
|
|
1818
|
+
dry_run: false,
|
|
1819
|
+
concurrency: 10
|
|
1820
|
+
});
|
|
1821
|
+
|
|
1822
|
+
// Step 3: Delete abandoned low-priority tasks
|
|
1823
|
+
await batch_delete_tasks({
|
|
1824
|
+
selector: "priority = 'low' AND updated_at < '2025-10-01' AND status = 'To Do'",
|
|
1825
|
+
dry_run: true
|
|
1826
|
+
});
|
|
1827
|
+
|
|
1828
|
+
await batch_delete_tasks({
|
|
1829
|
+
selector: "priority = 'low' AND updated_at < '2025-10-01' AND status = 'To Do'",
|
|
1830
|
+
dry_run: false,
|
|
1831
|
+
confirm: true
|
|
1832
|
+
});
|
|
1833
|
+
```
|
|
1834
|
+
|
|
1835
|
+
### Workflow 5: Security Audit Remediation
|
|
1836
|
+
|
|
1837
|
+
```typescript
|
|
1838
|
+
// Step 1: Search for security-related tasks
|
|
1839
|
+
const securityTasks = await search_tasks({
|
|
1840
|
+
query: "security vulnerability authentication xss sql injection",
|
|
1841
|
+
dartboard: "Engineering"
|
|
1842
|
+
});
|
|
1843
|
+
|
|
1844
|
+
// Step 2: Tag all security tasks
|
|
1845
|
+
await batch_update_tasks({
|
|
1846
|
+
selector: "tags CONTAINS 'security'",
|
|
1847
|
+
updates: {
|
|
1848
|
+
priority: "critical",
|
|
1849
|
+
tags: ["security", "audit-2026-q1"]
|
|
1850
|
+
}
|
|
1851
|
+
});
|
|
1852
|
+
|
|
1853
|
+
// Step 3: Track remediation
|
|
1854
|
+
await add_task_comment({
|
|
1855
|
+
dart_id: "duid_task123",
|
|
1856
|
+
comment: "Reviewed by security team - CVSS 8.5, requires immediate patching"
|
|
1857
|
+
});
|
|
1858
|
+
```
|
|
1859
|
+
|
|
1860
|
+
### Workflow 6: Managing Task Dependencies (Relationships)
|
|
1861
|
+
|
|
1862
|
+
```typescript
|
|
1863
|
+
// Step 1: Create a release task that will be blocked by feature tasks
|
|
1864
|
+
const release = await create_task({
|
|
1865
|
+
title: "Release v2.0",
|
|
1866
|
+
dartboard: "Engineering/releases",
|
|
1867
|
+
priority: "high",
|
|
1868
|
+
due_at: "2026-03-01T00:00:00Z"
|
|
1869
|
+
});
|
|
1870
|
+
|
|
1871
|
+
// Step 2: Create feature tasks that block the release
|
|
1872
|
+
const feature1 = await create_task({
|
|
1873
|
+
title: "Implement OAuth2",
|
|
1874
|
+
dartboard: "Engineering/backend",
|
|
1875
|
+
priority: "high",
|
|
1876
|
+
blocking_ids: [release.dart_id] // This task blocks the release
|
|
1877
|
+
});
|
|
1878
|
+
|
|
1879
|
+
const feature2 = await create_task({
|
|
1880
|
+
title: "Update user dashboard",
|
|
1881
|
+
dartboard: "Engineering/frontend",
|
|
1882
|
+
priority: "high",
|
|
1883
|
+
blocking_ids: [release.dart_id] // This task also blocks the release
|
|
1884
|
+
});
|
|
1885
|
+
|
|
1886
|
+
// Step 3: Update the release task with its blockers
|
|
1887
|
+
await update_task({
|
|
1888
|
+
dart_id: release.dart_id,
|
|
1889
|
+
updates: {
|
|
1890
|
+
blocker_ids: [feature1.dart_id, feature2.dart_id]
|
|
1891
|
+
}
|
|
1892
|
+
});
|
|
1893
|
+
|
|
1894
|
+
// Step 4: Find all blocked tasks in the release pipeline
|
|
1895
|
+
const blockedTasks = await list_tasks({
|
|
1896
|
+
has_blockers: true,
|
|
1897
|
+
dartboard: "Engineering/releases"
|
|
1898
|
+
});
|
|
1899
|
+
|
|
1900
|
+
// Step 5: When a feature is complete, update relationships
|
|
1901
|
+
// First get current state to preserve other blockers
|
|
1902
|
+
const releaseTask = await get_task({ dart_id: release.dart_id });
|
|
1903
|
+
|
|
1904
|
+
// Remove completed feature from blockers
|
|
1905
|
+
const remainingBlockers = releaseTask.blocker_ids?.filter(
|
|
1906
|
+
id => id !== feature1.dart_id
|
|
1907
|
+
) || [];
|
|
1908
|
+
|
|
1909
|
+
await update_task({
|
|
1910
|
+
dart_id: release.dart_id,
|
|
1911
|
+
updates: {
|
|
1912
|
+
blocker_ids: remainingBlockers
|
|
1913
|
+
}
|
|
1914
|
+
});
|
|
1915
|
+
|
|
1916
|
+
// Step 6: Find all tasks ready to release (no longer blocked)
|
|
1917
|
+
const readyTasks = await list_tasks({
|
|
1918
|
+
has_blockers: false,
|
|
1919
|
+
dartboard: "Engineering/releases",
|
|
1920
|
+
status: "To Do"
|
|
1921
|
+
});
|
|
1922
|
+
```
|
|
1923
|
+
|
|
1924
|
+
### Workflow 7: Linking Related Tasks
|
|
1925
|
+
|
|
1926
|
+
```typescript
|
|
1927
|
+
// Step 1: Create a design spec task
|
|
1928
|
+
const designSpec = await create_task({
|
|
1929
|
+
title: "Design authentication system spec",
|
|
1930
|
+
dartboard: "Engineering/design",
|
|
1931
|
+
priority: "high"
|
|
1932
|
+
});
|
|
1933
|
+
|
|
1934
|
+
// Step 2: Create implementation tasks related to the spec
|
|
1935
|
+
const backendTask = await create_task({
|
|
1936
|
+
title: "Implement auth backend",
|
|
1937
|
+
dartboard: "Engineering/backend",
|
|
1938
|
+
related_ids: [designSpec.dart_id]
|
|
1939
|
+
});
|
|
1940
|
+
|
|
1941
|
+
const frontendTask = await create_task({
|
|
1942
|
+
title: "Implement auth frontend",
|
|
1943
|
+
dartboard: "Engineering/frontend",
|
|
1944
|
+
related_ids: [designSpec.dart_id]
|
|
1945
|
+
});
|
|
1946
|
+
|
|
1947
|
+
// Step 3: Update the spec to link back to implementations
|
|
1948
|
+
await update_task({
|
|
1949
|
+
dart_id: designSpec.dart_id,
|
|
1950
|
+
updates: {
|
|
1951
|
+
related_ids: [backendTask.dart_id, frontendTask.dart_id]
|
|
1952
|
+
}
|
|
1953
|
+
});
|
|
1954
|
+
|
|
1955
|
+
// Step 4: Batch link all auth-tagged tasks to the spec
|
|
1956
|
+
await batch_update_tasks({
|
|
1957
|
+
selector: "tags CONTAINS 'auth' AND dart_id != '" + designSpec.dart_id + "'",
|
|
1958
|
+
updates: {
|
|
1959
|
+
related_ids: [designSpec.dart_id]
|
|
1960
|
+
},
|
|
1961
|
+
dry_run: true // Preview first!
|
|
1962
|
+
});
|
|
1963
|
+
|
|
1964
|
+
// Step 5: Find all tasks related to the spec
|
|
1965
|
+
const relatedToSpec = await list_tasks({});
|
|
1966
|
+
// Then filter client-side or use DartQL:
|
|
1967
|
+
await batch_update_tasks({
|
|
1968
|
+
selector: "related_ids CONTAINS '" + designSpec.dart_id + "'",
|
|
1969
|
+
updates: { status: "In Review" },
|
|
1970
|
+
dry_run: true
|
|
1971
|
+
});
|
|
1972
|
+
```
|
|
1973
|
+
|
|
1974
|
+
### Workflow 8: Handling Duplicate Tasks
|
|
1975
|
+
|
|
1976
|
+
```typescript
|
|
1977
|
+
// Step 1: Find potential duplicates via search
|
|
1978
|
+
const searchResults = await search_tasks({
|
|
1979
|
+
query: "authentication login bug"
|
|
1980
|
+
});
|
|
1981
|
+
|
|
1982
|
+
// Step 2: Mark tasks as duplicates of the original
|
|
1983
|
+
const originalTask = searchResults.results[0];
|
|
1984
|
+
const duplicateTasks = searchResults.results.slice(1);
|
|
1985
|
+
|
|
1986
|
+
// Link duplicates to original
|
|
1987
|
+
await update_task({
|
|
1988
|
+
dart_id: originalTask.dart_id,
|
|
1989
|
+
updates: {
|
|
1990
|
+
duplicate_ids: duplicateTasks.map(t => t.dart_id)
|
|
1991
|
+
}
|
|
1992
|
+
});
|
|
1993
|
+
|
|
1994
|
+
// Step 3: Close duplicate tasks
|
|
1995
|
+
await batch_update_tasks({
|
|
1996
|
+
selector: `dart_id IN (${duplicateTasks.map(t => `'${t.dart_id}'`).join(', ')})`,
|
|
1997
|
+
updates: {
|
|
1998
|
+
status: "Duplicate",
|
|
1999
|
+
duplicate_ids: [originalTask.dart_id] // Link back to original
|
|
2000
|
+
},
|
|
2001
|
+
dry_run: false
|
|
2002
|
+
});
|
|
2003
|
+
|
|
2004
|
+
// Step 4: Find all tasks marked as duplicates
|
|
2005
|
+
const allDuplicates = await list_tasks({});
|
|
2006
|
+
// Use DartQL to find:
|
|
2007
|
+
await batch_update_tasks({
|
|
2008
|
+
selector: "duplicate_ids IS NOT NULL",
|
|
2009
|
+
updates: { priority: "low" },
|
|
2010
|
+
dry_run: true
|
|
2011
|
+
});
|
|
2012
|
+
```
|
|
2013
|
+
|
|
2014
|
+
---
|
|
2015
|
+
|
|
2016
|
+
## Troubleshooting Guide
|
|
2017
|
+
|
|
2018
|
+
### Problem: Authentication Errors
|
|
2019
|
+
|
|
2020
|
+
**Error:**
|
|
2021
|
+
```
|
|
2022
|
+
Error: Invalid DART_TOKEN
|
|
2023
|
+
```
|
|
2024
|
+
|
|
2025
|
+
**Solution:**
|
|
2026
|
+
1. Get fresh token from https://app.dartai.com/?settings=account
|
|
2027
|
+
2. Ensure token starts with `dsa_`
|
|
2028
|
+
3. Verify environment variable: `echo $DART_TOKEN`
|
|
2029
|
+
4. Restart MCP server after changing token
|
|
2030
|
+
|
|
2031
|
+
### Problem: Rate Limiting (429)
|
|
2032
|
+
|
|
2033
|
+
**Error:**
|
|
2034
|
+
```
|
|
2035
|
+
Error: Rate limit exceeded
|
|
2036
|
+
```
|
|
2037
|
+
|
|
2038
|
+
**Solution:**
|
|
2039
|
+
1. Reduce `concurrency` parameter (try 2-3 instead of default 5)
|
|
2040
|
+
2. Add delays between batch operations
|
|
2041
|
+
3. Use API-compatible DartQL (avoids client-side filtering)
|
|
2042
|
+
4. Contact Dart support if persistent
|
|
2043
|
+
|
|
2044
|
+
dart-query has automatic retry with exponential backoff.
|
|
2045
|
+
|
|
2046
|
+
### Problem: CSV Import Failures
|
|
2047
|
+
|
|
2048
|
+
**Error:**
|
|
2049
|
+
```
|
|
2050
|
+
Row 3, column 'priority': Invalid priority: "5". Available: critical, high, medium, low
|
|
2051
|
+
```
|
|
2052
|
+
|
|
2053
|
+
**Solution:**
|
|
2054
|
+
1. Always use `validate_only: true` first
|
|
2055
|
+
2. Check `get_config()` for available values
|
|
2056
|
+
3. Use string priorities ("high") not numbers (3)
|
|
2057
|
+
4. Use string sizes ("medium") not numbers (3)
|
|
2058
|
+
5. Verify dartboard names exactly match config
|
|
2059
|
+
6. Check date formats (ISO8601: "2026-02-01T00:00:00Z")
|
|
2060
|
+
|
|
2061
|
+
### Problem: DartQL Syntax Errors
|
|
2062
|
+
|
|
2063
|
+
**Error:**
|
|
2064
|
+
```
|
|
2065
|
+
Unknown field: priorty. Did you mean: priority?
|
|
2066
|
+
```
|
|
2067
|
+
|
|
2068
|
+
**Solution:**
|
|
2069
|
+
1. Check field name spelling (fuzzy match suggestions provided)
|
|
2070
|
+
2. Valid fields: status, priority, size, title, description, assignee, dartboard, tags, dates, dart_id
|
|
2071
|
+
3. Use quotes for string values: `status = 'To Do'` not `status = To Do`
|
|
2072
|
+
4. Check operator syntax: `=`, `!=`, `>`, `>=`, `<`, `<=`, `IN`, `NOT IN`, `LIKE`, `CONTAINS`
|
|
2073
|
+
|
|
2074
|
+
### Problem: Batch Operations Matching Wrong Tasks
|
|
2075
|
+
|
|
2076
|
+
**Error:**
|
|
2077
|
+
```
|
|
2078
|
+
Accidentally updated 500 tasks instead of 50
|
|
2079
|
+
```
|
|
2080
|
+
|
|
2081
|
+
**Solution:**
|
|
2082
|
+
1. **ALWAYS** use `dry_run: true` first
|
|
2083
|
+
2. Review preview carefully before executing
|
|
2084
|
+
3. Test selector with `list_tasks()` first
|
|
2085
|
+
4. Start with small batches (< 10 tasks) to verify selector
|
|
2086
|
+
5. Use more specific selectors (multiple AND conditions)
|
|
2087
|
+
|
|
2088
|
+
**Recovery:**
|
|
2089
|
+
Tasks move to trash (recoverable via Dart web UI)
|
|
2090
|
+
|
|
2091
|
+
### Problem: Slow Performance
|
|
2092
|
+
|
|
2093
|
+
**Symptoms:**
|
|
2094
|
+
- Batch operations taking > 10s per task
|
|
2095
|
+
- CSV imports timing out
|
|
2096
|
+
- Context window filling up
|
|
2097
|
+
|
|
2098
|
+
**Solutions:**
|
|
2099
|
+
1. Use API-compatible DartQL (avoid OR, NOT, LIKE)
|
|
2100
|
+
2. Increase concurrency (try 10-15 instead of 5)
|
|
2101
|
+
3. Use `detail_level: "minimal"` for large queries
|
|
2102
|
+
4. Enable config cache (default 5 minutes)
|
|
2103
|
+
5. Paginate large result sets
|
|
2104
|
+
6. Use batch operations instead of individual CRUD
|
|
2105
|
+
|
|
2106
|
+
---
|
|
2107
|
+
|
|
2108
|
+
## Best Practices Summary
|
|
2109
|
+
|
|
2110
|
+
### Production Safety
|
|
2111
|
+
- ✅ Always use `dry_run: true` for batch operations
|
|
2112
|
+
- ✅ Always use `validate_only: true` for CSV imports
|
|
2113
|
+
- ✅ Test selectors with small datasets first (< 10 tasks)
|
|
2114
|
+
- ✅ Review previews before executing
|
|
2115
|
+
- ✅ Have rollback plan (tasks → trash, recoverable)
|
|
2116
|
+
- ✅ Use `confirm: true` for batch deletes
|
|
2117
|
+
- ✅ Triple-check selector specificity
|
|
2118
|
+
|
|
2119
|
+
### Performance
|
|
2120
|
+
- ✅ Use batch operations for > 5 tasks
|
|
2121
|
+
- ✅ Use CSV import for > 50 tasks
|
|
2122
|
+
- ✅ Use config cache (don't bust unless needed)
|
|
2123
|
+
- ✅ Use minimal detail levels when possible
|
|
2124
|
+
- ✅ Use API-compatible DartQL selectors
|
|
2125
|
+
- ✅ Adjust concurrency based on rate limits (2-15 range)
|
|
2126
|
+
- ✅ Paginate large result sets (limit/offset)
|
|
2127
|
+
|
|
2128
|
+
### Error Prevention
|
|
2129
|
+
- ✅ Call `get_config()` before creating tasks
|
|
2130
|
+
- ✅ Validate all CSV data before import
|
|
2131
|
+
- ✅ Use fuzzy match suggestions for typos
|
|
2132
|
+
- ✅ Check field names in DartQL queries
|
|
2133
|
+
- ✅ Use proper date formats (ISO8601)
|
|
2134
|
+
- ✅ Use string priorities/sizes ("high", "medium") not numbers
|
|
2135
|
+
|
|
2136
|
+
### Context Efficiency
|
|
2137
|
+
- ✅ Batch operations return summaries (not full data)
|
|
2138
|
+
- ✅ CSV import returns preview of first 10 (not all)
|
|
2139
|
+
- ✅ Use `info` tool for progressive discovery
|
|
2140
|
+
- ✅ Use `detail_level: "minimal"` when appropriate
|
|
2141
|
+
- ✅ **Result: 99% token reduction vs. traditional approach**
|
|
2142
|
+
|
|
2143
|
+
---
|
|
2144
|
+
|
|
2145
|
+
**For additional help:**
|
|
2146
|
+
- GitHub Issues: https://github.com/standardbeagle/dart-query/issues
|
|
2147
|
+
- Dart AI Support: https://dartai.com/support
|
|
2148
|
+
- MCP Documentation: https://modelcontextprotocol.io
|