vortexa-claude-skills 1.0.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,315 @@
1
+ ---
2
+ name: vortexa:compare
3
+ description: "Compare cargo flows period-over-period or region-over-region with overlay charts and metrics"
4
+ argument-hint: "compare crude exports from Saudi Arabia 2025 vs 2024, monthly"
5
+ allowed-tools:
6
+ - Read
7
+ - Edit
8
+ - Write
9
+ - Bash
10
+ - Glob
11
+ - Grep
12
+ ---
13
+
14
+ <objective>
15
+ Run comparison analytics on cargo flows -- either period-over-period (e.g., 2025 vs 2024) or region-over-region (e.g., Europe vs Asia imports). Produces overlay line charts with computed metrics (absolute change, percentage change, averages, totals). Uses CargoTimeSeries for data and `comparison_overlay_chart()` from lib/visualization.py.
16
+ </objective>
17
+
18
+ <execution_context>
19
+ ## Pre-loaded Context (via CLAUDE.md @imports)
20
+ The following are automatically available -- do NOT re-read them:
21
+ - context/guardrails.md -- NEVER/ALWAYS rules for all Vortexa API calls
22
+ - context/entity-resolution.md -- How to resolve entity names to hex IDs
23
+ - context/date-units.md -- Date parsing rules and unit defaults
24
+
25
+ ## Required Context (Read on demand)
26
+ Read before processing the user's query:
27
+ - context/cargo-movements.md -- Full CTS parameters, activity filters, timeseries_property values
28
+ </execution_context>
29
+
30
+ ## Setup Check
31
+ @commands/vortexa/_check-setup.md
32
+
33
+ <process>
34
+
35
+ ## Step 1: Read Endpoint Context
36
+
37
+ Read `context/cargo-movements.md` for CTS parameters, activity filter rules, and frequency options.
38
+
39
+ ## Step 2: Parse the Query and Determine Mode
40
+
41
+ Analyze $ARGUMENTS using signal word routing to determine the comparison mode:
42
+
43
+ ### Signal Word Routing
44
+
45
+ **Period mode** -- year or time-based comparison:
46
+ - Year references: 2025, 2024, "last year", "this year", "vs 2023"
47
+ - Explicit period phrases: "year over year", "YoY", "month over month", "MoM", "QoQ", "quarter over quarter"
48
+ - Multiple date ranges: "Q1 2025 vs Q1 2024", "Jan-Jun 2025 vs Jan-Jun 2024"
49
+
50
+ **Region mode** -- geographic comparison:
51
+ - Geographic references used as comparison items: "Europe vs Asia", "Middle East vs West Africa"
52
+ - Multiple origins or destinations being compared: "Saudi vs Iraq exports", "China vs India imports"
53
+
54
+ **Both present** -- ambiguous, ask:
55
+ "I see both year and region references. Are you comparing time periods or geographies?"
56
+
57
+ **Neither clear** -- ask:
58
+ "What would you like to compare? Time periods (e.g., 2025 vs 2024) or regions (e.g., Europe vs Asia)?"
59
+
60
+ ### Extract Parameters
61
+
62
+ - **Comparison items**: 2-5 items. If more than 5: "That's a lot of comparisons. Try /vortexa:breakdown for dimension analysis instead."
63
+ - **Product**: commodity (crude, LNG, etc.)
64
+ - **Activity**: same rules as cargo-flows (exports=loading_end, imports=unloading_start, etc.)
65
+ - **Base query parameters**: origin, destination, time range, unit, frequency
66
+
67
+ **For period mode:**
68
+ - Each comparison item is a time period (year, quarter, month range)
69
+ - Normalize x-axis to common reference: month names (Jan, Feb, ...) for year comparisons, week numbers for quarter comparisons
70
+ - Default frequency: monthly for year comparisons, weekly for quarter comparisons, daily for month comparisons
71
+
72
+ **For region mode:**
73
+ - Each comparison item is a geography (country, region, shipping region)
74
+ - Use the same time range for all items
75
+ - x-axis is the shared date range (no normalization needed)
76
+
77
+ ## Step 3: Check for Missing Parameters
78
+
79
+ Ask targeted questions BEFORE the confirmation step. Never default silently.
80
+
81
+ **Required (ask if missing):**
82
+ - **Comparison items** -- MUST have at least 2 items. Ask: "What periods/regions are you comparing?"
83
+ - **Product** -- MUST be specified. Ask if missing.
84
+ - **Activity** -- MUST be specified. If direction ambiguous, ask: "exports from origin or imports to destination?"
85
+
86
+ **Mode-specific required:**
87
+ - **Period mode**: frequency (default monthly for year comparisons, but confirm)
88
+ - **Region mode**: time range (MUST be specified)
89
+
90
+ **Ask if not specified:**
91
+ - **Unit** -- Apply commodity defaults (oil=bpd, LNG=t, LPG=t). Ask if ambiguous.
92
+ - **Geography filters** -- optional but commonly specified (e.g., "from Saudi Arabia" applies to all periods)
93
+
94
+ Ask one parameter at a time. Do NOT ask all missing params in a bulk dump.
95
+
96
+ ## Step 4: Resolve Entity IDs
97
+
98
+ For each entity mentioned (product, geography filters, region comparison items):
99
+ 1. Check `lib/aliases.json` for common shorthands (ME, AG, USG, ARA, etc.)
100
+ 2. Call `lib/entities.py` resolve functions with the correct entity type and layer:
101
+ - `resolve_geography(term, layer)` for origins/destinations and region comparison items
102
+ - `resolve_product(term, layer)` for products
103
+ - `resolve(term, entity_type, layer, cache)` for the unified resolver with caching
104
+ 3. If multiple matches: present top 3 candidates. Ask user to pick. NEVER auto-correct.
105
+ 4. If zero matches: tell user the term wasn't found, suggest checking spelling or trying a broader term.
106
+
107
+ Use `EntityCache()` from `lib/entities.py` for the session to avoid re-resolving the same entities.
108
+
109
+ ## Step 5: Confirm Before Executing (MANDATORY)
110
+
111
+ **Period mode confirmation:**
112
+ ```
113
+ Query: [restate]
114
+ Analysis: Period comparison
115
+ Endpoint: CargoTimeSeries
116
+ Comparing: [period1] vs [period2] (vs ...)
117
+ Activity: [filter_activity] ([user's term])
118
+ Origin: [name (layer)] or "not specified"
119
+ Destination: [name (layer)] or "not specified"
120
+ Product: [name (layer)]
121
+ Unit: [unit] ([reason])
122
+ Frequency: [value]
123
+ Chart: Overlay lines + difference table
124
+
125
+ Confirm or adjust?
126
+ ```
127
+
128
+ **Region mode confirmation:**
129
+ ```
130
+ Query: [restate]
131
+ Analysis: Region comparison
132
+ Endpoint: CargoTimeSeries
133
+ Comparing: [region1] vs [region2] (vs ...)
134
+ Activity: [filter_activity] ([user's term])
135
+ Product: [name (layer)]
136
+ Time: [start] -> [end]
137
+ Unit: [unit] ([reason])
138
+ Frequency: [value]
139
+ Chart: Overlay lines + metrics table
140
+
141
+ Confirm or adjust?
142
+ ```
143
+
144
+ NEVER execute without confirmation. Wait for user response.
145
+
146
+ ## Step 6: Generate & Execute Code Artifact
147
+
148
+ ### Period Mode Code
149
+
150
+ Generate code that:
151
+ 1. Runs a separate CTS query per period using `CargoTimeSeries` directly (no split needed)
152
+ 2. Normalizes x-axis: for year comparisons, map dates to month labels (Jan, Feb, ...) so lines overlay correctly
153
+ 3. Builds `series_dict` mapping period names to value lists
154
+ 4. Computes metrics inline (see metrics section below)
155
+ 5. Calls `comparison_overlay_chart(series_dict, x_labels, title, y_label)`
156
+ 6. Prints metrics table and saves chart
157
+
158
+ ### Region Mode Code
159
+
160
+ Generate code that:
161
+ 1. Runs a separate CTS query per region (filtering by the region geography) with same time range
162
+ 2. x-axis is the shared date range (no normalization needed)
163
+ 3. Builds `series_dict` mapping region names to value lists
164
+ 4. Same metrics computation and chart generation
165
+
166
+ ### Metrics Computation
167
+
168
+ Compute comparison metrics inline in generated code (NOT a lib/ function -- keep it clean with a small inline helper):
169
+
170
+ ```python
171
+ # Compute comparison metrics
172
+ metrics = {}
173
+ for name, values in series_dict.items():
174
+ metrics[name] = {
175
+ "Total": sum(v for v in values if v),
176
+ "Average": sum(v for v in values if v) / len([v for v in values if v]) if any(values) else 0,
177
+ }
178
+ # Difference table (pairwise from first comparison item)
179
+ base = list(series_dict.keys())[0]
180
+ for name in list(series_dict.keys())[1:]:
181
+ diff = metrics[name]["Total"] - metrics[base]["Total"]
182
+ pct = (diff / metrics[base]["Total"] * 100) if metrics[base]["Total"] else 0
183
+ print(f"{name} vs {base}: {diff:+,.0f} ({pct:+.1f}%)")
184
+ ```
185
+
186
+ ### Code Artifact Template
187
+
188
+ ```python
189
+ """Vortexa Compare: {description}
190
+ Generated by /vortexa:compare
191
+ Date: {date}
192
+ """
193
+ from datetime import datetime
194
+ import os
195
+ import sys; sys.path.insert(0, "lib")
196
+ from entities import resolve_geography, resolve_product, EntityCache
197
+ from visualization import comparison_overlay_chart
198
+
199
+ cache = EntityCache()
200
+ {entity_resolution}
201
+
202
+ # Query each comparison item
203
+ from vortexasdk import CargoTimeSeries
204
+ series_dict = {}
205
+ {per_item_queries}
206
+
207
+ # X-axis labels
208
+ x_labels = {x_labels}
209
+
210
+ # Metrics
211
+ {metrics_computation}
212
+
213
+ # Chart
214
+ fig = comparison_overlay_chart(series_dict, x_labels=x_labels, title="{title}", y_label="{unit_label}")
215
+
216
+ os.makedirs("output", exist_ok=True)
217
+ filepath = f"output/{slug}_compare_{datetime.now().strftime('%Y-%m-%d')}.html"
218
+ fig.write_html(filepath, auto_open=True)
219
+ print(f"Chart saved: {filepath}")
220
+ ```
221
+
222
+ **Period mode per-item query pattern:**
223
+ ```python
224
+ # Example: 2025 vs 2024
225
+ for year in [2025, 2024]:
226
+ df = CargoTimeSeries().search(
227
+ filter_activity=...,
228
+ filter_time_min=datetime(year, 1, 1),
229
+ filter_time_max=datetime(year, 12, 31, 23, 59, 59),
230
+ filter_products=[product_id],
231
+ filter_origins=[...], # if specified
232
+ filter_destinations=[...], # if specified
233
+ timeseries_unit=...,
234
+ timeseries_frequency=...,
235
+ ).to_df()
236
+ series_dict[str(year)] = df["value"].tolist()
237
+
238
+ x_labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
239
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
240
+ ```
241
+
242
+ **Region mode per-item query pattern:**
243
+ ```python
244
+ # Example: Europe vs Asia
245
+ for region_name, region_id in [("Europe", europe_id), ("Asia", asia_id)]:
246
+ df = CargoTimeSeries().search(
247
+ filter_activity=...,
248
+ filter_time_min=...,
249
+ filter_time_max=...,
250
+ filter_products=[product_id],
251
+ filter_destinations=[region_id], # or filter_origins depending on activity
252
+ timeseries_unit=...,
253
+ timeseries_frequency=...,
254
+ ).to_df()
255
+ series_dict[region_name] = df["value"].tolist()
256
+
257
+ x_labels = df["key"].tolist() # shared date buckets
258
+ ```
259
+
260
+ After generating:
261
+ - Ask user: "Save as new file, or add to an existing notebook/script?" Default: new file.
262
+ - If new file: create `vortexa_compare_{slug}.py` in project directory.
263
+ - Run the generated code to get results.
264
+
265
+ ## Step 7: Present Results
266
+
267
+ - Show metrics summary table:
268
+ - Total and Average per comparison item
269
+ - Absolute change and percentage change (pairwise from first item)
270
+ - Show overlay chart HTML path: "Chart saved: output/{slug}_compare_{date}.html"
271
+ - Methodology footnote using confirmed parameters:
272
+ ```
273
+ Methodology: CargoTimeSeries (comparison) | {mode} | {items} | {activity} | {filters} | {frequency} | {unit}
274
+ ```
275
+ Example: `Methodology: CargoTimeSeries (comparison) | period | 2025 vs 2024 | loading_end | filter_origins=[Saudi Arabia] | monthly | bpd`
276
+ - Offer: "Export to CSV?" and "Want a detailed summary?"
277
+
278
+ ## Step 8: Summary (if triggered)
279
+
280
+ **Smart trigger:** If the user's query contains "analyze", "summarize", "explain results", "what does this show", or "key findings" -- generate the summary automatically.
281
+
282
+ **Post-query offer:** After showing results, always offer: "Want a detailed summary?"
283
+
284
+ **Summary content** -- comparison-specific insights:
285
+ - Which comparison item has the highest total volume
286
+ - Growth/decline trends: percentage change between items
287
+ - Notable crossover points: where one item overtakes another on the chart
288
+ - Seasonal patterns: months where differences are largest/smallest
289
+ - Peak and trough identification per item
290
+
291
+ **Brief summary (default):** 3-5 bullet points with specific numbers.
292
+
293
+ **Extended summary (if user requests "detailed summary" or "full analysis"):**
294
+ - 100-200 word narrative in market commentary style
295
+ - Covers all the above plus broader context
296
+
297
+ After showing the summary, offer: "Save this summary to a .md file?"
298
+ If yes: create `output/{description}_summary_{date}.md`
299
+
300
+ ## Error Handling
301
+
302
+ Report immediately in plain English, no auto-retry:
303
+
304
+ - **401 Unauthorized**: "API key is invalid or expired. Run /vortexa:init to check your setup."
305
+ - **500 Server Error**: "Vortexa API returned a server error. Try again in a few minutes."
306
+ - **Timeout**: "Query timed out. Try narrowing the date range or reducing filters."
307
+ - **Empty results**: "No data found for this query. Check that the entity names, date range, and filters are correct."
308
+ - **Entity not found**: "The term '{term}' returned no matches. Check spelling or try a broader term."
309
+ - **Multiple entity matches**: "{n} matches found for '{term}': [list]. Which did you mean?"
310
+ - **Too many items**: "More than 5 comparison items requested. Try /vortexa:breakdown for dimension analysis instead."
311
+ - **Mismatched data lengths**: "The comparison periods returned different numbers of data points. Check that all periods have complete data coverage."
312
+
313
+ Never auto-retry. Never self-correct. Report the error and let the user decide.
314
+
315
+ </process>
@@ -0,0 +1,214 @@
1
+ ---
2
+ name: vortexa:custom
3
+ description: "Run any Vortexa API query or improve existing Vortexa Python code"
4
+ argument-hint: "Average waiting time at Fujairah for VLCCs"
5
+ allowed-tools:
6
+ - Read
7
+ - Edit
8
+ - Write
9
+ - Bash
10
+ - Glob
11
+ - Grep
12
+ ---
13
+
14
+ <objective>
15
+ Handle any Vortexa API query by loading all endpoint context docs and writing custom SDK code. Also read, validate, fix, or extend existing user Vortexa Python code. This is the open-ended skill for queries that don't fit the focused /vortexa:cargo-flows or /vortexa:voyages workflows.
16
+ </objective>
17
+
18
+ <execution_context>
19
+ ## Pre-loaded Context (via CLAUDE.md @imports)
20
+ The following are automatically available -- do NOT re-read them:
21
+ - context/guardrails.md -- NEVER/ALWAYS rules for all Vortexa API calls
22
+ - context/entity-resolution.md -- How to resolve entity names to hex IDs
23
+ - context/date-units.md -- Date parsing rules and unit defaults
24
+
25
+ ## Required Context (Read ALL on demand)
26
+ Read all three endpoint context docs before processing -- the custom skill needs the full API surface:
27
+ - context/cargo-movements.md -- CTS/CM parameters, activity filters, column names
28
+ - context/voyages.md -- VSE/VTS parameters, voyage definitions, V1/V2 differences
29
+ - context/reference-endpoints.md -- Entity lookups, product hierarchy, geography layers
30
+ </execution_context>
31
+
32
+ ## Setup Check
33
+ @commands/vortexa/_check-setup.md
34
+
35
+ <process>
36
+
37
+ ## Step 1: Read ALL Endpoint Context
38
+
39
+ Read all three endpoint context docs:
40
+ - `context/cargo-movements.md`
41
+ - `context/voyages.md`
42
+ - `context/reference-endpoints.md`
43
+
44
+ The custom skill operates across the full API surface. All three docs are needed regardless of query type.
45
+
46
+ ## Step 2: Determine Intent
47
+
48
+ Analyze $ARGUMENTS to classify the request:
49
+
50
+ **A. New data query** -- user wants data the API can provide
51
+ - Could involve any endpoint: CTS, CM, VSE, VTS, Congestion, Reference
52
+ - Could combine multiple endpoints in a single query (e.g., CM + VSE for OOW enrichment)
53
+ - Proceed to Steps 3-9 (standard query workflow)
54
+
55
+ **B. Code improvement** -- user references existing code
56
+ - User mentions a .py file, notebook, or pastes code
57
+ - Read the referenced file(s) first
58
+ - Use context docs to validate, fix, or extend the code
59
+ - Check for common mistakes against guardrails.md rules (wrong activity filter, missing entity resolution, midnight end dates, deprecated oil_on_water_state, etc.)
60
+ - Explain what was wrong and why the fix is correct, citing specific guardrails rules
61
+ - Skip the confirmation step (user already has code)
62
+
63
+ **C. Redirect** -- query fits a focused skill better
64
+ - Straightforward CTS/CM query: suggest "This looks like a cargo flow query -- try `/vortexa:cargo-flows {query}` for a more focused workflow."
65
+ - Straightforward VSE/VTS query: suggest "This looks like a voyage query -- try `/vortexa:voyages {query}` for a more focused workflow."
66
+ - Still process the query if the user insists or if the query combines multiple endpoints
67
+
68
+ ## Step 3: Parse the Query (New Data Queries)
69
+
70
+ Extract all relevant parameters from the natural language query:
71
+ - **Endpoint(s)**: Which API endpoint(s) are needed? May be multiple.
72
+ - **Product**: What commodity?
73
+ - **Geography**: Origins, destinations, storage locations -- what layers?
74
+ - **Activity**: What movement stage? (exports=loading_end, imports=unloading_start, etc.)
75
+ - **Vessel filters**: Class, flag, DWT, IMO, age, scrubber status
76
+ - **Corporate filters**: Owner, charterer, time charterer
77
+ - **Time range**: Apply date-units.md calendar/trailing convention
78
+ - **Unit**: Apply commodity defaults (oil=bpd, LNG=t, LPG=t)
79
+ - **Frequency**: For timeseries queries
80
+ - **Additional**: Intra movements, confidence, STS, waypoints, congestion breakdowns
81
+
82
+ ## Step 4: Check for Missing Parameters
83
+
84
+ Same conservative policy as cargo-flows and voyages: always ask, never default silently.
85
+ Ask one parameter at a time. Do NOT bulk-dump all missing params.
86
+
87
+ Required for every query:
88
+ - Time range -- MUST be specified
89
+ - At least one meaningful filter (product, geography, vessel, or corporate)
90
+
91
+ For timeseries: frequency must be specified or asked.
92
+ For search endpoints: set `size=500`.
93
+
94
+ ## Step 5: Resolve Entity IDs
95
+
96
+ Same entity resolution workflow as the other skills:
97
+ 1. Check `lib/aliases.json` for common shorthands (ME, AG, USG, ARA, etc.)
98
+ 2. Call `lib/entities.py` resolve functions: `resolve_geography(term, layer)`, `resolve_product(term, layer)`, `resolve(term, entity_type, layer, cache)`
99
+ 3. Multiple matches: present top 3 candidates, ask user to pick. NEVER auto-correct.
100
+ 4. Zero matches: tell the user, suggest alternatives.
101
+ 5. Use `EntityCache()` for the session to avoid re-resolving.
102
+
103
+ ## Step 6: Confirm Before Executing (MANDATORY for new queries)
104
+
105
+ Present the parsed query adapted to the specific endpoint(s):
106
+
107
+ ```
108
+ Query: [restate the user's question]
109
+ Endpoint(s): [list all endpoints being used]
110
+ [endpoint-specific parameters -- activity, voyage status, metric, breakdown, etc.]
111
+ Origin: [name (layer)] or "not specified"
112
+ Destination: [name (layer)] or "not specified"
113
+ Product: [name (layer)] or "not specified"
114
+ Time: [start datetime] -> [end datetime] ([interpretation])
115
+ Unit: [unit] ([reason])
116
+ Frequency: [value] (timeseries only)
117
+ Additional: [any other filters]
118
+
119
+ Confirm or adjust?
120
+ ```
121
+
122
+ NEVER execute without confirmation. Wait for user response.
123
+ Skip this step ONLY for code improvement (intent B) where the user already has code.
124
+
125
+ ## Step 7: Generate & Execute Code Artifact
126
+
127
+ Code is ALWAYS custom SDK code (Mode 2) -- reference the relevant context doc for correct parameter names and syntax.
128
+
129
+ ```python
130
+ """Vortexa Query: {description}
131
+ Generated by /vortexa:custom
132
+ Date: {date}
133
+ """
134
+ from datetime import datetime
135
+ import sys; sys.path.insert(0, "lib")
136
+ from entities import resolve, EntityCache
137
+
138
+ # Custom query -- built from Vortexa API documentation
139
+ cache = EntityCache()
140
+ # {entity resolution}
141
+ # {SDK calls using vortexasdk}
142
+ # {result formatting}
143
+ ```
144
+
145
+ Key rules:
146
+ - Write raw SDK calls using vortexasdk, referencing endpoint context docs for correct syntax
147
+ - Can combine multiple endpoints (e.g., CM + VSE for OOW enrichment, Reference + CTS for entity lookup then query)
148
+ - Use lib/ functions as building blocks where they fit (entity resolution, column rename, timeseries parsing)
149
+ - Add comment: `# Custom query -- built from Vortexa API documentation`
150
+ - Code must be self-contained and re-runnable
151
+
152
+ For code improvement (intent B):
153
+ - Read the user's existing file
154
+ - Identify issues using context docs and guardrails.md
155
+ - Fix or extend in-place, or create a corrected version
156
+ - Explain each change with references to specific guardrails rules
157
+
158
+ Ask user: "Save as new file, or add to existing script/notebook?" Default: new file.
159
+
160
+ ## Step 8: Present Results
161
+
162
+ Terminal summary (same pattern as cargo-flows and voyages):
163
+ - Brief natural language description of what was queried
164
+ - Row count and date range covered
165
+ - DataFrame preview with row cap (daily=30, weekly=52, monthly=24, yearly=all)
166
+ - File path to generated code artifact
167
+ - Offer: "Export to CSV?"
168
+
169
+ For code improvement: show a diff summary of what changed and why.
170
+
171
+ After the DataFrame preview and before the export offer, show a one-line methodology footnote using the CONFIRMED parameters from Step 6:
172
+ ```
173
+ Methodology: {Endpoint(s)} | {activity} | {key filters} | {frequency} | {unit} | {other relevant params}
174
+ ```
175
+ Example: `Methodology: CargoMovements.search | loading_end | filter_origins=[Saudi Arabia] | filter_products=[Crude & Condensates] | size=500`
176
+
177
+ Use human-readable names for entity filters (not hex IDs). Skip for code improvement (intent B).
178
+
179
+ ## Step 9: Summary (if triggered)
180
+
181
+ **Smart trigger:** If the user's query contains "analyze", "summarize", "explain results", "what does this show", or "key findings" -- generate the summary automatically.
182
+
183
+ **Post-query offer:** After showing results, always offer: "Want a summary of these results?"
184
+
185
+ **Brief summary (default):**
186
+ Analyze the DataFrame and produce 3-5 bullet points:
187
+ - Top 3-5 contributors by volume with percentages of total
188
+ - Period-over-period change if comparable time periods exist
189
+ - Notable outliers: spikes, drops, record values, trend reversals
190
+ - Each bullet includes specific numbers, not vague descriptions
191
+
192
+ **Extended summary (if user requests "detailed summary" or "full analysis"):**
193
+ - 100-200 word narrative paragraph in market commentary style
194
+ - Includes everything from brief plus trend descriptions and broader context
195
+
196
+ After showing the summary, offer: "Save this summary to a .md file?"
197
+ If yes: create `output/{description}_summary_{date}.md`
198
+
199
+ Skip for code improvement (intent B) -- summaries are for query results, not code reviews.
200
+
201
+ ## Error Handling
202
+
203
+ Same patterns as cargo-flows and voyages -- report immediately in plain English, no auto-retry:
204
+
205
+ - **401 Unauthorized**: "API key is invalid or expired. Run /vortexa:init to check your setup."
206
+ - **500 Server Error**: "Vortexa API returned a server error. Try again in a few minutes."
207
+ - **Timeout**: "Query timed out. Try narrowing the date range or reducing filters."
208
+ - **Empty results**: "No data found. Check entity names, date range, and filters."
209
+ - **Entity not found**: "The term '{term}' returned no matches. Check spelling or try a broader term."
210
+ - **Multiple entity matches**: Present top candidates with name, layer, and first 8 chars of ID. Ask user to pick.
211
+
212
+ Never auto-retry. Never self-correct. Report the error and let the user decide.
213
+
214
+ </process>
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: vortexa:explain
3
+ description: "Get plain-English explanations of Vortexa data model, filters, entity hierarchies, and methodology"
4
+ argument-hint: "What is loading_end vs loading_state?"
5
+ allowed-tools:
6
+ - Read
7
+ ---
8
+
9
+ <objective>
10
+ Answer any question about the Vortexa data model, API methodology, entity hierarchies, filter options, activity types, and endpoint behavior using ONLY the information in the context documentation. Support conversational follow-ups for guided exploration.
11
+
12
+ This is a Knowledge Variant skill -- it generates no code, makes no API calls, and produces no DataFrames. It reads documentation and explains concepts.
13
+ </objective>
14
+
15
+ <execution_context>
16
+ ## Pre-loaded Context (via CLAUDE.md @imports)
17
+ The following are automatically available -- do NOT re-read them:
18
+ - context/guardrails.md -- Activity filters, entity resolution rules, date ranges, API defaults, voyages rules, confirmation step, quick decision table
19
+ - context/entity-resolution.md -- Resolution workflow, SDK methods, geography/product/vessel/corporate hierarchies, disambiguation protocol
20
+ - context/date-units.md -- Calendar vs trailing date parsing, frequency selection, unit defaults by commodity
21
+
22
+ ## Required Context (Read on demand)
23
+ Read ALL three endpoint context docs at the start of the conversation:
24
+ - context/cargo-movements.md -- CTS and CM parameters, activity filters, column names, breakdown/split properties, worked examples
25
+ - context/voyages.md -- VSE and VTS parameters, voyage definitions, events, V1/V2 differences, freight metrics
26
+ - context/reference-endpoints.md -- Entity hierarchies, SDK methods, product/geography/vessel/corporate layers, search patterns
27
+ </execution_context>
28
+
29
+ <process>
30
+
31
+ ## Step 1: Read All Context Documentation
32
+
33
+ Read all three endpoint context docs:
34
+ - `context/cargo-movements.md`
35
+ - `context/voyages.md`
36
+ - `context/reference-endpoints.md`
37
+
38
+ Combined with the pre-loaded guardrails, entity-resolution, and date-units docs, this gives access to the full Vortexa knowledge base (~4,000 lines across 6 docs). This is a one-time read at the start of the conversation -- no need to re-read for follow-up questions.
39
+
40
+ ## Step 2: Identify the Topic
41
+
42
+ Analyze $ARGUMENTS to determine what the user is asking about. Common topic categories:
43
+
44
+ **Entity hierarchies** -- "What products are there?", "How are geographies organized?", "What vessel classes exist?"
45
+ - Answer from: reference-endpoints.md (full hierarchy tables), entity-resolution.md (resolution workflow)
46
+
47
+ **Filter behavior** -- "What is loading_end?", "Difference between loading_state and loading_end?", "When should I use exclude_intra_country?"
48
+ - Answer from: guardrails.md (activity filter table, geography logic table), cargo-movements.md (parameter details)
49
+
50
+ **Activity types** -- "What activities can I filter on?", "What does storing_state mean?", "What's cargo_on_water_state?"
51
+ - Answer from: guardrails.md (activity table with correct/wrong choices), cargo-movements.md (activity definitions)
52
+
53
+ **Methodology** -- "How does CTS differ from CM?", "What's the CM-Authoritative OOW pattern?", "How does quantity_at_time_of work?"
54
+ - Answer from: cargo-movements.md (endpoint comparison, OOW pattern), voyages.md (methodology sections)
55
+
56
+ **API mechanics** -- "V1 vs V2 voyages timeseries?", "What units are available?", "How do date ranges work?"
57
+ - Answer from: voyages.md (V1/V2 differences), date-units.md (units table), guardrails.md (API defaults)
58
+
59
+ **Endpoint guidance** -- "When should I use Voyages vs CargoMovements?", "What is VoyagesSearchEnriched?", "What breakdown properties does CTS support?"
60
+ - Answer from: voyages.md (endpoint selection), cargo-movements.md (split properties), guardrails.md (quick decision table)
61
+
62
+ ## Step 3: Search Context Docs and Synthesize Answer
63
+
64
+ Find the relevant information across the loaded context docs and synthesize a plain-English explanation.
65
+
66
+ ### Accuracy Constraint
67
+
68
+ **ONLY use information from the context docs.** Do NOT supplement with training knowledge or assumptions about the Vortexa API. If it is not written in the 6 context docs, do not state it as fact. This ensures the explanation matches exactly what the query skills (/vortexa:cargo-flows, /vortexa:voyages, /vortexa:breakdown, /vortexa:custom) actually use.
69
+
70
+ ### Synthesis Rules
71
+
72
+ 1. **If the topic IS covered:** Explain it clearly using the doc content. Include specific rules, tables, and examples from the docs. Cite which doc the information comes from (e.g., "Per guardrails.md, loading_end is the correct activity for exports").
73
+
74
+ 2. **If the topic is NOT covered:** Say "This concept isn't documented in the current context. The context docs cover: entity hierarchies, activity filters, date conventions, cargo movements (CTS/CM), voyages (VSE/VTS), and reference endpoints (products, geographies, vessels, corporations)."
75
+
76
+ 3. **If the topic spans multiple docs:** Cross-reference them. For example, "How do I query crude exports?" touches guardrails.md (activity=loading_end), entity-resolution.md (resolve product ID), cargo-movements.md (CTS parameters), and date-units.md (time range format).
77
+
78
+ ### Formatting Guidelines
79
+
80
+ - Structure answers with clear headers or bullet points for readability
81
+ - For hierarchy questions, show the hierarchy visually:
82
+ ```
83
+ group > group_product > category > grade
84
+ ```
85
+ - For "which should I use" questions, reference the decision tables in guardrails.md and the endpoint context docs
86
+ - For filter comparison questions, use side-by-side tables showing the differences
87
+ - For "what options are there" questions, list all options with brief descriptions from the docs
88
+ - For common-mistake questions, highlight the NEVER/ALWAYS rules from guardrails.md
89
+ - Keep explanations concise -- the user can always ask follow-ups for more detail
90
+
91
+ ## Step 4: Offer Drill-Down
92
+
93
+ After answering, offer follow-up exploration with 2-3 specific related topics the user might want to explore next:
94
+
95
+ "Want to explore deeper into any of these? For example:
96
+ - [related topic 1 based on what was just explained]
97
+ - [related topic 2 that naturally follows]
98
+ - [related topic 3 for broader context]"
99
+
100
+ ### Drill-Down Topic Selection
101
+
102
+ Choose follow-up suggestions that naturally extend the current explanation:
103
+ - If explaining an entity hierarchy -> suggest exploring a specific branch, or how to resolve IDs
104
+ - If explaining a filter -> suggest comparing it with a commonly confused alternative
105
+ - If explaining methodology -> suggest the related endpoint parameters or worked examples
106
+ - If explaining an endpoint -> suggest when to use it vs alternatives, or its key parameters
107
+
108
+ ### Example Drill-Down Flows
109
+
110
+ - "What products are there?" -> hierarchy shown -> "Tell me about Clean Products" -> sub-groups listed -> "What's the difference between category and grade?" -> explanation with examples
111
+ - "What activities are there?" -> list with descriptions -> "What's the difference between cargo_on_water_state and storing_state?" -> detailed comparison with use cases
112
+ - "How does entity resolution work?" -> workflow explained -> "Show me the geography layers" -> hierarchy with examples from each layer
113
+ - "When should I use CTS vs CM?" -> decision criteria -> "How does the CM-Authoritative OOW pattern work?" -> step-by-step explanation
114
+ - "What units are available?" -> full unit table -> "What's the default for LNG?" -> commodity defaults explained -> "How do rate units differ from absolute?" -> bpd vs b comparison
115
+
116
+ ### Conversational Continuity
117
+
118
+ The skill is conversational -- it can answer multiple follow-up questions in the same session using the context docs already loaded in Step 1. Unlike the data query skills which are one-shot (parse, confirm, execute, present), this skill maintains a dialogue where each answer builds on previous context.
119
+
120
+ If a follow-up question shifts to a topic better served by a data query, suggest the appropriate skill:
121
+ - "Can you pull that data?" -> "Try `/vortexa:cargo-flows` or `/vortexa:voyages` for actual data queries"
122
+ - "Show me a breakdown by origin" -> "Try `/vortexa:breakdown crude exports by origin`"
123
+
124
+ </process>