Find Hypertable Candidates
timescale/pg-aiguide
A skill your agent uses to analyze an existing PostgreSQL database and identify which tables should be converted to Timescale/TimescaleDB hypertables.
Find every OWID surface that references a chart, indicator, MDIM, or explorer — articles (links vs embeds), explorers, narrative charts, data insights, static viz, key-chart slots, MDIM views.
$ npx skills add owid/etl --skill find-chart-references -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install owid/etl find-chart-references --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/owid/etl.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/find-chart-references .claude/skills/find-chart-references && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "find-chart-references" agent skill from https://github.com/owid/etl/tree/master/.claude/skills/find-chart-references into .claude/skills/find-chart-references/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "find-chart-references", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/owid/etl/tree/master/.claude/skills/find-chart-referencesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add owid/etl --skill find-chart-references -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install owid/etl find-chart-references --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/owid/etl.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/find-chart-references .agents/skills/find-chart-references && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "find-chart-references" agent skill from https://github.com/owid/etl/tree/master/.claude/skills/find-chart-references into .agents/skills/find-chart-references/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "find-chart-references", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add owid/etl --skill find-chart-references -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install owid/etl find-chart-references --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/owid/etl.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/find-chart-references .cursor/skills/find-chart-references && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "find-chart-references" agent skill from https://github.com/owid/etl/tree/master/.claude/skills/find-chart-references into .cursor/skills/find-chart-references/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "find-chart-references", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/owid/etl.git --path .claude/skills/find-chart-references--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add owid/etl --skill find-chart-references -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install owid/etl find-chart-references --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/owid/etl.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/find-chart-references .gemini/skills/find-chart-references && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "find-chart-references" agent skill from https://github.com/owid/etl/tree/master/.claude/skills/find-chart-references into .gemini/skills/find-chart-references/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "find-chart-references", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install owid/etl find-chart-referencesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add owid/etl --skill find-chart-references -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/owid/etl.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/find-chart-references .github/skills/find-chart-references && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "find-chart-references" agent skill from https://github.com/owid/etl/tree/master/.claude/skills/find-chart-references into .github/skills/find-chart-references/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "find-chart-references", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add owid/etl --skill find-chart-references -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install owid/etl find-chart-references --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/owid/etl.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/find-chart-references .opencode/skills/find-chart-references && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "find-chart-references" agent skill from https://github.com/owid/etl/tree/master/.claude/skills/find-chart-references into .opencode/skills/find-chart-references/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "find-chart-references", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
find-chart-referencesFind every OWID surface that references a chart, indicator, MDIM, or explorer — articles (links vs embeds), explorers, narrative charts, data insights, static viz, key-chart slots, MDIM views.
Find Chart References is an agent skill from owid/etl. Find every OWID surface that references a chart, indicator, MDIM, or explorer — articles (links vs embeds), explorers, narrative charts, data insights, static viz, key-chart slots, MDIM views. Answers "what breaks or goes stale if this changes or goes away", and distinguishes surfaces a URL redirect fixes from surfaces that render the object themselves. Read-only, pure SQL. Trigger when the user asks "what references this chart/indicator", "where is this chart embedded", "what's the blast radius of this change"…
Its SKILL.md is about 4.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including scripts (for example `scripts/find_references.py` and `scripts/reference_report.py`).
It sits in Data & Analytics, covering SQL. It works with SQL. The repository describes itself as: A compute graph for loading and transforming OWID's data. The licence is MIT.
Read from SKILL.md and the folder at commit bf5dc8e. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 2 files in scripts/ (Python), which the agent can run.
Shell commands in SKILL.md call:
pythonFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
docs.google.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
ADMIN_API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Find Chart References loads about 4.9k tokens when it runs. Until then it costs about 187 tokens; SKILL.md has 2,640 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from owid/etl at commit bf5dc8e, republished under its MIT licence (© owid). 2,640 words, ~4,892 tokens.
.claude/skills/find-chart-references/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.One question — what would break, go stale, or need editing if this object changed or went away? — asked the same way for every grapher object, so each skill that needs it stops re-deriving its own surface list.
For how to point at the right database, see query-grapher-db. Everything here is
read-only SQL and needs no ADMIN_API_KEY.
kind field is the pointEvery finding carries a kind that decides what a fix costs:
| kind | meaning | does a URL redirect fix it? |
|---|---|---|
render | the surface resolves the object and draws it — a chart on an indicator, an MDIM view, an explorer view, a key-chart slot | n/a — the object is the content |
embed | the surface holds it by id/slug and renders its config directly — article chart blocks, data insights, static viz, explorers, narrative charts pinned to an MDIM view | No. Must be migrated by hand |
link | a hyperlink in prose or a raw URL | Yes — but the href is still worth updating |
The discriminator for articles is posts_gdocs_links.componentType: a span-*
value is a hyperlink inside body text; anything else is a block-level component
that renders the chart. Skills that only count rows in posts_gdocs_links cannot
tell these apart, and will report an embed as if a redirect covered it.
ENV_FILE=<creds> DATA_API_ENV=production .venv/bin/python \
.claude/skills/find-chart-references/scripts/find_references.py \
--chart-slugs life-expectancy,child-mortality \
--json ai/refs.json --csv ai/refs.csvSubjects (combinable): --chart-ids · --chart-slugs · --variable-ids ·
--dataset-id · --mdim <slug|catalogPath> · --explorer <slug>.
--transitive adds a second hop for indicator subjects only: after finding the
charts that render an indicator, sweep the articles referencing those charts. Off by
default — it multiplies the work on a widely-charted dataset. It changes nothing for a
--mdim or --explorer subject (their references are all direct), and the run says so
rather than letting the flag imply a wider sweep than it made.
Output rows: subject_type, subject, subject_id, surface, kind, where, where_path, surface_id, config_id, context, query_string, text, published.
Two fields carry the weight for callers:
config_id — the surface's chart_configs.id, present for every
config-bearing surface (charts, MDim views, explorer views, narrative charts). This
is what lets a caller inspect configs without re-deriving any joins: a single
SELECT ... FROM chart_configs WHERE id IN (...) covers charts, MDim views and
explorer views alike. One exception: for a narrative chart read
AdminAPI.get_narrative_chart(id)["configFull"] instead — the stored row lags a
parent edit until the child is re-saved. A row with an empty config_id has no
config to read: the explorer surface (as opposed to explorer view) is the
fallback for an indicator registered on an explorer whose view configs never name
it, and article, static-viz and key-chart rows never had one.query_string — the reference's own URL params (country=, time=, tab=),
where article-level pins live and what makes a replacement URL reconstructable.admin_url is the chart's editor in whichever environment was audited — a
staging sweep yields staging admin links, a production sweep yields admin.owid.io
(tailscale suffixes are stripped, since the short host resolves and the long one is
noise). MDim views deliberately have none: they are not editable in the admin, and
their fix belongs in the ETL YAML.
surface_id identifies the surface object itself (chart id,
multi_dim_x_chart_configs.id, narrative chart id, explorer slug, tag id), for when
you need to edit it rather than read it. For any gdoc-backed surface (articles,
data insights) it is the Google Doc id — posts_gdocs.id is literally the Doc id,
so https://docs.google.com/document/d/<surface_id>/edit opens the source document.
--markdown — the report to hand a human--markdown ai/refs.md renders one table per surface, grouped by kind, so a
long list stays scannable. For every article reference the table gives three ways to
reach it:
#:~:text= fragment,
built the same way as chart_diff/citations.py:create_text_fragment_url), which
opens the page scrolled to and highlighting the exact sentence.Every row also gets a 👁 preview — the referenced view itself, as the reader sees it: the chart plus that reference's own params, or the MDIM at that view's exact dimensions. A slug alone doesn't tell you which of an MDIM's hundred views is in play, so this is what makes a row judgeable without opening the article.
Block embeds have no anchor text, so those fall back to the plain article URL.
Indicator subjects are labelled with the indicator's name (not a bare variable id),
cells are truncated and pipe-escaped so the tables can't break, and drafts are marked
⚠️. For spreadsheet work use --csv, which carries the untruncated values.
Optional surfaces fail open (an absent legacy table, a subject that does not
resolve): the run keeps going and prints COVERAGE GAP: ... for each, then repeats
them all at the end. Read that block before reporting a result — those surfaces
were not swept, so an empty answer for them means UNKNOWN, not "nothing references
it". --gaps-json <path> writes the same list as JSON, which is how a wrapper
carries them into its own report instead of leaving them in stdout.
What is swept, per subject type. Anything not on this list is not covered — say so rather than implying full coverage.
Chart subjects (expanded to every old slug that still reaches the chart, since references written before a rename point at the old one):
| surface | source | kind |
|---|---|---|
| articles | posts_gdocs_links (grapher, guided-chart) + linkType='url' scan | embed or link by componentType |
| explorers | explorer_charts (by chart id) | embed |
| narrative charts | narrative_charts.parentChartId | link (renders its own config) |
| ↳ its placements | posts_gdocs_links where linkType='narrative-chart', target = the name; plus data insights whose front matter names it (posts_gdocs.content->>'$."narrative-chart"'), which write no link row | embed, surface gdoc (narrative chart) |
| data insights | posts_gdocs.content->>'$."grapher-url"' | embed |
| static viz | static_viz.grapherSlug | embed |
| key charts | chart_tags where keyChartLevel > 0 | render |
| featured metrics | featured_metrics matched on pathname (the table is read whole) | render |
Narrative charts get a second hop, always (sweep_articles_placing_narrative_charts, run over the findings after every sweep — it needs no --transitive). A narrative chart is not itself in an article; articles place it by name in a {.narrative-chart} block. So a narrative-chart row alone says what has to change and not where the change lands, and every fix for one includes an article edit. Same table and column the admin's own references endpoint reads (getNarrativeChartReferences → getPublishedLinksTo(…, ContentGraphLinkType.NarrativeChart)), with one deliberate difference: unpublished drafts are kept, because a draft referencing the name is exactly what surprises you at delete time. published rides along so a consumer can rank it below the live ones.
The placement rows carry the narrative chart as subject (not the chart that reached it), because find_in_doc falls through to subject when there is no anchor text — and the name is precisely what the ArchieML block spells out, so the search string comes out right for free. text is forced empty for the same reason.
A featured metric is the one render surface a redirect does not rescue. Like a key chart
it is a topic-page slot in no reference table — but held by URL, and resolved only when
Algolia indexes, matching pathname and the exact query-param map against published records.
So retiring what it names empties the slot silently, and re-adding the old URL is then refused
(creating a row validates that the slug resolves to something published). It must be swapped by
hand, before the migration — see docs/guides/data-work/redirect-to-mdims.md.
Matching is on pathname alone, deliberately: for an MDIM or explorer the row's query string
is the view, so a params-equal test would hide the rows a migration most needs to see — those
whose params no longer name a live view. The params travel in query_string instead. One object
can hold several rows; the key is (url, parentTagId, incomeGroup).
WordPress (posts / posts_links) is not swept, and adding it back would be a
regression. Every published post there that links a chart 404s on the live site, and none
of those slugs exists as a published gdoc — they are a dead mirror, not migrated content.
Indicator subjects: charts (chart_dimensions), MDIM views
(multi_dim_x_chart_configs plus a config scan — that column records only the
first y indicator, so multi-indicator views are invisible to the join alone),
explorer views (explorer_variables narrows to the explorers involved, then each
one's explorer_views → chart_configs says which of its views actually render the
indicator). Explorer views are emitted one row per view, so a dataset powering a
large explorer yields hundreds of rows — that is the price of every row carrying a
config_id. Under --transitive, also the narrative charts parented to any chart
or MDIM view that renders the indicators (parentMultiDimXChartConfigId): a
narrative chart holds its own config, so skipping that hop leaves it unaudited —
and the featured metrics held by those charts, which no other hop reaches.
MDIM findings are keyed by (mdim, view, indicator), not by view: one view can
render several of the requested indicators, and each one is its own reference. The
config scan resolves every stored indicator shape (an id, a {id: …} dict, a
{catalogPath: …} dict, or a bare catalog-path string), so a view holding a
catalog path is not silently skipped.
MDIM subjects: article links/embeds, narrative charts pinned to a view
(parentMultiDimXChartConfigId), inbound multi_dim_redirects, and featured metrics —
an MDIM's rows sit under /grapher/<slug>, the same namespace as a chart's, because
multi-dims are served from /grapher/. A row with no query string names the default view.
Explorer subjects: article links/embeds (linkType='explorer') plus a
linkType='url' scan, as for charts and MDIMs — an article that pastes
/explorers/<slug>?… produces a url-typed row, and only that row carries the
country=/time= pins the downstream audits grade. Also featured metrics, under
/explorers/<slug>; an explorer's row always carries a query string, since the admin
refuses one without it.
Raw-URL targets are un-wrapped before matching: a link pasted through Google Docs can
arrive as google.com/url?q=<encoded> (or ?url=<encoded>), with the real URL and its
parameters inside. Every raw-URL sweep keeps wrapper rows as SQL candidates and decides
the path in Python, because the url= form percent-encodes its slashes and a
LIKE '%/grapher/<slug>%' prefilter would drop it before it could be decoded.
This skill answers which surfaces reference the object. It deliberately does not interpret them — each caller keeps the analysis only it can do:
| Skill | Uses the sweep for | Keeps |
|---|---|---|
check-hardcoded-years | the surface list for a dataset/indicator, plus each reference's query_string (article time= pins) | reading configs for minTime/maxTime/map.time, grading pins against the data's latest time, the where-the-fix-goes table |
check-empty-entities | the same list, plus query_string (country= pins) and old-slug expansion | entity-selection vs entities-with-data checks, grading findings against production |
update-dataset (step 7) | one sweep shared by both audits above | the update workflow around them |
review-data-pr (§8d) | a cheap "which surfaces carry this dataset" check | judging whether the author's audit was complete |
map-charts-to-mdim | the sweep for the charts being redirected | replacement URLs, redirect severity, param-collision detection |
edit-faust-metadata | — (keeps blast_radius.py) | per-field inheritance analysis: which surfaces are shielded by their own patch override, which have no inheritance path. A generic sweep can't answer that |
When a caller needs a surface this doesn't cover, add it here rather than locally — that's the point of the split.
State these when reporting; silence reads as full coverage. --markdown now ends with
a Not searched section carrying this list plus the limits of that particular run
(no --transitive hop, excluded 'All charts' entries) — keep the two in step, and
still state them yourself when you report on a --json/--csv run.
Optional surfaces fail open: an absent legacy table or a subject that does not
resolve prints COVERAGE GAP: …, is repeated at the end of the run, leads the
report's Not searched section, and is available as JSON via --gaps-json <path>
for a wrapper that builds its own report. An empty answer for one of those surfaces
means UNKNOWN, not "nothing references it".
explorers TSV are not parsed.data://explorers/... wide tables — e.g. the
poverty explorer) appear in no DB table: their data and selections live in the
explorer TSV, outside grapher configs. Report them as a coverage caveat rather
than letting them pass silently.linkType='url' rows pointing at archive.ourworldindata.org are dropped as
frozen by design. As of 2026-07 every url-typed grapher row was an archive
snapshot — don't bet an audit on that classification continuing to hold.presentation.grapher_config lives in garden/grapher
.meta.yml, not the DB. It is invisible here and needs a repo grep, and it fans
out to every thin MDim/explorer view that inherits it.grapher-url (charts) and narrative-chart (narrative
charts) in their front matter; one storing the reference elsewhere is missed.posts_gdocs_links recorded — charts nested inside
layout containers may not produce a row.posts_gdocs_links lags; verify article fixes against the
live page, not the mirror.link, not an embed, and a redirect covers it — don't gate a migration on it.
Do check the href's query params, which ride along to the target.
There is still no API to repoint a narrative chart
(parentChartId/parentMultiDimXChartConfigId are written only at creation —
updateNarrativeChart reads both off the existing row), so the parent pointer
stays stale. That matters for a narrative chart pinned to an MDIM view — that
one is a genuine embed, and it can block the MDIM's next re-publish via an
unguarded FK.CreateNarrativeChartEditorPage
returns NotFoundPage unless type === "multiDim", and the site-side affordance
is gated on manager.adminCreateNarrativeChartPath, set only by
site/multiDim/MultiDim.tsx and MultiDimDataPageContent.tsx. The POST route does
accept {"type": "chart", "parentChartId": …}, so for a chart parent the API is the
only path — there is no click-path to it at all.target_query_param merges with the incoming query key by key,
the incoming side winning per key. A reference's params cost the reader exactly the
stored keys they collide with. Verified on production 2026-08-14 with a distinguishing
pair — global-forestry-area-1958-2014 → forest-area-km?tab=line sends a bare
?country=~FRA on to ?tab=line&country=%7EFRA (stored tab=line SURVIVES), and
?tab=map&country=~FRA on to ?tab=map&country=%7EFRA (incoming tab wins). A test
whose query sets every stored key cannot tell merge from wholesale replacement — an
earlier version of this note concluded "wholesale" from exactly that. Staging's serving
layer and a fresh row's first-week static 302 both behave differently (stored query wins,
visitor params dropped — both verified live 2026-08-14). Do not generalize from
functions/_common/redirectTools.ts: its explorer path also merges per key but with
the TARGET winning — the opposite winner, and a different code path.
MDIM dimension collisions are the same question — compare each reference's
query_string against the target's dimension slugs — but the answer is stronger than
"the reference overrides that one key": it discards the target's whole query.docs/guides/data-work/redirect-to-mdims.md.REFERENCE_DIGEST_FIELDS
in reference_report.py hashes the findings and map-explorer-to-mdim's preflight gates on
it, so an audit predating a surface reads as drifted and blocks until re-run. That is correct
— it really is stale — but say so, or it looks like a bug.When a run reveals a surface this catalog misses, add it here — this file is the shared list, and a gap fixed here fixes it for every skill that reads it.
© owid, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (scripts) in .claude/skills/find-chart-references of owid/etl.
Open the folder on GitHubat commit bf5dc8e
Find Chart References next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Find Chart References this skillowid/etl | 158 | — | ~4.9k | Automated safety check: Pass | MIT | |
| Find Hypertable Candidatestimescale/pg-aiguide | 1.9k | 1 repos | ~2.6k | Automated safety check: Pass | Apache-2.0 | |
| SlKaelio/ktx | 1.6k | — | ~2.7k | Automated safety check: Pass | Apache-2.0 | |
| Dinobase Business Data Querieskappa90/dinobase | 263 | — | ~1.5k | Automated safety check: Pass | Custom licence | |
| Analytics Engineerborghei/Claude-Skills | 881 | — | ~3.4k | Automated safety check: Pass | MIT | |
| Monte Carlo Validation Notebooksickn33/agentic-awesome-skills | 47k | 1 repos | ~1.1k | Automated safety check: Pass | MIT |
timescale/pg-aiguide
A skill your agent uses to analyze an existing PostgreSQL database and identify which tables should be converted to Timescale/TimescaleDB hypertables.
Kaelio/ktx
ktx's semantic layer - a structured catalog of sources (tables/views), measures, joins, and segments expressed as YAML.
kappa90/dinobase
Sets up Dinobase, a local DuckDB database that syncs data from 100+ business sources, then answers questions across them with SQL joins and previewed write-backs.
borghei/Claude-Skills
Analytics engineering across data modeling, dbt, transformation, and semantic layers.
sickn33/agentic-awesome-skills
Generates SQL validation notebooks for dbt PR changes with before/after comparison queries.
PostHog/posthog
Creates product analytics or SQL-backed box plot insights in PostHog.
owid/etl
Add a scatter view (with GDP per capita on x) to existing OWID charts via the admin API, mirroring the admin UI's "Add scatter type" defaults, then retire the old standalone "X vs.
owid/etl
Add new survey question codes (e.g. An agent skill from owid/etl.
owid/etl
Build or refresh an OWID static visualization end to end — resolve what data it needs from an old static viz image, an indicator, or a grapher chart; check both the ETL catalog and the producer's…
owid/etl
Propose redirects from (soon-to-sunset) grapher charts to the matching views of published MDIMs.
owid/etl
Take (soon-to-sunset) OWID explorers to redirected MDIMs, end to end.
owid/etl
Check chart or multidim preview on the staging server using a browser.
Works with
Categories
Find every OWID surface that references a chart, indicator, MDIM, or explorer — articles (links vs embeds), explorers, narrative charts, data insights, static viz, key-chart slots, MDIM views. Find Chart References is an agent skill from owid/etl. Find every OWID surface that references a chart, indicator, MDIM, or explorer — articles (links vs embeds), explorers, narrative charts, data insights, static viz, key-chart slots, MDIM views.
Find Chart References fits situations like: the user asks what references this chart/indicator; where is this chart embedded; whats the blast radius of this change; which articles link to X.
Run `npx skills add owid/etl --skill find-chart-references -a claude-code`. Or copy the skill folder (.claude/skills/find-chart-references in owid/etl) into .claude/skills/find-chart-references in your project. Claude Code loads it when a task matches its description.
Run `npx skills add owid/etl --skill find-chart-references -a codex`. Or copy the skill folder (.claude/skills/find-chart-references in owid/etl) into .agents/skills/find-chart-references in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add owid/etl --skill find-chart-references -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/find-chart-references, .gemini/skills/find-chart-references, .github/skills/find-chart-references and .opencode/skills/find-chart-references in your project.
Going by SKILL.md and its folder, Find Chart References needs Python for the scripts in its folder, the command-line tools its instructions call (python) and credentials named ADMIN_API_KEY. Our summary lists: Python 3; A credential in ADMIN_API_KEY.
SKILL.md names 1 domain. In commands or code: docs.google.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Find Chart References is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.9k tokens (SKILL.md is roughly 20k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Find Chart References: Find Hypertable Candidates (timescale/pg-aiguide, 1.9k stars), Sl (Kaelio/ktx, 1.6k stars), Dinobase Business Data Queries (kappa90/dinobase, 263 stars) and Analytics Engineer (borghei/Claude-Skills, 881 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
owid (a GitHub organization) maintains it in owid/etl, which has 158 GitHub stars. The repository holds 35 skills in this directory. The repository was last updated on October 8, 2026.
Source: owid/etl on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.