@hailer/mcp 0.0.1

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 (163) hide show
  1. package/.claude/commands/tool-builder.md +37 -0
  2. package/.claude/commands/ws-pull.md +44 -0
  3. package/.claude/settings.json +8 -0
  4. package/.claude/settings.local.json +49 -0
  5. package/.claude/skills/activity-api/SKILL.md +96 -0
  6. package/.claude/skills/activity-api/references/activity-endpoints.md +845 -0
  7. package/.claude/skills/add-app-member-skill/SKILL.md +977 -0
  8. package/.claude/skills/agent-building/SKILL.md +243 -0
  9. package/.claude/skills/agent-building/references/architecture-patterns.md +446 -0
  10. package/.claude/skills/agent-building/references/code-examples.md +587 -0
  11. package/.claude/skills/agent-building/references/implementation-guide.md +619 -0
  12. package/.claude/skills/app-api/SKILL.md +219 -0
  13. package/.claude/skills/app-api/references/app-endpoints.md +759 -0
  14. package/.claude/skills/building-hailer-apps-skill/SKILL.md +548 -0
  15. package/.claude/skills/create-app-skill/SKILL.md +1101 -0
  16. package/.claude/skills/create-insight-skill/SKILL.md +1317 -0
  17. package/.claude/skills/get-insight-data-skill/SKILL.md +1053 -0
  18. package/.claude/skills/hailer-api/SKILL.md +283 -0
  19. package/.claude/skills/hailer-api/references/activities.md +620 -0
  20. package/.claude/skills/hailer-api/references/authentication.md +216 -0
  21. package/.claude/skills/hailer-api/references/datasets.md +437 -0
  22. package/.claude/skills/hailer-api/references/files.md +301 -0
  23. package/.claude/skills/hailer-api/references/insights.md +469 -0
  24. package/.claude/skills/hailer-api/references/workflows.md +720 -0
  25. package/.claude/skills/hailer-api/references/workspaces-users.md +445 -0
  26. package/.claude/skills/insight-api/SKILL.md +185 -0
  27. package/.claude/skills/insight-api/references/insight-endpoints.md +514 -0
  28. package/.claude/skills/install-workflow-skill/SKILL.md +1056 -0
  29. package/.claude/skills/list-apps-skill/SKILL.md +1010 -0
  30. package/.claude/skills/list-workflows-minimal-skill/SKILL.md +992 -0
  31. package/.claude/skills/local-first-skill/SKILL.md +570 -0
  32. package/.claude/skills/mcp-tools/SKILL.md +419 -0
  33. package/.claude/skills/mcp-tools/references/api-endpoints.md +499 -0
  34. package/.claude/skills/mcp-tools/references/data-structures.md +554 -0
  35. package/.claude/skills/mcp-tools/references/implementation-patterns.md +717 -0
  36. package/.claude/skills/preview-insight-skill/SKILL.md +1290 -0
  37. package/.claude/skills/publish-hailer-app-skill/SKILL.md +453 -0
  38. package/.claude/skills/remove-app-member-skill/SKILL.md +671 -0
  39. package/.claude/skills/remove-app-skill/SKILL.md +985 -0
  40. package/.claude/skills/remove-insight-skill/SKILL.md +1011 -0
  41. package/.claude/skills/remove-workflow-skill/SKILL.md +920 -0
  42. package/.claude/skills/scaffold-hailer-app-skill/SKILL.md +1034 -0
  43. package/.claude/skills/skill-testing/README.md +137 -0
  44. package/.claude/skills/skill-testing/SKILL.md +348 -0
  45. package/.claude/skills/skill-testing/references/test-patterns.md +705 -0
  46. package/.claude/skills/skill-testing/references/testing-guide.md +603 -0
  47. package/.claude/skills/skill-testing/references/validation-checklist.md +537 -0
  48. package/.claude/skills/tool-builder/SKILL.md +328 -0
  49. package/.claude/skills/update-app-skill/SKILL.md +970 -0
  50. package/.claude/skills/update-workflow-field-skill/SKILL.md +1098 -0
  51. package/.env.example +81 -0
  52. package/.mcp.json +13 -0
  53. package/README.md +297 -0
  54. package/dist/app.d.ts +4 -0
  55. package/dist/app.js +74 -0
  56. package/dist/cli.d.ts +3 -0
  57. package/dist/cli.js +5 -0
  58. package/dist/client/adaptive-documentation-bot.d.ts +108 -0
  59. package/dist/client/adaptive-documentation-bot.js +475 -0
  60. package/dist/client/adaptive-documentation-types.d.ts +66 -0
  61. package/dist/client/adaptive-documentation-types.js +9 -0
  62. package/dist/client/agent-activity-bot.d.ts +51 -0
  63. package/dist/client/agent-activity-bot.js +166 -0
  64. package/dist/client/agent-tracker.d.ts +499 -0
  65. package/dist/client/agent-tracker.js +659 -0
  66. package/dist/client/description-updater.d.ts +56 -0
  67. package/dist/client/description-updater.js +259 -0
  68. package/dist/client/log-parser.d.ts +72 -0
  69. package/dist/client/log-parser.js +387 -0
  70. package/dist/client/mcp-client.d.ts +50 -0
  71. package/dist/client/mcp-client.js +532 -0
  72. package/dist/client/message-processor.d.ts +35 -0
  73. package/dist/client/message-processor.js +352 -0
  74. package/dist/client/multi-bot-manager.d.ts +24 -0
  75. package/dist/client/multi-bot-manager.js +74 -0
  76. package/dist/client/providers/anthropic-provider.d.ts +19 -0
  77. package/dist/client/providers/anthropic-provider.js +631 -0
  78. package/dist/client/providers/llm-provider.d.ts +47 -0
  79. package/dist/client/providers/llm-provider.js +367 -0
  80. package/dist/client/providers/openai-provider.d.ts +23 -0
  81. package/dist/client/providers/openai-provider.js +621 -0
  82. package/dist/client/simple-llm-caller.d.ts +19 -0
  83. package/dist/client/simple-llm-caller.js +100 -0
  84. package/dist/client/skill-generator.d.ts +81 -0
  85. package/dist/client/skill-generator.js +386 -0
  86. package/dist/client/test-adaptive-bot.d.ts +9 -0
  87. package/dist/client/test-adaptive-bot.js +82 -0
  88. package/dist/client/token-pricing.d.ts +38 -0
  89. package/dist/client/token-pricing.js +127 -0
  90. package/dist/client/token-tracker.d.ts +232 -0
  91. package/dist/client/token-tracker.js +457 -0
  92. package/dist/client/token-usage-bot.d.ts +53 -0
  93. package/dist/client/token-usage-bot.js +153 -0
  94. package/dist/client/tool-executor.d.ts +69 -0
  95. package/dist/client/tool-executor.js +159 -0
  96. package/dist/client/tool-schema-loader.d.ts +60 -0
  97. package/dist/client/tool-schema-loader.js +178 -0
  98. package/dist/client/types.d.ts +69 -0
  99. package/dist/client/types.js +7 -0
  100. package/dist/config.d.ts +162 -0
  101. package/dist/config.js +296 -0
  102. package/dist/core.d.ts +26 -0
  103. package/dist/core.js +147 -0
  104. package/dist/lib/context-manager.d.ts +111 -0
  105. package/dist/lib/context-manager.js +431 -0
  106. package/dist/lib/logger.d.ts +74 -0
  107. package/dist/lib/logger.js +277 -0
  108. package/dist/lib/materialize.d.ts +3 -0
  109. package/dist/lib/materialize.js +101 -0
  110. package/dist/lib/normalizedName.d.ts +7 -0
  111. package/dist/lib/normalizedName.js +48 -0
  112. package/dist/lib/prompt-length-manager.d.ts +81 -0
  113. package/dist/lib/prompt-length-manager.js +457 -0
  114. package/dist/lib/terminal-prompt.d.ts +9 -0
  115. package/dist/lib/terminal-prompt.js +108 -0
  116. package/dist/mcp/UserContextCache.d.ts +56 -0
  117. package/dist/mcp/UserContextCache.js +163 -0
  118. package/dist/mcp/auth.d.ts +2 -0
  119. package/dist/mcp/auth.js +29 -0
  120. package/dist/mcp/hailer-clients.d.ts +42 -0
  121. package/dist/mcp/hailer-clients.js +246 -0
  122. package/dist/mcp/signal-handler.d.ts +45 -0
  123. package/dist/mcp/signal-handler.js +317 -0
  124. package/dist/mcp/tool-registry.d.ts +100 -0
  125. package/dist/mcp/tool-registry.js +306 -0
  126. package/dist/mcp/tools/activity.d.ts +15 -0
  127. package/dist/mcp/tools/activity.js +955 -0
  128. package/dist/mcp/tools/app.d.ts +20 -0
  129. package/dist/mcp/tools/app.js +1488 -0
  130. package/dist/mcp/tools/discussion.d.ts +19 -0
  131. package/dist/mcp/tools/discussion.js +950 -0
  132. package/dist/mcp/tools/file.d.ts +15 -0
  133. package/dist/mcp/tools/file.js +119 -0
  134. package/dist/mcp/tools/insight.d.ts +17 -0
  135. package/dist/mcp/tools/insight.js +806 -0
  136. package/dist/mcp/tools/skill.d.ts +10 -0
  137. package/dist/mcp/tools/skill.js +279 -0
  138. package/dist/mcp/tools/user.d.ts +10 -0
  139. package/dist/mcp/tools/user.js +108 -0
  140. package/dist/mcp/tools/workflow-template.d.ts +19 -0
  141. package/dist/mcp/tools/workflow-template.js +822 -0
  142. package/dist/mcp/tools/workflow.d.ts +18 -0
  143. package/dist/mcp/tools/workflow.js +1362 -0
  144. package/dist/mcp/utils/api-errors.d.ts +45 -0
  145. package/dist/mcp/utils/api-errors.js +160 -0
  146. package/dist/mcp/utils/data-transformers.d.ts +102 -0
  147. package/dist/mcp/utils/data-transformers.js +194 -0
  148. package/dist/mcp/utils/file-upload.d.ts +33 -0
  149. package/dist/mcp/utils/file-upload.js +148 -0
  150. package/dist/mcp/utils/hailer-api-client.d.ts +120 -0
  151. package/dist/mcp/utils/hailer-api-client.js +323 -0
  152. package/dist/mcp/utils/index.d.ts +13 -0
  153. package/dist/mcp/utils/index.js +39 -0
  154. package/dist/mcp/utils/logger.d.ts +42 -0
  155. package/dist/mcp/utils/logger.js +103 -0
  156. package/dist/mcp/utils/types.d.ts +286 -0
  157. package/dist/mcp/utils/types.js +7 -0
  158. package/dist/mcp/workspace-cache.d.ts +42 -0
  159. package/dist/mcp/workspace-cache.js +97 -0
  160. package/dist/mcp-server.d.ts +42 -0
  161. package/dist/mcp-server.js +280 -0
  162. package/package.json +56 -0
  163. package/tsconfig.json +23 -0
