@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.
Files changed (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +427 -0
  3. package/TOOLS.md +2148 -0
  4. package/dist/api/dartClient.d.ts +123 -0
  5. package/dist/api/dartClient.d.ts.map +1 -0
  6. package/dist/api/dartClient.js +436 -0
  7. package/dist/api/dartClient.js.map +1 -0
  8. package/dist/batch/batchOperations.d.ts +14 -0
  9. package/dist/batch/batchOperations.d.ts.map +1 -0
  10. package/dist/batch/batchOperations.js +65 -0
  11. package/dist/batch/batchOperations.js.map +1 -0
  12. package/dist/cache/configCache.d.ts +20 -0
  13. package/dist/cache/configCache.d.ts.map +1 -0
  14. package/dist/cache/configCache.js +59 -0
  15. package/dist/cache/configCache.js.map +1 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +1120 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/parsers/csv.d.ts +44 -0
  21. package/dist/parsers/csv.d.ts.map +1 -0
  22. package/dist/parsers/csv.js +574 -0
  23. package/dist/parsers/csv.js.map +1 -0
  24. package/dist/parsers/dartql.d.ts +104 -0
  25. package/dist/parsers/dartql.d.ts.map +1 -0
  26. package/dist/parsers/dartql.js +889 -0
  27. package/dist/parsers/dartql.js.map +1 -0
  28. package/dist/tools/add_task_comment.d.ts +3 -0
  29. package/dist/tools/add_task_comment.d.ts.map +1 -0
  30. package/dist/tools/add_task_comment.js +43 -0
  31. package/dist/tools/add_task_comment.js.map +1 -0
  32. package/dist/tools/add_time_tracking.d.ts +3 -0
  33. package/dist/tools/add_time_tracking.d.ts.map +1 -0
  34. package/dist/tools/add_time_tracking.js +52 -0
  35. package/dist/tools/add_time_tracking.js.map +1 -0
  36. package/dist/tools/attach_url.d.ts +3 -0
  37. package/dist/tools/attach_url.d.ts.map +1 -0
  38. package/dist/tools/attach_url.js +38 -0
  39. package/dist/tools/attach_url.js.map +1 -0
  40. package/dist/tools/batch_delete_tasks.d.ts +3 -0
  41. package/dist/tools/batch_delete_tasks.d.ts.map +1 -0
  42. package/dist/tools/batch_delete_tasks.js +125 -0
  43. package/dist/tools/batch_delete_tasks.js.map +1 -0
  44. package/dist/tools/batch_update_tasks.d.ts +3 -0
  45. package/dist/tools/batch_update_tasks.d.ts.map +1 -0
  46. package/dist/tools/batch_update_tasks.js +327 -0
  47. package/dist/tools/batch_update_tasks.js.map +1 -0
  48. package/dist/tools/create_doc.d.ts +3 -0
  49. package/dist/tools/create_doc.d.ts.map +1 -0
  50. package/dist/tools/create_doc.js +65 -0
  51. package/dist/tools/create_doc.js.map +1 -0
  52. package/dist/tools/create_task.d.ts +3 -0
  53. package/dist/tools/create_task.d.ts.map +1 -0
  54. package/dist/tools/create_task.js +143 -0
  55. package/dist/tools/create_task.js.map +1 -0
  56. package/dist/tools/delete_doc.d.ts +3 -0
  57. package/dist/tools/delete_doc.d.ts.map +1 -0
  58. package/dist/tools/delete_doc.js +35 -0
  59. package/dist/tools/delete_doc.js.map +1 -0
  60. package/dist/tools/delete_task.d.ts +3 -0
  61. package/dist/tools/delete_task.d.ts.map +1 -0
  62. package/dist/tools/delete_task.js +35 -0
  63. package/dist/tools/delete_task.js.map +1 -0
  64. package/dist/tools/get_batch_status.d.ts +3 -0
  65. package/dist/tools/get_batch_status.d.ts.map +1 -0
  66. package/dist/tools/get_batch_status.js +24 -0
  67. package/dist/tools/get_batch_status.js.map +1 -0
  68. package/dist/tools/get_config.d.ts +3 -0
  69. package/dist/tools/get_config.d.ts.map +1 -0
  70. package/dist/tools/get_config.js +74 -0
  71. package/dist/tools/get_config.js.map +1 -0
  72. package/dist/tools/get_dartboard.d.ts +3 -0
  73. package/dist/tools/get_dartboard.d.ts.map +1 -0
  74. package/dist/tools/get_dartboard.js +43 -0
  75. package/dist/tools/get_dartboard.js.map +1 -0
  76. package/dist/tools/get_doc.d.ts +3 -0
  77. package/dist/tools/get_doc.d.ts.map +1 -0
  78. package/dist/tools/get_doc.js +34 -0
  79. package/dist/tools/get_doc.js.map +1 -0
  80. package/dist/tools/get_folder.d.ts +3 -0
  81. package/dist/tools/get_folder.d.ts.map +1 -0
  82. package/dist/tools/get_folder.js +45 -0
  83. package/dist/tools/get_folder.js.map +1 -0
  84. package/dist/tools/get_task.d.ts +3 -0
  85. package/dist/tools/get_task.d.ts.map +1 -0
  86. package/dist/tools/get_task.js +109 -0
  87. package/dist/tools/get_task.js.map +1 -0
  88. package/dist/tools/import_tasks_csv.d.ts +3 -0
  89. package/dist/tools/import_tasks_csv.d.ts.map +1 -0
  90. package/dist/tools/import_tasks_csv.js +218 -0
  91. package/dist/tools/import_tasks_csv.js.map +1 -0
  92. package/dist/tools/info.d.ts +3 -0
  93. package/dist/tools/info.d.ts.map +1 -0
  94. package/dist/tools/info.js +474 -0
  95. package/dist/tools/info.js.map +1 -0
  96. package/dist/tools/list_comments.d.ts +3 -0
  97. package/dist/tools/list_comments.d.ts.map +1 -0
  98. package/dist/tools/list_comments.js +46 -0
  99. package/dist/tools/list_comments.js.map +1 -0
  100. package/dist/tools/list_docs.d.ts +3 -0
  101. package/dist/tools/list_docs.d.ts.map +1 -0
  102. package/dist/tools/list_docs.js +101 -0
  103. package/dist/tools/list_docs.js.map +1 -0
  104. package/dist/tools/list_tasks.d.ts +3 -0
  105. package/dist/tools/list_tasks.d.ts.map +1 -0
  106. package/dist/tools/list_tasks.js +325 -0
  107. package/dist/tools/list_tasks.js.map +1 -0
  108. package/dist/tools/move_task.d.ts +3 -0
  109. package/dist/tools/move_task.d.ts.map +1 -0
  110. package/dist/tools/move_task.js +44 -0
  111. package/dist/tools/move_task.js.map +1 -0
  112. package/dist/tools/search_tasks.d.ts +3 -0
  113. package/dist/tools/search_tasks.d.ts.map +1 -0
  114. package/dist/tools/search_tasks.js +227 -0
  115. package/dist/tools/search_tasks.js.map +1 -0
  116. package/dist/tools/update_doc.d.ts +3 -0
  117. package/dist/tools/update_doc.d.ts.map +1 -0
  118. package/dist/tools/update_doc.js +102 -0
  119. package/dist/tools/update_doc.js.map +1 -0
  120. package/dist/tools/update_task.d.ts +3 -0
  121. package/dist/tools/update_task.d.ts.map +1 -0
  122. package/dist/tools/update_task.js +241 -0
  123. package/dist/tools/update_task.js.map +1 -0
  124. package/dist/types/index.d.ts +529 -0
  125. package/dist/types/index.d.ts.map +1 -0
  126. package/dist/types/index.js +65 -0
  127. package/dist/types/index.js.map +1 -0
  128. 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