@quarri/claude-data-tools 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,274 @@
1
+ ---
2
+ description: Run complete data analysis pipeline orchestrating query, insights, and charts
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # /quarri-analyze - Full Analysis Pipeline
8
+
9
+ Orchestrate a complete data analysis pipeline by coordinating query generation, statistical analysis, business insights, and visualization.
10
+
11
+ ## When to Use
12
+
13
+ Use `/quarri-analyze` when users want comprehensive analysis:
14
+ - "Analyze our sales trends"
15
+ - "What's driving customer churn?"
16
+ - "Give me insights on revenue performance"
17
+ - "Help me understand our order patterns"
18
+
19
+ This is more powerful than `/quarri-query` as it provides statistics, visualizations, and actionable insights.
20
+
21
+ ## Orchestration Flow
22
+
23
+ ```
24
+ /quarri-analyze
25
+
26
+ ├── 1. /quarri-query
27
+ │ └── Generate SQL, fetch schema, execute query
28
+
29
+ ├── 2. /quarri-insights
30
+ │ └── Statistical analysis + business interpretation
31
+
32
+ └── 3. /quarri-chart (if visualization warranted)
33
+ └── Chart recommendation + configuration
34
+ ```
35
+
36
+ ### Stage 1: Query (via /quarri-query)
37
+
38
+ Generate and execute SQL for the analysis question:
39
+ 1. Fetch schema using `quarri_get_schema`
40
+ 2. Search for relevant metrics using `quarri_search_metrics`
41
+ 3. Generate SQL following star schema patterns
42
+ 4. Execute using `quarri_execute_sql`
43
+
44
+ ### Stage 2: Insights (via /quarri-insights)
45
+
46
+ Analyze the query results:
47
+ - Descriptive statistics for numeric columns
48
+ - Distribution and outlier analysis
49
+ - Correlation between variables
50
+ - Time series trends if applicable
51
+ - Business interpretation and recommendations
52
+
53
+ ### Stage 3: Chart (via /quarri-chart)
54
+
55
+ If data warrants visualization:
56
+ - Apply chart decision tree
57
+ - Generate appropriate chart configuration
58
+ - Recommend alternatives if applicable
59
+
60
+ ## MECE Framework for Complex Analysis
61
+
62
+ When analyzing complex business questions, structure the breakdown using the MECE principle:
63
+ - **Mutually Exclusive**: Categories don't overlap
64
+ - **Collectively Exhaustive**: All possibilities covered
65
+
66
+ ### MECE Application Examples
67
+
68
+ #### Revenue Analysis
69
+ "Why is revenue changing?"
70
+ ```
71
+ Revenue Drivers (MECE Breakdown)
72
+ ├── Volume Drivers
73
+ │ ├── Customer count
74
+ │ ├── Order frequency per customer
75
+ │ └── Units per order
76
+ ├── Price Drivers
77
+ │ ├── Unit price
78
+ │ ├── Product mix shift
79
+ │ └── Discount rates
80
+ └── External Factors
81
+ ├── Seasonality
82
+ ├── Market conditions
83
+ └── Competition
84
+ ```
85
+
86
+ #### Customer Churn Analysis
87
+ "What's causing churn?"
88
+ ```
89
+ Churn Factors (MECE Breakdown)
90
+ ├── Product Issues
91
+ │ ├── Quality problems
92
+ │ ├── Feature gaps
93
+ │ └── Performance issues
94
+ ├── Service Issues
95
+ │ ├── Support quality
96
+ │ ├── Response time
97
+ │ └── Resolution rate
98
+ ├── Price Issues
99
+ │ ├── Absolute cost
100
+ │ ├── Perceived value
101
+ │ └── Competitor pricing
102
+ └── External Factors
103
+ ├── Business closure
104
+ ├── Changed needs
105
+ └── Market exit
106
+ ```
107
+
108
+ #### Sales Performance
109
+ "Why are sales underperforming?"
110
+ ```
111
+ Sales Performance (MECE Breakdown)
112
+ ├── Lead Generation
113
+ │ ├── Marketing qualified leads
114
+ │ ├── Inbound inquiries
115
+ │ └── Outbound prospecting
116
+ ├── Conversion Rate
117
+ │ ├── Lead to opportunity
118
+ │ ├── Opportunity to proposal
119
+ │ └── Proposal to close
120
+ └── Deal Size
121
+ ├── Initial contract value
122
+ ├── Upsell/cross-sell
123
+ └── Discounting
124
+ ```
125
+
126
+ ### When to Apply MECE
127
+
128
+ Apply MECE structuring when:
129
+ 1. Question involves "why" (root cause analysis)
130
+ 2. Multiple factors could explain the outcome
131
+ 3. User needs comprehensive coverage
132
+ 4. Decision-making requires evaluating alternatives
133
+
134
+ For simple queries ("show revenue by region"), skip MECE and provide direct analysis.
135
+
136
+ ## Workflow
137
+
138
+ ```
139
+ 1. Parse the analysis question
140
+ - Identify primary metric/measure
141
+ - Identify dimensions/breakdowns
142
+ - Determine time scope
143
+
144
+ 2. Execute /quarri-query
145
+ - Generate appropriate SQL
146
+ - Execute and retrieve data
147
+ - Validate results
148
+
149
+ 3. Execute /quarri-insights
150
+ - Run statistical analysis
151
+ - Identify patterns
152
+ - Generate business insights
153
+
154
+ 4. Determine if visualization needed
155
+ - Data has clear visual pattern?
156
+ - More than 3 data points?
157
+ - User explicitly requested chart?
158
+
159
+ 5. If yes, execute /quarri-chart
160
+ - Select appropriate chart type
161
+ - Generate configuration
162
+
163
+ 6. Synthesize comprehensive report
164
+ - Combine all findings
165
+ - Apply MECE structure if complex question
166
+ - Prioritize actionable recommendations
167
+ ```
168
+
169
+ ## Output Format
170
+
171
+ ```markdown
172
+ ## Analysis: [Question Summary]
173
+
174
+ ### Query
175
+ ```sql
176
+ [SQL generated by /quarri-query]
177
+ ```
178
+ [Brief explanation of what the query retrieves]
179
+
180
+ ### Data Summary
181
+ - **Rows**: [count]
182
+ - **Date range**: [range]
183
+ - **Key dimensions**: [list]
184
+
185
+ ### Statistical Findings
186
+ [From /quarri-insights]
187
+ - [Key statistic 1]
188
+ - [Key statistic 2]
189
+ - [Key statistic 3]
190
+
191
+ ### MECE Breakdown (if applicable)
192
+ [Structured analysis of drivers/factors]
193
+
194
+ ### Business Insights
195
+
196
+ #### Key Finding
197
+ **[Most important takeaway with specific numbers]**
198
+
199
+ #### Additional Insights
200
+ 1. **[Insight type]**: [Specific finding]
201
+ - Implication: [What it means]
202
+ - Action: [What to do]
203
+
204
+ 2. **[Insight type]**: [Specific finding]
205
+ - Implication: [What it means]
206
+ - Action: [What to do]
207
+
208
+ ### Visualization
209
+ [From /quarri-chart if applicable]
210
+ [Chart type recommendation with rationale]
211
+ [Configuration or URL]
212
+
213
+ ### Recommended Next Steps
214
+ 1. [Immediate action]
215
+ 2. [Follow-up analysis]
216
+ 3. [Deeper investigation if warranted]
217
+ ```
218
+
219
+ ## Example: Full Analysis
220
+
221
+ **User**: "Analyze why revenue dropped last month"
222
+
223
+ **Analysis Output**:
224
+
225
+ ### Query
226
+ ```sql
227
+ SELECT
228
+ DATE_TRUNC('week', order_date) as week,
229
+ product_category,
230
+ COUNT(*) as order_count,
231
+ COUNT(DISTINCT customer_id) as customers,
232
+ SUM(revenue) as revenue,
233
+ AVG(order_value) as avg_order_value
234
+ FROM quarri.bridge
235
+ WHERE order_date >= DATE '2024-11-01'
236
+ GROUP BY week, product_category
237
+ ORDER BY week, product_category
238
+ ```
239
+
240
+ ### MECE Breakdown: Revenue Decline Drivers
241
+
242
+ ```
243
+ Revenue = Customers × Orders/Customer × Revenue/Order
244
+
245
+ Analysis by Driver:
246
+ ├── Customer Count: -8% (from 1,245 to 1,146)
247
+ │ └── PRIMARY DRIVER: New customer acquisition dropped
248
+ ├── Order Frequency: -2% (from 2.3 to 2.25 orders/customer)
249
+ │ └── Minor decline, within normal range
250
+ └── Revenue per Order: +1% (from $89 to $90)
251
+ └── Stable, slight increase
252
+ ```
253
+
254
+ ### Key Finding
255
+ **Customer acquisition dropped 8%, accounting for 75% of the revenue decline. New customer count fell from 312 to 198 (-37%).**
256
+
257
+ ### Recommended Actions
258
+ 1. **Immediate**: Review marketing spend and campaign performance from last month
259
+ 2. **This week**: Analyze acquisition channel performance (paid vs organic)
260
+ 3. **Follow-up**: Compare conversion rates by channel to identify where leads are dropping
261
+
262
+ ## Error Handling
263
+
264
+ - If query returns no data, suggest adjusting filters or date range
265
+ - If statistical analysis fails, report data quality issues
266
+ - If MECE breakdown unclear, ask clarifying questions
267
+ - Always provide partial results if some stages succeed
268
+
269
+ ## Integration
270
+
271
+ This skill orchestrates:
272
+ - `/quarri-query` for data retrieval
273
+ - `/quarri-insights` for statistical analysis and business interpretation
274
+ - `/quarri-chart` for visualization recommendations
@@ -0,0 +1,415 @@
1
+ ---
2
+ description: Generate charts in multiple formats - QuickChart URLs, matplotlib, or ASCII
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # /quarri-chart - Flexible Chart Generation
8
+
9
+ Generate data visualizations in multiple formats optimized for Claude Code users.
10
+
11
+ ## When to Use
12
+
13
+ Use `/quarri-chart` when users want visualizations:
14
+ - "Create a chart of revenue by month"
15
+ - "Visualize customer distribution"
16
+ - "Show me a graph of this data"
17
+ - "What's the best way to display these results?"
18
+
19
+ ## Output Formats
20
+
21
+ ### 1. QuickChart URL (DEFAULT)
22
+
23
+ Generate a URL that renders instantly in any browser or terminal with image support.
24
+
25
+ **When to use**: Quick visualization, sharing, embedding in documents
26
+
27
+ ```
28
+ https://quickchart.io/chart?c={encoded_config}
29
+ ```
30
+
31
+ **Example**:
32
+ ```
33
+ https://quickchart.io/chart?c={type:'bar',data:{labels:['Q1','Q2','Q3','Q4'],datasets:[{label:'Revenue',data:[120,150,180,200]}]}}
34
+ ```
35
+
36
+ ### 2. Matplotlib Code
37
+
38
+ Generate Python code that creates and saves chart images.
39
+
40
+ **When to use**: Custom styling, publication-quality charts, local files
41
+
42
+ ```python
43
+ import matplotlib.pyplot as plt
44
+ import pandas as pd
45
+
46
+ # Data
47
+ categories = ['Q1', 'Q2', 'Q3', 'Q4']
48
+ values = [120, 150, 180, 200]
49
+
50
+ # Create figure
51
+ fig, ax = plt.subplots(figsize=(10, 6))
52
+ ax.bar(categories, values, color='#4F46E5')
53
+
54
+ # Styling
55
+ ax.set_xlabel('Quarter')
56
+ ax.set_ylabel('Revenue ($K)')
57
+ ax.set_title('Quarterly Revenue')
58
+ ax.spines['top'].set_visible(False)
59
+ ax.spines['right'].set_visible(False)
60
+
61
+ # Save
62
+ plt.tight_layout()
63
+ plt.savefig('revenue_chart.png', dpi=150)
64
+ plt.show()
65
+ ```
66
+
67
+ ### 3. ASCII Chart
68
+
69
+ Terminal-friendly text visualization for quick inspection.
70
+
71
+ **When to use**: Terminal environments, quick data review, no graphics support
72
+
73
+ ```
74
+ Revenue by Quarter
75
+
76
+ Q1 |████████████ | $120K
77
+ Q2 |███████████████ | $150K
78
+ Q3 |██████████████████ | $180K
79
+ Q4 |████████████████████ | $200K
80
+ 0 100 200
81
+ ```
82
+
83
+ ## Chart Selection Logic
84
+
85
+ ### Decision Tree
86
+
87
+ ```
88
+ START: What is the primary analysis goal?
89
+
90
+ 1. TRENDS OVER TIME?
91
+ └─→ Single series? → LINE CHART
92
+ └─→ Multiple series? → MULTI-LINE
93
+ └─→ Cumulative? → AREA CHART
94
+
95
+ 2. COMPARING CATEGORIES?
96
+ └─→ 2-7 categories → VERTICAL BAR
97
+ └─→ 8-15 categories → HORIZONTAL BAR
98
+ └─→ 15+ categories → TOP N + "Other"
99
+ └─→ Multiple dimensions → GROUPED BAR
100
+
101
+ 3. SHOWING DISTRIBUTION?
102
+ └─→ Continuous data → HISTOGRAM
103
+ └─→ Categorical → BAR (sorted)
104
+ └─→ Compare groups → BOX PLOT
105
+
106
+ 4. PARTS OF A WHOLE?
107
+ └─→ 2-6 parts → PIE/DONUT
108
+ └─→ 7+ parts → STACKED BAR (100%)
109
+
110
+ 5. RELATIONSHIP BETWEEN VARIABLES?
111
+ └─→ Two numeric → SCATTER PLOT
112
+ └─→ With grouping → SCATTER with colors
113
+
114
+ DEFAULT: TABLE (when visualization unclear)
115
+ ```
116
+
117
+ ## QuickChart Configuration
118
+
119
+ ### Bar Chart
120
+ ```javascript
121
+ {
122
+ type: 'bar',
123
+ data: {
124
+ labels: ['A', 'B', 'C'],
125
+ datasets: [{
126
+ label: 'Values',
127
+ data: [10, 20, 15],
128
+ backgroundColor: '#4F46E5'
129
+ }]
130
+ },
131
+ options: {
132
+ title: { display: true, text: 'Chart Title' },
133
+ legend: { display: false }
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### Line Chart
139
+ ```javascript
140
+ {
141
+ type: 'line',
142
+ data: {
143
+ labels: ['Jan', 'Feb', 'Mar', 'Apr'],
144
+ datasets: [{
145
+ label: 'Revenue',
146
+ data: [100, 120, 115, 140],
147
+ borderColor: '#4F46E5',
148
+ fill: false
149
+ }]
150
+ }
151
+ }
152
+ ```
153
+
154
+ ### Horizontal Bar
155
+ ```javascript
156
+ {
157
+ type: 'horizontalBar',
158
+ data: {
159
+ labels: ['Product A', 'Product B', 'Product C'],
160
+ datasets: [{
161
+ data: [300, 250, 200],
162
+ backgroundColor: ['#4F46E5', '#10B981', '#F59E0B']
163
+ }]
164
+ }
165
+ }
166
+ ```
167
+
168
+ ### Pie/Donut Chart
169
+ ```javascript
170
+ {
171
+ type: 'doughnut',
172
+ data: {
173
+ labels: ['Desktop', 'Mobile', 'Tablet'],
174
+ datasets: [{
175
+ data: [60, 30, 10],
176
+ backgroundColor: ['#4F46E5', '#10B981', '#F59E0B']
177
+ }]
178
+ }
179
+ }
180
+ ```
181
+
182
+ ### Scatter Plot
183
+ ```javascript
184
+ {
185
+ type: 'scatter',
186
+ data: {
187
+ datasets: [{
188
+ label: 'Data Points',
189
+ data: [{x: 1, y: 2}, {x: 2, y: 4}, {x: 3, y: 3}],
190
+ backgroundColor: '#4F46E5'
191
+ }]
192
+ }
193
+ }
194
+ ```
195
+
196
+ ## Matplotlib Templates
197
+
198
+ ### Bar Chart
199
+ ```python
200
+ import matplotlib.pyplot as plt
201
+
202
+ fig, ax = plt.subplots(figsize=(10, 6))
203
+ categories = ['A', 'B', 'C', 'D']
204
+ values = [25, 40, 30, 35]
205
+
206
+ bars = ax.bar(categories, values, color='#4F46E5', edgecolor='white')
207
+ ax.bar_label(bars, fmt='%.0f')
208
+
209
+ ax.set_ylabel('Value')
210
+ ax.set_title('Category Comparison')
211
+ ax.spines['top'].set_visible(False)
212
+ ax.spines['right'].set_visible(False)
213
+
214
+ plt.tight_layout()
215
+ plt.savefig('bar_chart.png', dpi=150)
216
+ ```
217
+
218
+ ### Line Chart
219
+ ```python
220
+ import matplotlib.pyplot as plt
221
+ import matplotlib.dates as mdates
222
+
223
+ fig, ax = plt.subplots(figsize=(12, 6))
224
+ dates = ['2024-01', '2024-02', '2024-03', '2024-04']
225
+ values = [100, 120, 115, 140]
226
+
227
+ ax.plot(dates, values, marker='o', color='#4F46E5', linewidth=2, markersize=8)
228
+ ax.fill_between(dates, values, alpha=0.1, color='#4F46E5')
229
+
230
+ ax.set_ylabel('Revenue ($K)')
231
+ ax.set_title('Monthly Revenue Trend')
232
+ ax.grid(True, alpha=0.3)
233
+ ax.spines['top'].set_visible(False)
234
+ ax.spines['right'].set_visible(False)
235
+
236
+ plt.tight_layout()
237
+ plt.savefig('line_chart.png', dpi=150)
238
+ ```
239
+
240
+ ### Horizontal Bar (for many categories)
241
+ ```python
242
+ import matplotlib.pyplot as plt
243
+
244
+ fig, ax = plt.subplots(figsize=(10, 8))
245
+ categories = ['Product A', 'Product B', 'Product C', 'Product D', 'Product E']
246
+ values = [45, 38, 32, 28, 22]
247
+
248
+ bars = ax.barh(categories, values, color='#4F46E5')
249
+ ax.bar_label(bars, fmt='%.0f', padding=5)
250
+
251
+ ax.set_xlabel('Sales ($K)')
252
+ ax.set_title('Top Products by Sales')
253
+ ax.invert_yaxis() # Largest at top
254
+ ax.spines['top'].set_visible(False)
255
+ ax.spines['right'].set_visible(False)
256
+
257
+ plt.tight_layout()
258
+ plt.savefig('horizontal_bar.png', dpi=150)
259
+ ```
260
+
261
+ ## ASCII Chart Generation
262
+
263
+ ### Horizontal Bar (ASCII)
264
+ ```
265
+ def ascii_bar_chart(data, title, max_width=40):
266
+ """Generate ASCII horizontal bar chart"""
267
+ print(f"\n{title}\n")
268
+ max_val = max(data.values())
269
+
270
+ for label, value in data.items():
271
+ bar_len = int((value / max_val) * max_width)
272
+ bar = '█' * bar_len
273
+ print(f"{label:>15} |{bar} {value:,.0f}")
274
+
275
+ print(f"{'':>15} {'─' * max_width}")
276
+
277
+ # Example
278
+ data = {'Electronics': 45000, 'Clothing': 32000, 'Home': 28000}
279
+ ascii_bar_chart(data, "Revenue by Category")
280
+ ```
281
+
282
+ **Output:**
283
+ ```
284
+ Revenue by Category
285
+
286
+ Electronics |████████████████████████████████████████ 45,000
287
+ Clothing |████████████████████████████ 32,000
288
+ Home |████████████████████████ 28,000
289
+ ────────────────────────────────────────
290
+ ```
291
+
292
+ ### Vertical Bar (ASCII)
293
+ ```
294
+ def ascii_vertical_bar(data, title, height=10):
295
+ """Generate ASCII vertical bar chart"""
296
+ print(f"\n{title}\n")
297
+ max_val = max(data.values())
298
+
299
+ for row in range(height, 0, -1):
300
+ line = ""
301
+ for value in data.values():
302
+ threshold = (row / height) * max_val
303
+ line += " █ " if value >= threshold else " "
304
+ print(f"{int(max_val * row / height):>6} |{line}")
305
+
306
+ print(f"{'':>6} +{'─────' * len(data)}")
307
+ labels = "".join(f"{k:^5}" for k in data.keys())
308
+ print(f"{'':>8}{labels}")
309
+
310
+ # Example
311
+ data = {'Q1': 120, 'Q2': 150, 'Q3': 180, 'Q4': 200}
312
+ ascii_vertical_bar(data, "Quarterly Revenue")
313
+ ```
314
+
315
+ ### Sparkline (ASCII)
316
+ ```
317
+ def ascii_sparkline(values, width=30):
318
+ """Generate inline ASCII sparkline"""
319
+ chars = '▁▂▃▄▅▆▇█'
320
+ min_val, max_val = min(values), max(values)
321
+ range_val = max_val - min_val or 1
322
+
323
+ line = ""
324
+ for v in values:
325
+ idx = int((v - min_val) / range_val * (len(chars) - 1))
326
+ line += chars[idx]
327
+
328
+ return f"[{line}] {values[0]:,.0f} → {values[-1]:,.0f}"
329
+
330
+ # Example
331
+ monthly = [100, 105, 98, 112, 120, 118, 125, 130, 128, 140, 145, 155]
332
+ print(f"Revenue trend: {ascii_sparkline(monthly)}")
333
+ # Output: Revenue trend: [▁▂▁▃▄▄▅▆▅▇▇█] 100 → 155
334
+ ```
335
+
336
+ ## Workflow
337
+
338
+ 1. **Analyze data shape**:
339
+ - Count rows and columns
340
+ - Identify column types (numeric, categorical, date)
341
+ - Check value distributions
342
+
343
+ 2. **Determine visualization goal**:
344
+ - Parse user question for intent
345
+ - Consider data characteristics
346
+
347
+ 3. **Select chart type**:
348
+ - Apply decision tree
349
+ - Consider data density and readability
350
+
351
+ 4. **Choose output format**:
352
+ - Default: QuickChart URL (instant rendering)
353
+ - If user needs customization: matplotlib code
354
+ - If terminal-only: ASCII chart
355
+
356
+ 5. **Generate and present**:
357
+ - Show chart or URL
358
+ - Include rationale
359
+ - Suggest alternatives
360
+
361
+ ## Output Format
362
+
363
+ ```markdown
364
+ ## Visualization: [Data Description]
365
+
366
+ ### Analysis
367
+ - Data: [rows] rows, [columns] columns
368
+ - Question type: [trend/comparison/distribution/etc.]
369
+ - Key columns: [list]
370
+
371
+ ### Recommended Chart: [Type]
372
+ **Why**: [Brief rationale]
373
+
374
+ ### Chart
375
+
376
+ **QuickChart URL** (click to view):
377
+ [URL]
378
+
379
+ **Alternative: Matplotlib Code**
380
+ ```python
381
+ [Code block]
382
+ ```
383
+
384
+ **Alternative: ASCII Preview**
385
+ ```
386
+ [ASCII chart]
387
+ ```
388
+
389
+ ### Alternatives
390
+ - [Alternative chart 1]: [When it might be better]
391
+ - [Alternative chart 2]: [When it might be better]
392
+ ```
393
+
394
+ ## Color Palettes
395
+
396
+ ```python
397
+ # Primary palette
398
+ PRIMARY = '#4F46E5' # Indigo
399
+
400
+ # Categorical (multiple series)
401
+ CATEGORICAL = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899']
402
+
403
+ # Sequential (single metric, gradient)
404
+ SEQUENTIAL = ['#E0E7FF', '#A5B4FC', '#818CF8', '#6366F1', '#4F46E5']
405
+
406
+ # Diverging (positive/negative)
407
+ DIVERGING = ['#EF4444', '#FCA5A5', '#E5E7EB', '#86EFAC', '#22C55E']
408
+ ```
409
+
410
+ ## Integration
411
+
412
+ Charts work best when combined with:
413
+ - `/quarri-query`: Get data first, then visualize
414
+ - `/quarri-analyze`: Called as part of full analysis pipeline
415
+ - `/quarri-insights`: Visual support for statistical findings