@@ -0,0 +1,469 @@
1
+ # Hailer Insights API
2
+
3
+ ## Overview
4
+
5
+ The Insights API provides SQL-based querying capabilities for analyzing data across workspaces, activities, and datasets. Powered by SQLite, it supports complex queries, joins, aggregations, and analytics.
6
+
7
+ ## Key Features
8
+
9
+ - SQLite-compatible SQL syntax
10
+ - Query activities, datasets, and workspace data
11
+ - Aggregations and analytics functions
12
+ - Saved queries for reuse
13
+ - Parameterized queries for security
14
+ - Export results to CSV/JSON/XLSX
15
+
16
+ ## Endpoints
17
+
18
+ ### Execute Query
19
+
20
+ ```http
21
+ POST /v3/insights/query
22
+ Content-Type: application/json
23
+
24
+ {
25
+ "sql": "SELECT * FROM activities WHERE status = 'open'",
26
+ "workspace_id": "ws_123",
27
+ "parameters": {}
28
+ }
29
+ ```
30
+
31
+ **Response:**
32
+ ```json
33
+ {
34
+ "data": [
35
+ {
36
+ "id": "act_123",
37
+ "title": "Task 1",
38
+ "status": "open",
39
+ "created_at": "2025-01-15T10:30:00Z"
40
+ }
41
+ ],
42
+ "meta": {
43
+ "rows": 1,
44
+ "execution_time_ms": 45
45
+ }
46
+ }
47
+ ```
48
+
49
+ ### List Saved Queries
50
+
51
+ ```http
52
+ GET /v3/insights/queries?workspace_id=ws_123
53
+ ```
54
+
55
+ ### Save Query
56
+
57
+ ```http
58
+ POST /v3/insights/queries
59
+ {
60
+ "name": "Open High Priority Tasks",
61
+ "sql": "SELECT * FROM activities WHERE status = 'open' AND priority = 'high'",
62
+ "workspace_id": "ws_123",
63
+ "description": "All open high priority tasks"
64
+ }
65
+ ```
66
+
67
+ ### Execute Saved Query
68
+
69
+ ```http
70
+ POST /v3/insights/queries/{query_id}/execute
71
+ {
72
+ "parameters": {
73
+ "status": "open"
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## Available Tables
79
+
80
+ ### activities Table
81
+
82
+ All activities in the workspace.
83
+
84
+ **Columns:**
85
+ - `id` (text) - Activity ID
86
+ - `title` (text) - Activity title
87
+ - `description` (text) - Activity description
88
+ - `status` (text) - Current status
89
+ - `priority` (text) - Priority level
90
+ - `workspace_id` (text) - Workspace ID
91
+ - `created_at` (datetime) - Creation timestamp
92
+ - `updated_at` (datetime) - Last update timestamp
93
+ - `completed_at` (datetime) - Completion timestamp (null if not completed)
94
+ - `due_date` (datetime) - Due date
95
+ - `created_by` (text) - Creator user ID
96
+ - `assigned_to` (text) - Assigned user ID (first assignee)
97
+ - `parent_id` (text) - Parent activity ID
98
+ - `tags` (text) - Comma-separated tags
99
+
100
+ **Example:**
101
+ ```sql
102
+ SELECT
103
+ status,
104
+ COUNT(*) as count,
105
+ AVG(julianday(completed_at) - julianday(created_at)) as avg_days_to_complete
106
+ FROM activities
107
+ WHERE completed_at IS NOT NULL
108
+ GROUP BY status
109
+ ```
110
+
111
+ ### dataset_{id} Tables
112
+
113
+ Each dataset is accessible as a table with name `dataset_{id}`.
114
+
115
+ **Columns:** Based on dataset field definitions
116
+
117
+ **Example:**
118
+ ```sql
119
+ SELECT
120
+ company_name,
121
+ annual_revenue
122
+ FROM dataset_customers
123
+ WHERE annual_revenue > 1000000
124
+ ORDER BY annual_revenue DESC
125
+ ```
126
+
127
+ ### users Table
128
+
129
+ Workspace users.
130
+
131
+ **Columns:**
132
+ - `id` (text) - User ID
133
+ - `name` (text) - User name
134
+ - `email` (text) - Email address
135
+ - `role` (text) - Workspace role
136
+ - `created_at` (datetime) - Join timestamp
137
+
138
+ **Example:**
139
+ ```sql
140
+ SELECT
141
+ u.name,
142
+ COUNT(a.id) as activity_count
143
+ FROM users u
144
+ LEFT JOIN activities a ON a.assigned_to = u.id
145
+ GROUP BY u.id
146
+ ORDER BY activity_count DESC
147
+ ```
148
+
149
+ ### files Table
150
+
151
+ Uploaded files.
152
+
153
+ **Columns:**
154
+ - `id` (text) - File ID
155
+ - `filename` (text) - Original filename
156
+ - `size` (integer) - File size in bytes
157
+ - `mime_type` (text) - MIME type
158
+ - `activity_id` (text) - Associated activity
159
+ - `workspace_id` (text) - Workspace ID
160
+ - `created_at` (datetime) - Upload timestamp
161
+ - `created_by` (text) - Uploader user ID
162
+
163
+ ### comments Table
164
+
165
+ Activity comments.
166
+
167
+ **Columns:**
168
+ - `id` (text) - Comment ID
169
+ - `activity_id` (text) - Activity ID
170
+ - `text` (text) - Comment text
171
+ - `created_at` (datetime) - Creation timestamp
172
+ - `created_by` (text) - Author user ID
173
+
174
+ ### time_entries Table
175
+
176
+ Time tracking entries.
177
+
178
+ **Columns:**
179
+ - `id` (text) - Entry ID
180
+ - `activity_id` (text) - Activity ID
181
+ - `user_id` (text) - User who logged time
182
+ - `hours` (real) - Hours logged
183
+ - `description` (text) - Entry description
184
+ - `date` (date) - Entry date
185
+ - `created_at` (datetime) - Creation timestamp
186
+
187
+ ## SQL Capabilities
188
+
189
+ ### Basic Queries
190
+
191
+ ```sql
192
+ -- Select all open activities
193
+ SELECT * FROM activities WHERE status = 'open';
194
+
195
+ -- Count activities by status
196
+ SELECT status, COUNT(*) as count
197
+ FROM activities
198
+ GROUP BY status;
199
+
200
+ -- Activities due this week
201
+ SELECT title, due_date
202
+ FROM activities
203
+ WHERE due_date BETWEEN datetime('now') AND datetime('now', '+7 days');
204
+ ```
205
+
206
+ ### Joins
207
+
208
+ ```sql
209
+ -- Activities with creator names
210
+ SELECT
211
+ a.title,
212
+ a.status,
213
+ u.name as creator
214
+ FROM activities a
215
+ JOIN users u ON a.created_by = u.id
216
+ WHERE a.status = 'open';
217
+
218
+ -- Activities with file counts
219
+ SELECT
220
+ a.id,
221
+ a.title,
222
+ COUNT(f.id) as file_count
223
+ FROM activities a
224
+ LEFT JOIN files f ON f.activity_id = a.id
225
+ GROUP BY a.id;
226
+ ```
227
+
228
+ ### Aggregations
229
+
230
+ ```sql
231
+ -- Average completion time by priority
232
+ SELECT
233
+ priority,
234
+ AVG(julianday(completed_at) - julianday(created_at)) as avg_days,
235
+ COUNT(*) as count
236
+ FROM activities
237
+ WHERE completed_at IS NOT NULL
238
+ GROUP BY priority;
239
+
240
+ -- Total time logged per activity
241
+ SELECT
242
+ a.title,
243
+ SUM(t.hours) as total_hours
244
+ FROM activities a
245
+ LEFT JOIN time_entries t ON t.activity_id = a.id
246
+ GROUP BY a.id;
247
+ ```
248
+
249
+ ### Window Functions
250
+
251
+ ```sql
252
+ -- Rank users by activity completion rate
253
+ SELECT
254
+ name,
255
+ completed,
256
+ total,
257
+ RANK() OVER (ORDER BY completed * 1.0 / total DESC) as rank
258
+ FROM (
259
+ SELECT
260
+ u.name,
261
+ SUM(CASE WHEN a.status = 'completed' THEN 1 ELSE 0 END) as completed,
262
+ COUNT(*) as total
263
+ FROM users u
264
+ LEFT JOIN activities a ON a.assigned_to = u.id
265
+ GROUP BY u.id
266
+ );
267
+ ```
268
+
269
+ ### Common Table Expressions (CTEs)
270
+
271
+ ```sql
272
+ WITH monthly_stats AS (
273
+ SELECT
274
+ STRFTIME('%Y-%m', created_at) as month,
275
+ COUNT(*) as created,
276
+ SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed
277
+ FROM activities
278
+ WHERE created_at >= datetime('now', '-12 months')
279
+ GROUP BY month
280
+ )
281
+ SELECT
282
+ month,
283
+ created,
284
+ completed,
285
+ completed * 100.0 / created as completion_rate
286
+ FROM monthly_stats
287
+ ORDER BY month DESC;
288
+ ```
289
+
290
+ ## Date Functions
291
+
292
+ ### SQLite Date Functions
293
+
294
+ ```sql
295
+ -- Current date/time
296
+ SELECT datetime('now');
297
+ SELECT date('now');
298
+
299
+ -- Date arithmetic
300
+ SELECT datetime('now', '+7 days');
301
+ SELECT datetime('now', '-1 month');
302
+ SELECT datetime('now', 'start of month');
303
+
304
+ -- Format dates
305
+ SELECT STRFTIME('%Y-%m-%d', created_at) as date
306
+ FROM activities;
307
+
308
+ -- Extract components
309
+ SELECT
310
+ STRFTIME('%Y', created_at) as year,
311
+ STRFTIME('%m', created_at) as month,
312
+ STRFTIME('%d', created_at) as day,
313
+ STRFTIME('%H', created_at) as hour
314
+ FROM activities;
315
+
316
+ -- Calculate differences
317
+ SELECT
318
+ title,
319
+ julianday(completed_at) - julianday(created_at) as days_to_complete
320
+ FROM activities
321
+ WHERE completed_at IS NOT NULL;
322
+ ```
323
+
324
+ ## Parameterized Queries
325
+
326
+ Use parameters for security and reusability:
327
+
328
+ ```http
329
+ POST /v3/insights/query
330
+ {
331
+ "sql": "SELECT * FROM activities WHERE status = :status AND priority = :priority",
332
+ "workspace_id": "ws_123",
333
+ "parameters": {
334
+ "status": "open",
335
+ "priority": "high"
336
+ }
337
+ }
338
+ ```
339
+
340
+ ## Query Limits
341
+
342
+ - Maximum execution time: 30 seconds
343
+ - Maximum result rows: 10,000 (use LIMIT for pagination)
344
+ - Maximum query length: 100,000 characters
345
+
346
+ ## Example Queries
347
+
348
+ ### Activity Analytics
349
+
350
+ ```sql
351
+ -- Overdue activities
352
+ SELECT
353
+ id,
354
+ title,
355
+ assigned_to,
356
+ due_date,
357
+ julianday('now') - julianday(due_date) as days_overdue
358
+ FROM activities
359
+ WHERE due_date < datetime('now')
360
+ AND status NOT IN ('completed', 'cancelled')
361
+ ORDER BY days_overdue DESC;
362
+ ```
363
+
364
+ ```sql
365
+ -- Activities created vs completed by month
366
+ SELECT
367
+ STRFTIME('%Y-%m', created_at) as month,
368
+ COUNT(*) as created,
369
+ SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed
370
+ FROM activities
371
+ GROUP BY month
372
+ ORDER BY month DESC
373
+ LIMIT 12;
374
+ ```
375
+
376
+ ### User Performance
377
+
378
+ ```sql
379
+ -- User workload and completion rate
380
+ SELECT
381
+ u.name,
382
+ COUNT(a.id) as total_activities,
383
+ SUM(CASE WHEN a.status = 'completed' THEN 1 ELSE 0 END) as completed,
384
+ SUM(CASE WHEN a.status IN ('open', 'in_progress') THEN 1 ELSE 0 END) as active,
385
+ ROUND(100.0 * SUM(CASE WHEN a.status = 'completed' THEN 1 ELSE 0 END) / COUNT(a.id), 2) as completion_rate
386
+ FROM users u
387
+ LEFT JOIN activities a ON a.assigned_to = u.id
388
+ WHERE u.role IN ('member', 'admin')
389
+ GROUP BY u.id
390
+ ORDER BY completion_rate DESC;
391
+ ```
392
+
393
+ ### Time Tracking
394
+
395
+ ```sql
396
+ -- Time logged per user this month
397
+ SELECT
398
+ u.name,
399
+ SUM(t.hours) as total_hours,
400
+ COUNT(DISTINCT t.activity_id) as activities_worked
401
+ FROM users u
402
+ LEFT JOIN time_entries t ON t.user_id = u.id
403
+ WHERE t.date >= date('now', 'start of month')
404
+ GROUP BY u.id
405
+ ORDER BY total_hours DESC;
406
+ ```
407
+
408
+ ### Dataset Analysis
409
+
410
+ ```sql
411
+ -- Join dataset with activities
412
+ SELECT
413
+ c.company_name,
414
+ c.annual_revenue,
415
+ COUNT(a.id) as related_activities
416
+ FROM dataset_customers c
417
+ LEFT JOIN activities a ON a.custom_fields LIKE '%' || c.company_name || '%'
418
+ GROUP BY c.id
419
+ ORDER BY related_activities DESC;
420
+ ```
421
+
422
+ ## Export Results
423
+
424
+ ### Export as CSV
425
+
426
+ ```http
427
+ POST /v3/insights/query
428
+ {
429
+ "sql": "SELECT * FROM activities WHERE status = 'completed'",
430
+ "workspace_id": "ws_123",
431
+ "format": "csv"
432
+ }
433
+ ```
434
+
435
+ Response will be CSV file download.
436
+
437
+ ### Export as Excel
438
+
439
+ ```http
440
+ POST /v3/insights/query
441
+ {
442
+ "sql": "SELECT * FROM activities WHERE status = 'completed'",
443
+ "workspace_id": "ws_123",
444
+ "format": "xlsx"
445
+ }
446
+ ```
447
+
448
+ ## Best Practices
449
+
450
+ 1. **Use LIMIT for large result sets** - Prevents timeouts
451
+ 2. **Add WHERE clauses** - Filter at database level for performance
452
+ 3. **Use indexes** - On frequently queried fields (created via dataset configuration)
453
+ 4. **Parameterize queries** - Prevents SQL injection
454
+ 5. **Test queries** - Verify on small datasets first
455
+ 6. **Use CTEs for readability** - Break complex queries into steps
456
+ 7. **Monitor execution time** - Optimize slow queries
457
+ 8. **Cache frequently used results** - Store in datasets or client-side
458
+ 9. **Use appropriate date functions** - SQLite date functions for date math
459
+ 10. **Document saved queries** - Add descriptions for team understanding
460
+
461
+ ## Query Optimization Tips
462
+
463
+ - Use `EXPLAIN QUERY PLAN` to understand query execution
464
+ - Add indexes on JOIN and WHERE columns
465
+ - Limit result sets with appropriate WHERE clauses
466
+ - Use EXISTS instead of IN for subqueries
467
+ - Avoid SELECT * - specify needed columns
468
+ - Use appropriate JOINs (INNER vs LEFT)
469
+ - Pre-aggregate data in datasets when possible