Skill-Atlas

agent
Security Audit
Pass
Health Pass
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 10 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Skill-Atlas

README.md
Skill Atlas

Skill Atlas

🔎 Query your whole skill collection at ~85% fewer tokens

A third tier for Claude Code skills — dormant, zero tokens, still findable.
Search a graph of your collection instead of preloading it.

53 skills, 6 kept enabled: 2,544 → 338 tokens per session (−86.7%). The other
47 cost nothing until asked for.

CI

The atlas, scope view


⚡ Install

claude plugin marketplace add danielLublinsky/Skill-Atlas
claude plugin install skill-atlas@skill-atlas

Python 3 only — no dependencies, no network (d3 is vendored).

Update. New versions arrive on their own — Claude Code refreshes marketplaces
periodically and picks up the new version, applying it on the next restart. To
pull one immediately:

claude plugin marketplace update skill-atlas
claude plugin update skill-atlas@skill-atlas

Then restart Claude Code — the update is staged until you do.

From a local clone (for hacking on it)
git clone https://github.com/danielLublinsky/Skill-Atlas.git
claude plugin marketplace add ./Skill-Atlas
claude plugin install skill-atlas@skill-atlas

▶️ Run

Command What it does
/skill-atlas Build the graph, categorize what's new, render atlas.html. Run this once to set up.
/skill-atlas:edit-searchable Move plugins in and out of the searchable tier, interactively.
/skill-atlas:skill-search Find the right skill for a task across the whole library, dormant tier included. Usually you never type this — Claude calls it on its own before a nontrivial task.
(automatic) A SessionStart hook keeps everything fresh after that.

Then open ./.claude/skill-atlas/atlas.html in a browser, and just ask for a
task — the search runs itself, names the skill it picked in one line, and gets
on with the work.

Without the plugin (Makefile)
make build    # graph.json + catalog/ from your live manifests
make render   # atlas.html
make check    # CI gate: exit 1 on any broken reference or dangling mention
make test     # unit suite against fixtures — never touches the real ~/.claude
make release  # bump both manifests, validate, test — never commits or pushes

The plugin cache is keyed by version, so a push without a bump ships no code to
anyone already installed. make release (or BUMP=minor, VERSION=1.0.0) is
what makes a change land.


🎯 The problem

Claude Code injects every enabled skill's description into every session —
~48 tokens each. At 100+ skills that's thousands of tokens you pay for constantly,
and near-duplicates quietly compete for the model's attention.

Disabling fixes the cost and loses the skill. So Skill Atlas adds a tier in between:

Tier In context? Findable? Cost / session
🟢 enabled yes natively ~48 tokens each
🟣 searchable no via skill-search 0
disabled no no 0

A searchable skill is dormant — its description never enters your context, but
it stays discoverable on demand. All that advertises the whole dormant tier is one
~50-token line at session start.

🔍 Search reads two files, not the catalog

flowchart LR
    A(["🧭 a task arrives<br/><i>“resolve this merge conflict”</i>"])

    subgraph R1["1️⃣ read the index · ~1.6k tok"]
        I["<b>_index.md</b> — 14 lines<br/><i>name · count · what it covers · member tokens</i>"]
    end

    subgraph R2["2️⃣ read one shard · ~0.6k tok"]
        S["<b>version-control.md</b><br/>using-git-worktrees<br/>resolving-merge-conflicts ← hit"]
    end

    X["the other 13 shards<br/><i>~10k tok · never opened</i>"]

    A --> I
    I -- "pick ONE category" --> S
    I -. skipped .-> X
    S --> E["🟢 <b>enabled</b><br/><i>invoke natively</i>"]
    S --> F["🟣 <b>searchable</b><br/><i>read its path,<br/>follow as instructions</i>"]

    classDef file stroke:#8a8578,stroke-width:1.5px
    classDef ghost fill:transparent,stroke:#8a8578,stroke-width:1.5px
    classDef hit fill:#1baf7a26,stroke:#1baf7a,stroke-width:2px
    classDef dormant fill:#8a5cd626,stroke:#8a5cd6,stroke-width:2px
    classDef muted fill:transparent,stroke:#8a8578,stroke-width:1px,stroke-dasharray:4 3
    class I,S file
    class A ghost
    class E hit
    class F dormant
    class X muted
    style R1 fill:#3987e514,stroke:#3987e5,stroke-width:1.5px
    style R2 fill:#3987e514,stroke:#3987e5,stroke-width:1.5px

A search costs ~2.4k tokens — the index (1.6k), one shard (~0.6k) and the
search skill itself (0.4k) — and you pay it only when a search happens. The
alternative it replaces is every dormant description sitting in context from
session start, billed whether you search or not. The arbitrage is real when
searches are occasional; it is not free, and the numbers above are measured
rather than estimated.

One shard is the norm. A second is opened only when the entry you found lists a
category you haven't read — the catalog pointing, not the model guessing — and
never a third. Counts overlap on purpose, so the pick doesn't have to land on
the right bucket, only a right one. Tier-off skills are excluded when shards
are written, so a disabled plugin can never return through a side door. The
result is announced in one line before the work continues: search is a lookup
inside a task, not a deliverable.

The model categorizes once. The first run drafts 8–12 categories named for
user-intent task shapes, not products, then freezes the taxonomy. Later runs only
file new skills and re-confirm the ones whose description changed — each assignment
carries a hash of the description it was made against.

🕸️ The graph

The atlas, category view

Discovery is manifest-driveninstalled_plugins.json → each plugin.json
settings — so marketplace catalogues and stale cached versions never pollute the
picture. (The naive "every directory with a SKILL.md" count over-counts by ~60% on a
real machine: build_graph.py --naive-count.)

Skills are nodes. The edges are the interesting part:

Edge Caught
🔗 references — a skill → its own bundled files broken when the file isn't there
💬 mentions — a skill naming another skill dangling when the target is disabled, unregistered or absent

Mention matching is deliberately strict — only backticked, skills/<name>, or
unambiguous hyphenated names, code fences stripped first. Loose matching produced 91
edges on a 41-skill collection, almost all of them ordinary English words. You also
get duplicate names, orphans, and an exit code to gate CI on.

atlas.html is self-contained and opens from file:// with zero network requests:
scope (origin, state, breakage in red) and categories (hub-and-spoke — solid
edge to the home category, dashed to the rest; search cat:<name> to isolate).

🛠️ Building and debugging skills

Debugging a skill in the atlas

  • What's really registered — discovery is manifest-driven, so unregistered copies
    and stale plugin caches surface as their own nodes instead of quietly counting.
  • Broken bundles — a references edge whose file isn't on disk draws red, so a
    typo'd references/foo.md is visible without opening anything.
  • Why it didn't trigger — tier is the node's fill (enabled · searchable ·
    disabled), and duplicate names are called out in the footer with both nodes drawn.
  • Read it in place — pin any skill or bundled file and hit open markdown to
    read the source in a popup without leaving the graph.

📚 Docs

docs/ — component guide, numbered 1–9: start at
overview, then jump to the component you're touching
(discovery, graph build, categorization, catalog & search, rendering, hooks).

DESIGN.md — the historical record for both phases: what was
considered, what was chosen, what was dropped, and why

⚖️ License

Apache-2.0 — see LICENSE.

D3 is vendored in vendor/d3.v7.min.js and inlined into
every generated atlas.html. It is ISC-licensed, © 2010-2023 Mike Bostock —
see vendor/LICENSE-d3.

Reviews (0)

No results found