A Claude Code skill that answers one question before any Unity debugging starts:
Is this bug already known to Unity - and is it fixed somewhere?
Unity publishes its Known Issues per editor version and its fixes per patch release. Almost nobody reads them, so hours get spent debugging bugs that are not in the user's code. This skill reads them in ~30 ms.
$ python scripts/unity_kb.py search "Android 15 keyboard Edit Field overlapping into cutoff area" --editor-version 6000.0.20f1
FIXED_IN_NEWER | editor 6000.0.20f1 | 1 hits | 43ms | index 90/90 releases
FIX UUM-77367 | fixed in 6000.0.30f1 | Android: Fixed Android 15 keyboard Edit Field overlapping into cutoff area.
NEXT upgrade 6000.0.20f1 -> 6000.0.30f1 (contains the fix) | newest in line 6000.0.83f1 (2026-09-02)
.\install.ps1 # -> ~/.claude/skills/unity-changelog
.\install.ps1 -WhatIf # dry run
python scripts\unity_kb.py sync --line 6000.0 # optional: warm the index up front (~10 s)Requirements: Python 3.9+ with stdlib sqlite3 built with FTS5 (checked by the installer).
No pip packages, no config.
Three sources, one local index, a hard output cap.
| Editor release notes | The official releases API hands out markdown changelogs (not HTML), incremental per patch, ~17 KB each. All 90 releases of a version line are 1.1 MB. |
| Unity Issue Tracker | issuetracker.unity.com/api/v1.0 - each issue carries issuePorts[] with fixedInVersion per release line, i.e. exactly "open in 6000.0.X, fixed in 6000.6.2f1". |
| Package changelogs | docs.unity3d.com/Packages/<pkg>@<ver>/changelog/CHANGELOG.html for the packages the project actually uses (read from packages-lock.json). |
Everything network-bound happens in a sync, never in a query:
sync (once per line, ~10 s, background) -> SQLite FTS5 index -> query (25-50 ms)
- The index lives in
~/.claude/cache/unity-changelog/kb.sqlite(~3 MB per release line) and refreshes itself; raw markdown is discarded after parsing. - A cold cache never blocks a query: the build is handed to a detached background process and the query answers from the Issue Tracker, which needs no index.
- Relevance uses IDF from the index itself. A term appearing in <= 0.25 % of entries is "distinctive", and a hit needs at least one - which is what keeps "my script throws NullReferenceException" from matching half the changelog.
- Output is capped:
NO_MATCHis a single line (~20 tokens), a hit is 2-4 lines (~60-250 tokens). Repro steps and changelog bodies are never dumped into the context.
| Verdict | Meaning |
|---|---|
FIXED_IN_NEWER |
Fixed in a later release; the NEXT line names the version to upgrade to |
KNOWN_UNFIXED |
Known issue with no released fix for this line - build a workaround, stop debugging |
FIXED_IN_PACKAGE |
A package update fixes it |
LIKELY_UNRELATED |
Only weak matches - keep debugging |
NO_MATCH |
Nothing known - keep debugging |
INCONCLUSIVE |
The index was not built yet, so silence proves nothing |
A fix only counts when it is released (isReleasedFixedInVersion) and newer than the
user's version - a backport to 2021.3.x is not an upgrade path for someone on 6000.0.
unity_kb.py search "<symptom>" [--project P | --editor-version V] [--max-hits 5]
[--budget-ms 4000] [--sources notes,tracker,packages]
[--format compact|json] [--no-net]
unity_kb.py sync [--scope line|major|all] [--packages] [--line 6000.0] [--quiet]
unity_kb.py issue UUM-150250 | 24176
unity_kb.py version [--project P]
unity_kb.py upgrade-path [--editor-version V]
unity_kb.py cache info | clear
UNITY_KB_CACHE overrides the index location (used by the tests).
SKILL.md trigger + workflow Claude follows
references/sources.md endpoints, API quirks, field semantics, measured costs
references/triage.md engine bug vs. own code, query building, reporting
scripts/indexer.py fetching, markdown/HTML parsing, SQLite FTS5 index, background sync
scripts/unity_kb.py CLI, IDF scoring, tracker client, verdicts, report
tests/smoke.ps1 37 end-to-end assertions against real published Unity data
tests/fixtures/FakeProject minimal Unity project (ProjectVersion.txt + packages-lock.json)
tests/smoke.ps1 # full run, needs network
tests/smoke.ps1 -Keep # same, but keeps the test index
tests/smoke.ps1 -Offline # re-check the logic without network (needs a -Keep run first)Assertions are pinned to verified public facts (e.g. UUM-14959 is a Known Issue in 6000.0.30f1 and fixed in 6000.0.31f1), so a failure means the skill regressed.
The Issue Tracker's search parameter is q. ?query=... returns HTTP 200 with a valid
JSON list but silently ignores the filter and returns the same default page every time -
so does search, text, phrase, keyword, filter. It looks like a working search
until the results are checked against the search term. More of these in
references/sources.md.