Evolving The Data Model
TriliumNext/Trilium
A skill your agent uses when adding a DB migration or a new column/field to a Becca entity in Trilium ("add a migration", "new column on notes/attributes", "ALTER TABLE", "add a field to…
Activate this skill for DataJunction (DJ) semantic modeling decisions — choosing the right node shape (fact, dimension, transform, metric, cube), turning a draft SQL query into well-designed nodes…
$ npx skills add DataJunction/dj --skill datajunction-semantic-model -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install DataJunction/dj datajunction-semantic-model --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/DataJunction/dj.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/datajunction/skills/datajunction-semantic-model .claude/skills/datajunction-semantic-model && 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 "datajunction-semantic-model" agent skill from https://github.com/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-model into .claude/skills/datajunction-semantic-model/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "datajunction-semantic-model", 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/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-modelType 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 DataJunction/dj --skill datajunction-semantic-model -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install DataJunction/dj datajunction-semantic-model --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/DataJunction/dj.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/datajunction/skills/datajunction-semantic-model .agents/skills/datajunction-semantic-model && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "datajunction-semantic-model" agent skill from https://github.com/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-model into .agents/skills/datajunction-semantic-model/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "datajunction-semantic-model", 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 DataJunction/dj --skill datajunction-semantic-model -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install DataJunction/dj datajunction-semantic-model --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/DataJunction/dj.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/datajunction/skills/datajunction-semantic-model .cursor/skills/datajunction-semantic-model && 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 "datajunction-semantic-model" agent skill from https://github.com/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-model into .cursor/skills/datajunction-semantic-model/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "datajunction-semantic-model", 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/DataJunction/dj.git --path plugins/datajunction/skills/datajunction-semantic-model--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 DataJunction/dj --skill datajunction-semantic-model -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install DataJunction/dj datajunction-semantic-model --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/DataJunction/dj.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/datajunction/skills/datajunction-semantic-model .gemini/skills/datajunction-semantic-model && 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 "datajunction-semantic-model" agent skill from https://github.com/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-model into .gemini/skills/datajunction-semantic-model/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "datajunction-semantic-model", 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 DataJunction/dj datajunction-semantic-modelInstalls 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 DataJunction/dj --skill datajunction-semantic-model -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/DataJunction/dj.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/datajunction/skills/datajunction-semantic-model .github/skills/datajunction-semantic-model && 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 "datajunction-semantic-model" agent skill from https://github.com/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-model into .github/skills/datajunction-semantic-model/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "datajunction-semantic-model", 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 DataJunction/dj --skill datajunction-semantic-model -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install DataJunction/dj datajunction-semantic-model --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/DataJunction/dj.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/datajunction/skills/datajunction-semantic-model .opencode/skills/datajunction-semantic-model && 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 "datajunction-semantic-model" agent skill from https://github.com/DataJunction/dj/tree/main/plugins/datajunction/skills/datajunction-semantic-model into .opencode/skills/datajunction-semantic-model/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "datajunction-semantic-model", 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.
datajunction-semantic-modelActivate this skill for DataJunction (DJ) semantic modeling decisions — choosing the right node shape (fact, dimension, transform, metric, cube), turning a draft SQL query into well-designed nodes…
Datajunction Semantic Model is an agent skill from DataJunction/dj. Activate this skill for DataJunction (DJ) semantic modeling decisions — choosing the right node shape (fact, dimension, transform, metric, cube), turning a draft SQL query into well-designed nodes, and the cross-cutting conventions (ownership, naming, namespace organization). Format-agnostic modeling guidance. Keywords: - semantic modeling - decompose query, model query, query to nodes - how should I model this metric, what shape should this node be - design a cube, what belongs in this cube - ratio metric…
Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Databases, covering SQL. It works with SQL. The licence is MIT.
Read from SKILL.md and the folder at commit 904745e. 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.
No scripts in the folder and no shell commands in SKILL.md (its code samples are sql).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Datajunction Semantic Model loads about 4.3k tokens when it runs. Until then it costs about 186 tokens; SKILL.md has 1,717 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); files beside SKILL.md are not scanned.
The full file from DataJunction/dj at commit 904745e, republished under its MIT licence (© DataJunction). 1,717 words, ~4,291 tokens.
.claude/skills/datajunction-semantic-model/SKILL.md (or your agent's skills folder).Use this skill when designing how something gets expressed as DJ nodes — independent of whether you'll write the result as YAML files in a repo or POST it to the DJ API.
For DJ vocabulary (what node types exist, how dimension links work mechanically), see the datajunction skill. This skill assumes that vocabulary and focuses on the modeling decisions.
Before authoring a new node, check whether an authoritative one already exists. Use the datajunction-query skill's MCP tools (search_nodes, get_node_details) to find candidates. Every additional transform / dim / metric fragments the catalog; every reuse strengthens it.
When you can't find a fit:
datajunction-api's "Checking if a Namespace Is Repo-Backed" section for how to verify).Not just metrics — every DJ node should declare owners. The reasons apply uniformly across all node types:
Best practices:
owners field empty or omit it✅ GOOD — team ownership:
data-platform-team@company.com
finance-analytics@company.com
⚠️ ACCEPTABLE — individual ownership (less sustainable):
alice@company.com
❌ BAD — no owners (governance nightmare!)This applies to sources, transforms, dimensions, metrics, and cubes alike.
Use fully qualified names with namespace:
namespace.node_nameExamples:
finance.total_revenuecommon.dimensions.usersclean.user_eventsrevenue (missing namespace)Names should be readable and business-meaningful — what a stakeholder would call this thing, not the column transformations behind it. total_revenue over sum_amount_usd. avg_session_duration_secs over avg_session_dur.
Namespaces are organized by business area:
Common conventions:
common.dimensions.* — shared dimensions (users, dates, regions)finance.* — financial metrics & factsgrowth.* — user engagement & activationproduct.* — product usage & featuressource.* — raw source tablesA general spirit that runs through every layer:
The semantic layer has two goals working together:
DJ uses normalized star schema modeling. The decisions you make here shape everything downstream.
| Node | Used for | Examples |
|---|---|---|
| Source | Physical table in the warehouse | warehouse.finance.transactions_table |
| Dimension | An entity with attributes you'll slice by | users, products, dates, regions, geo_country |
| Transform | Cleaned/derived fact data — the aggregable rows | clean_transactions, daily_user_activity, enriched_orders |
| Metric | One aggregation expression over a transform | total_revenue, num_orders, avg_session_duration |
| Cube | A curated set of metrics + dimensions for downstream consumers | revenue_dashboard, weekly_orders_report |
When to author a transform vs use a source directly:
status IN ('complete', 'completed') → 'completed'), joining, or filtering before it represents the entity meaningfully.What does one row in your fact transform represent?
order_id(order_id, snapshot_date)(customer_id, month)Grains don't mix in one fact. If you find yourself with two different grains in one transform, you have two facts trying to live in one node — split them.
The DJ idiom: every JOIN that connects a fact to a dimension belongs in a dimension_links: declaration on the fact's transform — not inside a metric's query.
Why: dimension links make the join optional. Consumers slice by that dim only when they ask for it. A hardcoded JOIN in a metric forces every query that touches the fact to pay the join cost even when nobody's slicing by that dim. It also fragments behavior — metrics on the same fact would each carry their own copy of the same JOIN, with the inevitable drift.
Same applies to dim-to-dim joins (e.g., users → countries → regions) — express them as dimension links on the dimension node, creating a dimensional graph DJ can traverse automatically.
See the datajunction skill's "Dimension Links" section for the mechanics; this is about when to use them — which is essentially always.
A metric is one aggregation expression over a single source, transform, or dimension node.
Metrics cannot contain WHERE clauses
-- ❌ NOT ALLOWED — WHERE clause in metric
SELECT SUM(amount_usd)
FROM finance.transactions
WHERE status = 'completed'
-- ✅ CORRECT — use CASE WHEN
SELECT SUM(
CASE WHEN status = 'completed' THEN amount_usd ELSE 0 END
) FROM finance.transactionsA WHERE permanently constrains scope; CASE WHEN lets the metric coexist with a broader-population sibling on the same fact. Reflect the scope in the metric name (active_signups, not signups).
Metrics select a single expression from a single node
Build derived metrics by referencing other metrics in the query. Excellent for ratios, rates, and complex calculations.
-- Create base metrics first
SELECT COUNT(*) FROM finance.transactions -- metric: finance.transaction_count
SELECT SUM(amount_usd) FROM finance.transactions -- metric: finance.total_revenue
-- Then compose them into a derived metric
SELECT finance.total_revenue / finance.transaction_count -- metric: finance.avg_transaction_value
-- DJ handles divide-by-zero automatically; NULLIF() is optional safetyThis is the highest-leverage discipline in DJ metric modeling. Apply it even when "the user only cares about the final ratio."
❌ Less reusable — anonymous SQL blob:
SELECT SUM(amount_usd)
/ NULLIF(SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END), 0)
FROM finance.transactions✅ Reusable — three named, discoverable, composable metrics:
-- metric: total_revenue
SELECT SUM(amount_usd) FROM finance.transactions
-- metric: num_completed_orders
SELECT SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END)
FROM finance.transactions
-- metric: avg_order_value (derived)
SELECT total_revenue / NULLIF(num_completed_orders, 0)Why: the bottom shape gives three named metrics anyone can find, query, and reuse. The top shape gives one — the base aggregates are anonymous SQL blobs nobody else can reference. Different teams asking "what's our total revenue?" can't find it; they'd have to know to read inside avg_order_value's query.
Common shapes a metric can take. Each shows the query: expression — the actual file/API format lives in datajunction-repo or datajunction-api.
Base metrics (simple aggregations):
-- COUNT
SELECT COUNT(transaction_id) FROM finance.transactions
-- COUNT DISTINCT
SELECT COUNT(DISTINCT customer_id) FROM finance.transactions
-- APPROX_COUNT_DISTINCT (HyperLogLog — for large datasets)
SELECT APPROX_COUNT_DISTINCT(profile_id) FROM finance.transactions
-- SUM
SELECT SUM(amount_usd) FROM finance.transactions
-- AVG
SELECT AVG(amount_usd) FROM finance.transactions
-- Conditional aggregation
SELECT SUM(
CASE
WHEN status = 'completed' AND refund_flag = false
THEN amount_usd
ELSE 0
END
) FROM finance.transactionsDerived metrics (composed from base metrics):
-- ratio
SELECT finance.total_revenue / NULLIF(finance.transaction_count, 0)
-- rate as percentage
SELECT finance.clicks * 100.0 / NULLIF(finance.impressions, 0)
-- revenue per thousand impressions (RPM)
SELECT finance.total_revenue / NULLIF(finance.impressions, 0) * 1000Statistical metrics:
SELECT VAR_POP(amount_usd) FROM finance.transactions
SELECT STDDEV_POP(amount_usd) FROM finance.transactions
SELECT PERCENTILE_APPROX(amount_usd, 0.5) FROM finance.transactions -- median
SELECT PERCENTILE_APPROX(amount_usd, 0.95) FROM finance.transactions -- p95Rolling window metrics (set required_dimensions to include the ORDER BY dim):
-- trailing 7-day sum
SELECT SUM(finance.daily_revenue) OVER (
ORDER BY common.dimensions.date.dateint
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
)Period-over-period metrics:
-- week-over-week % change
SELECT
(finance.weekly_revenue - LAG(finance.weekly_revenue, 1) OVER (
ORDER BY common.dimensions.date.week_code
)) * 100.0 /
LAG(finance.weekly_revenue, 1) OVER (
ORDER BY common.dimensions.date.week_code
)Same shape for MoM (month_code), QoQ (quarter_code), YoY (year).
| Field | Required | Valid Values | Notes |
|---|---|---|---|
name | ✅ Yes | namespace.metric_name | Fully qualified name |
query | ✅ Yes | SQL SELECT expression | Single aggregation from single node |
description | ❌ Optional | String | Recommended for clarity |
direction | ❌ Optional | higher_is_better / lower_is_better / neutral | Indicates performance direction |
unit | ❌ Optional | dollar / unitless / ⚠️ NOT count | Server rejects count — use unitless |
mode | ❌ Optional | draft / published | Default: published |
fixed_grain | ❌ Optional | List of dimension names | Grain the aggregate is computed at; omit for query grain, [] for global |
required_dimensions | ❌ Optional | List of dimension names | For time-based / windowed metrics |
owners | ❌ Optional but strongly recommended | List of email addresses | Prefer team emails |
When a user arrives with an existing SQL query and wants to express it as DJ nodes, don't generate node definitions on the first pass. Propose a structured decomposition, get critique, iterate on the shape, then have the user create the nodes (in YAML via datajunction-repo, or via API via datajunction-api).
1. Parse the query mechanically. From the user's SQL, extract:
SUM, COUNT, COUNT DISTINCT, MIN, MAX, AVG,
APPROX_COUNT_DISTINCT, percentile/window aggregates) → each is a
candidate base metric.2. Resolve parents against existing nodes first. For each candidate parent table or dimension, use the datajunction-query skill's MCP tools (search_nodes, get_node_details) to check whether DJ already has an authoritative node for it. Prefer building on existing nodes — every additional transform fragments the catalog.
3. Treat every JOIN as a candidate dimension link, not a baked-in join. See "Joins → dimension links" above. The DJ idiom is to express joins as dimension_links: on the fact's transform, not hardcoded in the metric query.
4. Apply the reusability rule. Even if the user's query has aggregates only inside a ratio expression, decompose them: one named base metric per aggregate, then a derived metric for the ratio.
5. Handle WHERE clauses correctly. A WHERE in the user's query is one of two things:
CASE WHEN, not as a WHERE on the metric's query.6. Name things meaningfully. Propose readable, business-meaningful names that match what a stakeholder would call the metric or entity.
7. Check for duplicates before producing nodes. For each proposed metric / transform / dimension name, check whether something with the same name (or doing the same thing under a different name) already exists in the catalog. Reuse rather than recreate; rename when the names collide but the semantics differ.
8. Propose, don't produce. Present the decomposition as a structured list (parents, base metrics, derived metrics, dim links) and ask the user to critique the shape. Only after they confirm, hand off to datajunction-repo (for YAML) or datajunction-api (for curl) to produce the actual node definitions.
User's query:
SELECT
region_id,
SUM(amount_usd)
/ SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS avg_order_value
FROM finance.transactions
GROUP BY region_idDecomposition:
Parent transform:
Reuse: finance.transactions (existing)
Base metrics (one per aggregate):
1. total_revenue = SUM(amount_usd)
2. num_completed_orders = SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END)
Derived metric:
1. avg_order_value = total_revenue / NULLIF(num_completed_orders, 0)
Dimension links:
- region_id → common.dimensions.region (existing shared dim)Why this shape is worth the extra metric nodes: downstream tools re-aggregate the materialized output. Three independent metrics roll up correctly across any dimensional slice — sum the numerator, sum the denominator, then divide. A single pre-divided ratio doesn't compose: when consumers re-aggregate, the numerator and denominator can drift apart across slices in subtle ways (especially when NULL rows are dropped from one but not the other).
© DataJunction, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in plugins/datajunction/skills/datajunction-semantic-model of DataJunction/dj.
Open the folder on GitHubat commit 904745e
Datajunction Semantic Model 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 |
|---|---|---|---|---|---|---|
| Datajunction Semantic Model this skillDataJunction/dj | 161 | — | ~4.3k | Automated safety check: Pass | MIT | |
| Evolving The Data ModelTriliumNext/Trilium | 38k | — | ~2.1k | Automated safety check: Pass | AGPL-3.0 | |
| Orchardcore Data MigrationOrchardCMS/OrchardCore | 8.2k | — | ~1.7k | Automated safety check: Pass | BSD-3-Clause | |
| SQL Optimization Patternsynulihao/AgentSkillOS | 617 | 11 repos | ~3.3k | Automated safety check: Pass | None | |
| SQL PortabilityHL7/sql-on-fhir | 150 | — | ~512 | Automated safety check: Pass | Custom licence | |
| StmoSAP/project-foxhound | 180 | 2 repos | ~1.8k | Automated safety check: Pass | GPL-3.0 |
TriliumNext/Trilium
A skill your agent uses when adding a DB migration or a new column/field to a Becca entity in Trilium ("add a migration", "new column on notes/attributes", "ALTER TABLE", "add a field to…
OrchardCMS/OrchardCore
Creates and updates OrchardCore data migrations (DataMigration classes with CreateAsync/UpdateFromX).
ynulihao/AgentSkillOS
Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries.
HL7/sql-on-fhir
Analyse whether a SQL query is portable across database implementations using sqlglot transpilation.
SAP/project-foxhound
Manage Redash queries and dashboards on Mozilla's STMO (sql.telemetry.mozilla.org) using stmo-cli.
kurealnum/dotfiles
A skill your agent uses when generating or regenerating Drizzle migration files, changing database schema tables or columns, resolving migration sequence conflicts after rebase, reviewing migration…
DataJunction/dj
Activate this skill whenever working with DataJunction (DJ) semantic layer.
DataJunction/dj
Activate this skill when authoring DataJunction (DJ) nodes via the REST API directly (curl, HTTP clients) — typically for exploration, ad-hoc prototyping, or namespaces that aren't repo-backed.
DataJunction/dj
Activate this skill for querying DataJunction (DJ) — finding nodes, generating SQL, fetching metric data, exploring lineage, visualizing results — via the DJ UI, MCP tools, or REST/GraphQL APIs.
Works with
Categories
Activate this skill for DataJunction (DJ) semantic modeling decisions — choosing the right node shape (fact, dimension, transform, metric, cube), turning a draft SQL query into well-designed nodes…. Datajunction Semantic Model is an agent skill from DataJunction/dj. Activate this skill for DataJunction (DJ) semantic modeling decisions — choosing the right node shape (fact, dimension, transform, metric, cube), turning a draft SQL query into well-designed nodes, and the cross-cutting conventions (ownership, naming, namespace organization).
Datajunction Semantic Model fits situations like: tasks that involve SQL.
Run `npx skills add DataJunction/dj --skill datajunction-semantic-model -a claude-code`. Or copy the skill folder (plugins/datajunction/skills/datajunction-semantic-model in DataJunction/dj) into .claude/skills/datajunction-semantic-model in your project. Claude Code loads it when a task matches its description.
Run `npx skills add DataJunction/dj --skill datajunction-semantic-model -a codex`. Or copy the skill folder (plugins/datajunction/skills/datajunction-semantic-model in DataJunction/dj) into .agents/skills/datajunction-semantic-model 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 DataJunction/dj --skill datajunction-semantic-model -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/datajunction-semantic-model, .gemini/skills/datajunction-semantic-model, .github/skills/datajunction-semantic-model and .opencode/skills/datajunction-semantic-model in your project.
SKILL.md names no scripts, command-line tools or credentials: Datajunction Semantic Model is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. 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. Review the folder before installing.
Datajunction Semantic Model 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.3k tokens (SKILL.md is roughly 17k 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 Datajunction Semantic Model: Evolving The Data Model (TriliumNext/Trilium, 38k stars), Orchardcore Data Migration (OrchardCMS/OrchardCore, 8.2k stars), SQL Optimization Patterns (ynulihao/AgentSkillOS, 617 stars) and SQL Portability (HL7/sql-on-fhir, 150 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
DataJunction (a GitHub organization) maintains it in DataJunction/dj, which has 161 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 7, 2026.
Source: DataJunction/dj on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.