Refresh the data cache
Clears the configured customer's local data lake, then re-pulls a fresh 60-day window so the next report runs against clean data. Before deleting anything, this flow always offers the lighter update-cache alternative – most people who reach for "refresh" actually just want the newest data, not a full wipe.
Two steps once a full refresh is confirmed:
- Delete (
refresh_cache.py) is stdlib-only and offline-safe – it never touches the network, so it can't fail on auth lapses, network errors, or S3 hiccups. It clears the lake root and the catalog; it will exit non-zero if bucket.json is missing (nothing to scope the deletion to); that's the only failure mode.
- Re-pull (
pull_parsely_dpl.py) requires fresh AWS SSO. Splitting the steps means a stale auth at re-pull time doesn't leave the user in a half-state – the lake is cleared either way, and the next report run (or a retry of this flow) will fill it back in. The pull also rebuilds the dpl_events catalog view.
If config itself looks broken (wrong bucket, missing profile), use the clear-configs skill instead and re-run the init flow.
Output discipline
This is housekeeping, with one exception: because deletion is destructive and irreversible, always confirm before running it (see step 2 below). Past that checkpoint, be terse – announce, run, stop. Don't narrate the script output line-by-line – the scripts print their own progress.
Steps
Resolve the plugin root. Every bash snippet below assumes $plugin_root is set in that shell invocation; re-run this line whenever you start a new shell:
plugin_root="${CLAUDE_PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-<plugin-root>}}"
plugin_python="${AGENTIC_ANALYTICS_VENV:-${AGENTIC_ANALYTICS_DATA_DIR:-$HOME/.local/share/agentic-analytics}/venv}/bin/python"
[ -x "$plugin_python" ] || plugin_python="python3"
<plugin-root> is the plugin's install directory – the directory two levels above this SKILL.md file. In a dev checkout of the source repo that's plugin/. $plugin_python is the plugin's isolated venv (created by the init flow at $AGENTIC_ANALYTICS_DATA_DIR/venv, default ~/.local/share/agentic-analytics/venv); it falls back to python3 if the venv doesn't exist yet.
Load bucket config. Read ${XDG_CONFIG_HOME:-~/.config}/agentic-analytics/bucket.json. It contains:
bucket – S3 bucket holding the customer's DPL events.
profile – AWS profile to authenticate with.
cache_dir – a slug identifying the customer's data (e.g. acme).
If the file is missing, tell the user to run the init flow first (/agentic-analytics:init on harnesses with slash commands, or "set up agentic analytics" in chat) and stop. Do not guess values.
Offer the lighter alternative, every time. Before deleting anything, explain the trade-off and ask which the user wants. Always ask – don't skip this because the user's phrasing sounds decisive ("wipe it", "start over"); the cost of asking is one message, the cost of an unnecessary multi-gigabyte wipe-and-re-pull is real. Say something like:
Refreshing the cache for '<cache_dir>' deletes everything currently cached and re-pulls the full 60-day window from S3 – can take a while. If you just want the newest data without losing what's already cached, update-cache does that instead and is much faster.
Full refresh (delete + re-pull) – use this for stale/corrupt data, schema drift, or a bad prior pull. Or: update only (no deletion, just top up).
- If the user picks update only: follow the update-cache skill's steps in this same turn (announce, then run
pull_parsely_dpl.py incrementally with no delete step, then report) using the bucket/profile/cache_dir already loaded in step 1. Stop here – do not continue to step 3.
- If the user picks full refresh: continue to step 3.
Announce. Output verbatim:
Refreshing the local cache. Config (bucket.json, AWS profile) will be left alone.
Delete the cache. Runs the deletion script. Reports which dirs it cleared and the bytes freed, or (nothing to clear):
"$plugin_python" "$plugin_root/scripts/refresh_cache.py"
Re-pull a fresh 60 days. Same window the staircase report targets. pull_parsely_dpl.py is incremental and idempotent; after a wipe it pulls the full window once and also rebuilds the dpl_events catalog view.
read target_start target_end < <(python3 -c "
from datetime import date, timedelta
start = date.today() - timedelta(days=60)
end = date.today() - timedelta(days=1)
print(start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d'))
")
"$plugin_python" "$plugin_root/scripts/db/pull_parsely_dpl.py" \
--bucket <bucket> [--site <site>] \
--start "$target_start" --end "$target_end" \
[--profile <profile>]
Substitute <bucket> and <profile> with the values held from step 1. Omit --site to refresh all sites; pass --site <site> to limit the pull to one site. Do NOT add || true here – unlike the report path, a failed re-pull is the headline result of this flow; surface it.
Report done. One short line: "Cache rebuilt. Next report run uses fresh data."
If the re-pull failed (auth lapse, S3 error, no events for the window), say so plainly and tell the user the lake is now empty – the next report run will try to pull again, or they can re-run this flow once auth is fresh.
Notes
- Only the currently configured customer's DPL data is affected. The lake root holds all sources/sites pooled under
$AGENTIC_ANALYTICS_DATA_DIR (default ~/.local/share/agentic-analytics); deletion is scoped to the dpl/events/ subtree and the catalog, so other data you may later land in the lake is untouched. To work with a different customer, switch bucket.json first.
- Deletion is not scoped to a single site even when the re-pull afterward is –
refresh_cache.py always clears the whole dpl/events/ subtree (every site/apikey under the configured bucket). Passing --site <site> to step 5 only limits what gets re-pulled, not what got deleted. If you only want to top up or repair one site's data without touching the rest, use update-cache instead – it never deletes.
- The DuckDB catalog (
catalog.duckdb and its .wal sidecar) is cleared too. It's derived state any report can regenerate by re-running pull_parsely_dpl.py.
- Legacy gz cache sweep: if you're upgrading from a pre-lake version, this flow also clears the old gz-JSON cache at
~/.cache/agentic-analytics/dpl/<cache_dir>/ and the duckdb-tmp/ working dir (scoped to your cache_dir). The lake code never reads them; sweeping just reclaims the orphaned disk. No-op for fresh installs.
1---2name: refresh-cache3description: Blow away the local data cache and rebuild it. Use when the user asks to refresh the cache, rebuild the cache, clear cached data, start clean, recover from a bad pull, or says reports are returning stale or weird-looking numbers. Leaves config alone. Offers the lighter update-cache flow as an alternative before deleting anything.4---56# Refresh the data cache78Clears the configured customer's local data lake, then re-pulls a fresh 60-day window so the next report runs against clean data. Before deleting anything, this flow always offers the lighter update-cache alternative – most people who reach for "refresh" actually just want the newest data, not a full wipe.910Two steps once a full refresh is confirmed:11121. **Delete** (`refresh_cache.py`) is stdlib-only and offline-safe – it never touches the network, so it can't fail on auth lapses, network errors, or S3 hiccups. It clears the lake root and the catalog; it will exit non-zero if `bucket.json` is missing (nothing to scope the deletion to); that's the only failure mode.132. **Re-pull** (`pull_parsely_dpl.py`) requires fresh AWS SSO. Splitting the steps means a stale auth at re-pull time doesn't leave the user in a half-state – the lake is cleared either way, and the next report run (or a retry of this flow) will fill it back in. The pull also rebuilds the `dpl_events` catalog view.1415If config itself looks broken (wrong bucket, missing profile), use the clear-configs skill instead and re-run the init flow.1617## Output discipline1819This is housekeeping, with one exception: because deletion is destructive and irreversible, always confirm before running it (see step 2 below). Past that checkpoint, be terse – announce, run, stop. Don't narrate the script output line-by-line – the scripts print their own progress.2021## Steps22230. **Resolve the plugin root.** Every bash snippet below assumes `$plugin_root` is set in that shell invocation; re-run this line whenever you start a new shell:2425 ```bash26 plugin_root="${CLAUDE_PLUGIN_ROOT:-${CURSOR_PLUGIN_ROOT:-<plugin-root>}}"27 plugin_python="${AGENTIC_ANALYTICS_VENV:-${AGENTIC_ANALYTICS_DATA_DIR:-$HOME/.local/share/agentic-analytics}/venv}/bin/python"28 [ -x "$plugin_python" ] || plugin_python="python3"29 ```3031 `<plugin-root>` is the plugin's install directory – the directory two levels above this SKILL.md file. In a dev checkout of the source repo that's `plugin/`. `$plugin_python` is the plugin's isolated venv (created by the init flow at `$AGENTIC_ANALYTICS_DATA_DIR/venv`, default `~/.local/share/agentic-analytics/venv`); it falls back to `python3` if the venv doesn't exist yet.32331. **Load bucket config.** Read `${XDG_CONFIG_HOME:-~/.config}/agentic-analytics/bucket.json`. It contains:3435 - `bucket` – S3 bucket holding the customer's DPL events.36 - `profile` – AWS profile to authenticate with.37 - `cache_dir` – a slug identifying the customer's data (e.g. `acme`).3839 If the file is missing, tell the user to run the init flow first (`/agentic-analytics:init` on harnesses with slash commands, or "set up agentic analytics" in chat) and stop. Do not guess values.40412. **Offer the lighter alternative, every time.** Before deleting anything, explain the trade-off and ask which the user wants. Always ask – don't skip this because the user's phrasing sounds decisive ("wipe it", "start over"); the cost of asking is one message, the cost of an unnecessary multi-gigabyte wipe-and-re-pull is real. Say something like:4243 > Refreshing the cache for '`<cache_dir>`' deletes **everything** currently cached and re-pulls the full 60-day window from S3 – can take a while. If you just want the newest data without losing what's already cached, `update-cache` does that instead and is much faster.44 >45 > Full refresh (delete + re-pull) – use this for stale/corrupt data, schema drift, or a bad prior pull. Or: update only (no deletion, just top up).4647 - If the user picks **update only**: follow the update-cache skill's steps in this same turn (announce, then run `pull_parsely_dpl.py` incrementally with no delete step, then report) using the `bucket`/`profile`/`cache_dir` already loaded in step 1. Stop here – do not continue to step 3.48 - If the user picks **full refresh**: continue to step 3.49503. **Announce.** Output verbatim:5152 > Refreshing the local cache. Config (bucket.json, AWS profile) will be left alone.53544. **Delete the cache.** Runs the deletion script. Reports which dirs it cleared and the bytes freed, or `(nothing to clear)`:5556 ```bash57 "$plugin_python" "$plugin_root/scripts/refresh_cache.py"58 ```59605. **Re-pull a fresh 60 days.** Same window the staircase report targets. `pull_parsely_dpl.py` is incremental and idempotent; after a wipe it pulls the full window once and also rebuilds the `dpl_events` catalog view.6162 ```bash63 read target_start target_end < <(python3 -c "64 from datetime import date, timedelta65 start = date.today() - timedelta(days=60)66 end = date.today() - timedelta(days=1)67 print(start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d'))68 ")69 "$plugin_python" "$plugin_root/scripts/db/pull_parsely_dpl.py" \70 --bucket <bucket> [--site <site>] \71 --start "$target_start" --end "$target_end" \72 [--profile <profile>]73 ```7475 Substitute `<bucket>` and `<profile>` with the values held from step 1. Omit `--site` to refresh all sites; pass `--site <site>` to limit the pull to one site. Do NOT add `|| true` here – unlike the report path, a failed re-pull is the headline result of this flow; surface it.76776. **Report done.** One short line: "Cache rebuilt. Next report run uses fresh data."7879 If the re-pull failed (auth lapse, S3 error, no events for the window), say so plainly and tell the user the lake is now empty – the next report run will try to pull again, or they can re-run this flow once auth is fresh.8081## Notes8283- Only the **currently configured** customer's DPL data is affected. The lake root holds all sources/sites pooled under `$AGENTIC_ANALYTICS_DATA_DIR` (default `~/.local/share/agentic-analytics`); deletion is scoped to the `dpl/events/` subtree and the catalog, so other data you may later land in the lake is untouched. To work with a different customer, switch `bucket.json` first.84- Deletion is **not** scoped to a single site even when the re-pull afterward is – `refresh_cache.py` always clears the whole `dpl/events/` subtree (every site/apikey under the configured bucket). Passing `--site <site>` to step 5 only limits what gets re-pulled, not what got deleted. If you only want to top up or repair one site's data without touching the rest, use update-cache instead – it never deletes.85- The DuckDB catalog (`catalog.duckdb` and its `.wal` sidecar) is cleared too. It's derived state any report can regenerate by re-running `pull_parsely_dpl.py`.86- **Legacy gz cache sweep:** if you're upgrading from a pre-lake version, this flow also clears the old gz-JSON cache at `~/.cache/agentic-analytics/dpl/<cache_dir>/` and the `duckdb-tmp/` working dir (scoped to your `cache_dir`). The lake code never reads them; sweeping just reclaims the orphaned disk. No-op for fresh installs.