Публічний реєстр
Звіт про здоров'я програмного забезпеченнясхема 0.27.0 · метрики 1.13.0 · 2026-07-25 19:39 UTC

meshtastic / python

The Python CLI and API for talking to Meshtastic devices

PythonGPL-3.0★ 826 зірок⑂ 334 форкиз квіт. 2020 р.Переглянути на GitHub ↗

meshtastic/python має індекс здоров’я 76 зі 100, що відповідає смузі «Добрий». Найвищий показник — Vitality (89/100), найнижчий — Security (55/100). Останнє оновлення було 2 дні тому. Більшість нещодавньої роботи виконують 3 учасники.

76
загалом / 100
Добрий

Індекс здоров'я програмного забезпечення

Метрики згруповано у зважені категорії на шкалі 1–100. Загальна оцінка починається як їхнє середнє; коли публічні дані активують Політику юрисдикцій високого ризику, рейтинг коригується й отримує верхню межу 49 («Під ризиком»). Готовність до ШІ не входить до індексу.

76
Відмінний85-100Зразковий; відповідає практично всім перевіреним критеріям
Добрий70-84Здоровий; незначні прогалини
Помірний50-69Прийнятний, але з помітними прогалинами; рекомендовано перевірку
У зоні ризику30-49Суттєві слабкі місця; впровадження потребує обережності
Критичний1-29Серйозні проблеми (покинутий, єдиний мейнтейнер, без базової гігієни)
ЖиттєздатністьСпільнота тавпровадженняСталість таврядуванняІнженернаякістьБезпекаГотовність доШІ

Профіль оцінок

Кожна вісь — окрема категорія. Форма важить більше, ніж середнє: здоровий об'єкт заповнює всю фігуру, тоді як профіль із піками та провалами означає, що сила в одному вимірі маскує ризик в іншому.

Власність

MeshtasticОрганізація
7 009 підписників138 публічних репозиторіївз лют. 2020 р.

За цим репозиторієм стоїть організація — спільна, підзвітна опіка, здатна пережити будь-якого окремого мейнтейнера.

Пакетні екосистеми

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікація
PyPImeshtastic2.7.11-2768 днів тому

Метрики за категоріями

Життєздатність

Чи живий проєкт — чи пишеться код і чи виходять релізи?

89Відмінний · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 2 дн. тому
24.9/36Ритм комітів — 36/52 тижнів із комітами
18/18Обсяг комітів — 228 комітів за останній рік
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Використані вхідні дані
commits_last_year228
human_commit_share1
days_since_last_push2
active_weeks_last_year36
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 100 релізів
36/36Свіжість релізів — останній реліз 8 дн. тому
27/27Ритм релізів — реліз кожні ~34,2 дн.
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Використані вхідні дані
releases_count100
latest_release_tag2.7.11
releases_from_tagsні
days_since_latest_release8
mean_days_between_releases34,2

Спільнота та впровадження

Чи має проєкт користувачів, завантаження, увагу та влаштовані умови для контриб’юторів?

74Добрий · 18% загального індексу
Як обчислюється оцінка
47.3/60Зірки — 826 зірок
21/25Форки — 334 форків
8.6/15Спостерігачі — 36 спостерігачів
Використані вхідні дані
forks334
stars826
watchers36
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (GPL-3.0)
18/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
has_contributingтак
has_issue_templateні
has_code_of_conductні
has_pull_request_templateні

Сталість та врядування

Чи переживе проєкт своїх людей — бас-фактор, реактивність, хто за ним стоїть і як супроводжуються пакети?

80Добрий · 24% загального індексу
Як обчислюється оцінка
36/54Бас-фактор — на 3 контриб’ютор(ів) припадає половина всіх комітів
17.2/22.5Розподіл комітів — головний контриб’ютор — автор 24% комітів
13.5/13.5Широта контриб’юторів — 99 контриб’юторів
10/10OpenSSF Scorecard: Contributors — project has 17 contributing companies or organizations
Використані вхідні дані
bus_factor3
contributors_sampled99
top_contributor_share0,235
Як обчислюється оцінка
33.9/46.8Вирішення issue — закрито 73% issue
32.9/38.3Прийняття PR — злито 433/504 вирішених PR
1.5/15OpenSSF Scorecard: Code-Review — Found 2/15 approved changesets -- score normalized to 1
Використані вхідні дані
merged_prs433
open_issues116
closed_issues308
issue_closed_ratio0,726
closed_unmerged_prs71
Як обчислюється оцінка
30/30Підтримка власника — у власності організації
0/20Верифікований домен
25/25Охоплення власника — 7 009 підписників у meshtastic
25/25Послужний список — 138 публічних репозиторіїв, вік облікового запису ~6 р.
Використані вхідні дані
followers7 009
owner_typeOrganization
is_verified
owner_loginmeshtastic
public_repos138
account_age_days2 338

Супровід пакетів

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 1 пакет(ів) у pypi
35/35Свіжість публікацій — остання публікація 8 дн. тому
20/20Історія версій — 276 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packagesmeshtastic
ecosystemspypi
any_deprecatedні
min_days_since_publish8

Інженерна якість

Чи наявні базові інженерні практики та документація?

76Добрий · 20% загального індексу
Як обчислюється оцінка
24/24Процеси CI — 6 процес(ів) CI
24/24Наявні тести
16/16Конфігурація лінтера — .pylintrc, ruff.toml
0/9.6Pre-commit-хуки
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 3 out of 3 merged PRs checked by a CI test -- score normalized to 10
Використані вхідні дані
has_ciтак
has_testsтак
has_editorconfigні
has_linter_configтак
has_precommit_configні

Документація

65Помірний
Як обчислюється оцінка
30/30README
0/25Каталог документації
15/15Сайт документації / домашня сторінка — https://meshtastic.org
10/10Опис репозиторію
10/10Теми — 2 тем
0/10Wiki
Використані вхідні дані
topicsmeshtastic, meshtastic-python
has_wikiні
homepagehttps://meshtastic.org
has_readmeтак
has_docs_dirні
has_descriptionтак

Безпека

Чи міцні видимі практики безпеки й ланцюга постачання, без непослабленої пов’язаності з юрисдикціями високого ризику?

55Помірний · 16% загального індексу

Стан безпеки

44У зоні ризику
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 3 out of 3 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0.8/7.5Code-Review — Found 2/15 approved changesets -- score normalized to 1
2.5/2.5Contributors — project has 17 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
7.5/7.5Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 53 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate4,4
Як обчислюється оцінка
35/35Прямі залежності без відомих сповіщень — жодна пряма залежність не має відомих сповіщень
25/25Непрямі залежності без відомих сповіщень — жодна непряма залежність не має відомих сповіщень
0/40Немає задавнених сповіщень — жодне сповіщення не має дати публікації
Використані вхідні дані
sourceosv
advisories0
affected_packages0
assessed_packages13
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Виключено з оцінювання (немає даних або не застосовно): Немає задавнених сповіщень. Залишкові ваги перенормовано. Звірено з runtime-замиканням залежностей pypi:meshtastic@2.7.11 — тим, що тягне за собою встановлення опублікованого пакета, — 13 пакетів. Досяжність не аналізується.

Готовність до ШІ

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Незалежний, експериментальний бейдж — вага 0.0, тож він подається окремо і не впливає на загальний індекс здоров'я.

60Помірний · 0% загального індексу
Як обчислюється оцінка
45/45Інструкції для агентів — .github/copilot-instructions.md
0/15Машиночитана документація (llms.txt)
13.9/40Читабельна історія комітів — намір зазначено у 26 з 100 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,26
agent_instruction_files.github/copilot-instructions.md
agent_instruction_max_bytes6 037
Як обчислюється оцінка
18/18Розгортання однією командою — Makefile
22/22Автоматизовані тести
11/11Конфігурація лінтера / форматера — .pylintrc, ruff.toml
0/11Статична перевірка типів
10/10Відтворюване середовище — Dockerfile, lockfile
10/10Підтверджена практика роботи з агентами — 5 з останніх 100 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Використані вхідні дані
has_nixні
has_testsтак
lockfilespoetry.lock
has_dockerfileтак
typed_languageні
bootstrap_filesMakefile
has_devcontainerні
has_linter_configтак
typecheck_configs
agent_commit_share0,05
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
0/45Типізований код — Python без конфігурації перевірки типів
52.8/55Керовані розміри файлів — 4/98 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languagePython
largest_source_bytes140 787
source_files_sampled98
oversized_source_files4
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
0/20Сервер MCP
40/40Придатні до запуску приклади — examples
Використані вхідні дані
example_dirsexamples
has_mcp_signalні
api_schema_files

Ключові факти

826зірок GitHub
99контриб'юторів
228комітів за останні 12 місяців
2днів від останнього пушу
100релізів
3бас-фактор
116відкритих issue
PyPIпакетних екосистем

Попередження щодо збору даних

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token

Докладніше

Історія зірок і форків 0 ★ / 334 ⇿
0Зірки
334Форки
100Релізи

Коли додано кожну зірку й форк — зібрано з GitHub і згруповано за днями. Кумулятивне зростання розміщено просто над денними додаваннями, з яких воно складається, тож їх видно одне проти одного: рівномірне органічне накопичення виглядає зовсім інакше, ніж різкий короткочасний сплеск. Там, де цю різницю можна виміряти, її подано як автентичність росту.

012525037532662020-062023-062026-07
Мажорні 0Мінорні 6Патчі 91

Кожна точка охоплює 6 днів.

OpenSSF Scorecard 4.4 / 10
4.4сукупно

Незалежна, не прив'язана до інструментів оцінка безпеки від відкритого проєкту OpenSSF Scorecard. Кожна перевірка винагороджує практику безпеки, а не інструмент конкретного постачальника. Перевірки, які Scorecard не зміг визначити, позначено н/д і виключено з оцінки безпеки (вони ніколи не зараховуються як нуль).Scorecard v5.5.0 · 2026-07-25 19:39 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests3 out of 3 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
1Code-ReviewFound 2/15 approved changesets -- score normalized to 1
10Contributorsproject has 17 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities53 existing vulnerabilities detected
Прямі залежності 18
РеєстрПакетОбмеження версіїМаніфест
PyPIpyserial^3.5pyproject.toml
PyPIprotobuf>=4.21.12pyproject.toml
PyPItabulate^0.9.0pyproject.toml
PyPIrequests^2.31.0pyproject.toml
PyPIpyyaml^6.0.1pyproject.toml
PyPIpypubsub^4.0.3pyproject.toml
PyPIbleak>=0.22.3pyproject.toml
PyPIpackaging>=24.0pyproject.toml
PyPIargcomplete^3.5.2pyproject.toml
PyPIpyqrcode^1.2.1pyproject.toml
PyPIdotmap^1.3.30pyproject.toml
PyPIprint-color^0.4.6pyproject.toml
PyPIdash^2.17.1pyproject.toml
PyPIpytap2^2.3.0pyproject.toml
PyPIdash-bootstrap-components^1.6.0pyproject.toml
PyPIpandas^2.2.2pyproject.toml
PyPIpandas-stubs^2.2.2.240603pyproject.toml
PyPIwcwidth^0.2.13pyproject.toml
Усі залежності 193

Повний розв'язаний набір залежностей із графа залежностей GitHub: 18 прямих і 175 непрямих (транзитивних) пакетів. Транзитивне замикання є повним, коли в репозиторії закомічено lockfile.

РеєстрПакетВерсіяЗв'язок
PyPIargcomplete3.6.3пряма
PyPIbleak1.1.1пряма
PyPIdash2.18.2пряма
PyPIdash-bootstrap-components1.7.1пряма
PyPIdotmap1.3.30пряма
PyPIpackaging24.2пряма
PyPIpandas2.3.3пряма
PyPIpandas-stubs2.2.2.240807пряма
PyPIprint-color0.4.6пряма
PyPIprotobuf6.33.6пряма
PyPIpypubsub4.0.3пряма
PyPIpyqrcode1.2.1пряма
PyPIpyserial3.5пряма
PyPIpytap22.3.0пряма
PyPIpyyaml6.0.3пряма
PyPIrequests2.32.5пряма
PyPItabulate0.9.0пряма
PyPIwcwidth0.2.14пряма
PyPIaltgraph0.17.4непряма
PyPIanyio4.11.0непряма
PyPIappnope0.1.4непряма
PyPIargon2-cffi25.1.0непряма
PyPIargon2-cffi-bindings25.1.0непряма
PyPIarrow1.4.0непряма
PyPIastroid3.3.11непряма
PyPIasttokens3.0.0непряма
PyPIasync-lru2.0.5непряма
PyPIasync-timeout5.0.1непряма
PyPIattrs25.4.0непряма
PyPIautopep82.3.2непряма
PyPIbabel2.17.0непряма
PyPIbeautifulsoup44.14.2непряма
PyPIbleach6.2.0непряма
PyPIblinker1.9.0непряма
PyPIcertifi2025.10.5непряма
PyPIcffi2.0.0непряма
PyPIcharset-normalizer3.4.4непряма
PyPIclick8.1.8непряма
PyPIcolorama0.4.6непряма
PyPIcomm0.2.3непряма
PyPIcontourpy1.3.0непряма
PyPIcoverage7.10.7непряма
PyPIcycler0.12.1непряма
PyPIdash-core-components2.0.0непряма
PyPIdash-html-components2.0.0непряма
PyPIdash-table5.0.0непряма
PyPIdbus-fast2.45.1непряма
PyPIdebugpy1.8.17непряма
PyPIdecorator5.2.1непряма
PyPIdefusedxml0.7.1непряма
PyPIdill0.4.0непряма
PyPIexceptiongroup1.3.0непряма
PyPIexecuting2.2.1непряма
PyPIfastjsonschema2.21.2непряма
PyPIflask3.0.3непряма
PyPIfonttools4.60.2непряма
PyPIfqdn1.5.1непряма
PyPIh110.16.0непряма
PyPIhttpcore1.0.9непряма
PyPIhttpx0.28.1непряма
PyPIhypothesis6.141.1непряма
PyPIidna3.17непряма
PyPIimportlib-metadata8.7.0непряма
PyPIimportlib-resources6.5.2непряма
PyPIiniconfig2.1.0непряма
PyPIipykernel6.31.0непряма
PyPIipympl0.9.8непряма
PyPIipython8.18.1непряма
PyPIipython-pygments-lexers1.1.1непряма
PyPIipywidgets8.1.8непряма
PyPIisoduration20.11.0непряма
PyPIisort6.1.0непряма
PyPIitsdangerous2.2.0непряма
PyPIjedi0.19.2непряма
PyPIjinja23.1.6непряма
PyPIjson50.12.1непряма
PyPIjsonpointer3.0.0непряма
PyPIjsonschema4.25.1непряма
PyPIjsonschema-specifications2025.9.1непряма
PyPIjupyter-client8.6.3непряма
PyPIjupyter-core5.8.1непряма
PyPIjupyter-events0.12.0непряма
PyPIjupyter-lsp2.3.0непряма
PyPIjupyter-server2.18.2непряма
PyPIjupyter-server-terminals0.5.3непряма
PyPIjupyterlab4.5.7непряма
PyPIjupyterlab-pygments0.3.0непряма
PyPIjupyterlab-server2.28.0непряма
PyPIjupyterlab-widgets3.0.16непряма
PyPIkiwisolver1.4.7непряма
PyPIlark1.3.1непряма
PyPImacholib1.16.3непряма
PyPImako1.3.12непряма
PyPImarkdown3.9непряма
PyPImarkupsafe3.0.3непряма
PyPImatplotlib3.9.4непряма
PyPImatplotlib-inline0.2.1непряма
PyPImccabe0.7.0непряма
PyPImistune3.2.1непряма
PyPImodbus-tk1.1.5непряма
PyPImypy1.18.2непряма
PyPImypy-extensions1.1.0непряма
PyPImypy-protobuf3.6.0непряма
PyPInarwhals2.11.0непряма
PyPInbclient0.10.2непряма
PyPInbconvert7.17.1непряма
PyPInbformat5.10.4непряма
PyPInest-asyncio1.6.0непряма
PyPInotebook-shim0.2.4непряма
PyPInumpy2.0.2непряма
PyPIoverrides7.7.0непряма
PyPIpandocfilters1.5.1непряма
PyPIparse1.20.2непряма
PyPIparso0.8.5непряма
PyPIpathspec0.12.1непряма
PyPIpdoc30.10.0непряма
PyPIpefile2023.2.7непряма
PyPIpexpect4.9.0непряма
PyPIpillow11.3.0непряма
PyPIplatformdirs4.4.0непряма
PyPIplotly6.4.0непряма
PyPIpluggy1.6.0непряма
PyPIppk2-api0.9.2непряма
PyPIprometheus-client0.23.1непряма
PyPIprompt-toolkit3.0.52непряма
PyPIpsutil7.1.3непряма
PyPIptyprocess0.7.0непряма
PyPIpure-eval0.2.3непряма
PyPIpyarrow18.1.0непряма
PyPIpyarrow-stubs10.0.1.9непряма
PyPIpycodestyle2.14.0непряма
PyPIpycparser2.23непряма
PyPIpygments2.20.0непряма
PyPIpyinstaller6.16.0непряма
PyPIpyinstaller-hooks-contrib2025.9непряма
PyPIpylint3.3.9непряма
PyPIpyobjc-core12.0непряма
PyPIpyobjc-framework-cocoa12.0непряма
PyPIpyobjc-framework-corebluetooth12.0непряма
PyPIpyobjc-framework-libdispatch12.0непряма
PyPIpyparsing3.2.5непряма
PyPIpytest8.4.2непряма
PyPIpytest-cov5.0.0непряма
PyPIpython-dateutil2.9.0.post0непряма
PyPIpython-json-logger4.0.0непряма
PyPIpytz2025.2непряма
PyPIpywin32311непряма
PyPIpywin32-ctypes0.2.3непряма
PyPIpywinpty3.0.2непряма
PyPIpyzmq27.1.0непряма
PyPIreferencing0.36.2непряма
PyPIretrying1.4.2непряма
PyPIrfc3339-validator0.1.4непряма
PyPIrfc3986-validator0.1.1непряма
PyPIrfc3987-syntax1.1.0непряма
PyPIrpds-py0.27.1непряма
PyPIsend2trash1.8.3непряма
PyPIsetuptools82.0.1непряма
PyPIsix1.17.0непряма
PyPIsniffio1.3.1непряма
PyPIsortedcontainers2.4.0непряма
PyPIsoupsieve2.8непряма
PyPIstack-data0.6.3непряма
PyPIterminado0.18.1непряма
PyPItinycss21.4.0непряма
PyPItomli2.3.0непряма
PyPItomlkit0.13.3непряма
PyPItornado6.5.6непряма
PyPItraitlets5.14.3непряма
PyPItypes-protobuf5.29.1.20250403непряма
PyPItypes-pytz2025.2.0.20251108непряма
PyPItypes-pyyaml6.0.12.20250915непряма
PyPItypes-requests2.32.4.20250913непряма
PyPItypes-setuptools69.5.0.20240522непряма
PyPItypes-tabulate0.9.0.20241207непряма
PyPItyping-extensions4.15.0непряма
PyPItzdata2025.2непряма
PyPIuri-template1.3.0непряма
PyPIurllib32.6.3непряма
PyPIwebcolors24.11.1непряма
PyPIwebencodings0.5.1непряма
PyPIwebsocket-client1.9.0непряма
PyPIwerkzeug3.0.6непряма
PyPIwidgetsnbextension4.0.15непряма
PyPIwinrt-runtime3.2.1непряма
PyPIwinrt-windows-devices-bluetooth3.2.1непряма
PyPIwinrt-windows-devices-bluetooth-advertisement3.2.1непряма
PyPIwinrt-windows-devices-bluetooth-genericattributeprofile3.2.1непряма
PyPIwinrt-windows-devices-enumeration3.2.1непряма
PyPIwinrt-windows-foundation3.2.1непряма
PyPIwinrt-windows-foundation-collections3.2.1непряма
PyPIwinrt-windows-storage-streams3.2.1непряма
PyPIzipp3.23.0непряма
Сповіщення про залежності 0

Встановлення pypi:meshtastic@2.7.11 тягне 13 пакетів, прямих і транзитивних: 0 мають відомі сповіщення, з них 0 — прямі залежності.

Жодне відоме сповіщення не стосується оцінених залежностей.

Сповіщення означає, що версія, записана в графі залежностей, потрапляє в уражений діапазон. Досяжність не аналізується, а граф містить піниї розробки й тестування — знахідка може стосуватися інструментів, а не поставленого коду.

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [
        "meshtastic",
        "meshtastic-python"
      ],
      "is_fork": false,
      "size_kb": 5062,
      "has_wiki": false,
      "homepage": "https://meshtastic.org",
      "languages": {
        "Shell": 5758,
        "Python": 812825,
        "Makefile": 1284
      },
      "pushed_at": "2026-07-23T00:37:45Z",
      "created_at": "2020-04-27T02:20:46Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-23T18:12:07Z",
      "description": "The Python CLI and API for talking to Meshtastic devices",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "GPL-3.0",
      "default_branch": "master",
      "license_spdx_raw": "GPL-3.0",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "https://meshtastic.org",
      "name": "Meshtastic",
      "type": "Organization",
      "login": "meshtastic",
      "company": null,
      "location": "United States of America",
      "followers": 7009,
      "avatar_url": "https://avatars.githubusercontent.com/u/61627050?v=4",
      "created_at": "2020-02-29T15:13:30Z",
      "is_verified": null,
      "public_repos": 138,
      "account_age_days": 2338
    },
    "license": {
      "state": "standard",
      "spdx_id": "GPL-3.0",
      "raw_spdx": "GPL-3.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "2.7.11",
          "kind": "patch",
          "published_at": "2026-07-17T17:39:05Z"
        },
        {
          "tag": "2.7.10",
          "kind": "patch",
          "published_at": "2026-06-29T20:48:56Z"
        },
        {
          "tag": "2.7.9",
          "kind": "patch",
          "published_at": "2026-06-09T02:04:36Z"
        },
        {
          "tag": "2.7.8",
          "kind": "patch",
          "published_at": "2026-03-02T17:40:51Z"
        },
        {
          "tag": "2.7.7",
          "kind": "patch",
          "published_at": "2026-01-24T16:42:18Z"
        },
        {
          "tag": "2.7.6",
          "kind": "patch",
          "published_at": "2026-01-05T02:26:49Z"
        },
        {
          "tag": "2.7.5",
          "kind": "patch",
          "published_at": "2025-11-18T19:54:32Z"
        },
        {
          "tag": "2.7.4",
          "kind": "patch",
          "published_at": "2025-11-06T22:53:07Z"
        },
        {
          "tag": "2.7.3",
          "kind": "patch",
          "published_at": "2025-09-18T16:50:10Z"
        },
        {
          "tag": "2.7.2",
          "kind": "patch",
          "published_at": "2025-09-12T16:51:22Z"
        },
        {
          "tag": "2.7.1",
          "kind": "patch",
          "published_at": "2025-08-18T22:37:21Z"
        },
        {
          "tag": "2.7.0",
          "kind": "minor",
          "published_at": "2025-08-01T22:58:33Z"
        },
        {
          "tag": "2.6.4",
          "kind": "patch",
          "published_at": "2025-06-23T22:18:21Z"
        },
        {
          "tag": "2.6.3",
          "kind": "patch",
          "published_at": "2025-05-08T22:29:41Z"
        },
        {
          "tag": "2.6.2",
          "kind": "patch",
          "published_at": "2025-04-23T16:51:36Z"
        },
        {
          "tag": "2.6.1",
          "kind": "patch",
          "published_at": "2025-04-06T05:58:32Z"
        },
        {
          "tag": "2.6.0",
          "kind": "minor",
          "published_at": "2025-03-10T23:20:40Z"
        },
        {
          "tag": "2.5.12",
          "kind": "patch",
          "published_at": "2025-02-19T17:25:35Z"
        },
        {
          "tag": "2.5.11",
          "kind": "patch",
          "published_at": "2025-01-24T17:23:51Z"
        },
        {
          "tag": "2.5.10",
          "kind": "patch",
          "published_at": "2025-01-10T17:12:00Z"
        },
        {
          "tag": "2.5.9",
          "kind": "patch",
          "published_at": "2024-12-29T03:26:38Z"
        },
        {
          "tag": "2.5.8",
          "kind": "patch",
          "published_at": "2024-12-27T16:52:45Z"
        },
        {
          "tag": "2.5.7",
          "kind": "patch",
          "published_at": "2024-12-22T03:51:26Z"
        },
        {
          "tag": "2.5.6post1",
          "kind": "other",
          "published_at": "2024-12-20T21:55:59Z"
        },
        {
          "tag": "2.5.5",
          "kind": "patch",
          "published_at": "2024-11-26T21:26:58Z"
        },
        {
          "tag": "2.5.4",
          "kind": "patch",
          "published_at": "2024-11-01T16:06:38Z"
        },
        {
          "tag": "2.5.3",
          "kind": "patch",
          "published_at": "2024-10-18T17:04:56Z"
        },
        {
          "tag": "2.5.2",
          "kind": "patch",
          "published_at": "2024-10-12T16:34:30Z"
        },
        {
          "tag": "2.5.1",
          "kind": "patch",
          "published_at": "2024-09-29T21:33:22Z"
        },
        {
          "tag": "2.5.0",
          "kind": "minor",
          "published_at": "2024-09-12T16:31:32Z"
        },
        {
          "tag": "2.4.3",
          "kind": "patch",
          "published_at": "2024-09-11T16:18:20Z"
        },
        {
          "tag": "2.4.2",
          "kind": "patch",
          "published_at": "2024-09-11T16:11:21Z"
        },
        {
          "tag": "2.4.1",
          "kind": "patch",
          "published_at": "2024-09-05T21:23:46Z"
        },
        {
          "tag": "2.4.0",
          "kind": "minor",
          "published_at": "2024-08-22T02:32:45Z"
        },
        {
          "tag": "2.3.15",
          "kind": "patch",
          "published_at": "2024-08-11T17:24:36Z"
        },
        {
          "tag": "2.3.14",
          "kind": "patch",
          "published_at": "2024-07-08T03:56:13Z"
        },
        {
          "tag": "2.3.13",
          "kind": "patch",
          "published_at": "2024-07-02T16:51:31Z"
        },
        {
          "tag": "2.3.12",
          "kind": "patch",
          "published_at": "2024-06-26T02:11:34Z"
        },
        {
          "tag": "2.3.11",
          "kind": "patch",
          "published_at": "2024-06-08T15:13:55Z"
        },
        {
          "tag": "2.3.10",
          "kind": "patch",
          "published_at": "2024-06-01T18:51:46Z"
        },
        {
          "tag": "2.3.9",
          "kind": "patch",
          "published_at": "2024-05-18T00:18:05Z"
        },
        {
          "tag": "2.3.8",
          "kind": "patch",
          "published_at": "2024-05-01T16:50:25Z"
        },
        {
          "tag": "2.3.7",
          "kind": "patch",
          "published_at": "2024-04-25T18:37:28Z"
        },
        {
          "tag": "2.3.6",
          "kind": "patch",
          "published_at": "2024-04-20T17:55:06Z"
        },
        {
          "tag": "2.3.5",
          "kind": "patch",
          "published_at": "2024-04-15T06:51:58Z"
        },
        {
          "tag": "2.3.4.post1",
          "kind": "other",
          "published_at": "2024-04-08T17:53:41Z"
        },
        {
          "tag": "2.3.4",
          "kind": "patch",
          "published_at": "2024-04-08T17:18:20Z"
        },
        {
          "tag": "2.3.3",
          "kind": "patch",
          "published_at": "2024-03-29T16:31:09Z"
        },
        {
          "tag": "2.3.2.post1",
          "kind": "other",
          "published_at": "2024-03-25T21:15:03Z"
        },
        {
          "tag": "2.3.1",
          "kind": "patch",
          "published_at": "2024-03-21T12:47:55Z"
        },
        {
          "tag": "2.3.0",
          "kind": "minor",
          "published_at": "2024-03-11T17:43:09Z"
        },
        {
          "tag": "2.2.22",
          "kind": "patch",
          "published_at": "2024-02-17T02:17:22Z"
        },
        {
          "tag": "2.2.21",
          "kind": "patch",
          "published_at": "2024-02-12T17:03:33Z"
        },
        {
          "tag": "2.2.20",
          "kind": "patch",
          "published_at": "2024-02-01T14:27:12Z"
        },
        {
          "tag": "2.2.19",
          "kind": "patch",
          "published_at": "2024-01-18T14:15:23Z"
        },
        {
          "tag": "2.2.18",
          "kind": "patch",
          "published_at": "2024-01-16T16:40:29Z"
        },
        {
          "tag": "2.2.17",
          "kind": "patch",
          "published_at": "2024-01-06T12:26:59Z"
        },
        {
          "tag": "2.2.16",
          "kind": "patch",
          "published_at": "2023-12-17T17:52:36Z"
        },
        {
          "tag": "2.2.15",
          "kind": "patch",
          "published_at": "2023-12-13T01:04:57Z"
        },
        {
          "tag": "2.2.14",
          "kind": "patch",
          "published_at": "2023-12-13T01:03:47Z"
        },
        {
          "tag": "2.2.13",
          "kind": "patch",
          "published_at": "2023-12-13T01:00:05Z"
        },
        {
          "tag": "2.2.12",
          "kind": "patch",
          "published_at": "2023-11-05T01:02:19Z"
        },
        {
          "tag": "2.2.11",
          "kind": "patch",
          "published_at": "2023-11-04T14:26:39Z"
        },
        {
          "tag": "2.2.10",
          "kind": "patch",
          "published_at": "2023-10-11T15:07:39Z"
        },
        {
          "tag": "2.2.9",
          "kind": "patch",
          "published_at": "2023-10-08T11:55:57Z"
        },
        {
          "tag": "2.2.8",
          "kind": "patch",
          "published_at": "2023-09-30T11:47:15Z"
        },
        {
          "tag": "2.2.7",
          "kind": "patch",
          "published_at": "2023-09-26T11:10:20Z"
        },
        {
          "tag": "2.2.6",
          "kind": "patch",
          "published_at": "2023-09-20T12:04:54Z"
        },
        {
          "tag": "2.2.5",
          "kind": "patch",
          "published_at": "2023-09-14T14:18:53Z"
        },
        {
          "tag": "2.2.4",
          "kind": "patch",
          "published_at": "2023-09-14T12:00:08Z"
        },
        {
          "tag": "2.2.3",
          "kind": "patch",
          "published_at": "2023-09-07T13:55:55Z"
        },
        {
          "tag": "2.2.2",
          "kind": "patch",
          "published_at": "2023-08-26T00:29:41Z"
        },
        {
          "tag": "2.2.1",
          "kind": "patch",
          "published_at": "2023-08-21T20:33:17Z"
        },
        {
          "tag": "2.2.0",
          "kind": "minor",
          "published_at": "2023-08-08T22:11:02Z"
        },
        {
          "tag": "2.1.14",
          "kind": "patch",
          "published_at": "2023-08-08T21:05:45Z"
        },
        {
          "tag": "2.1.13",
          "kind": "patch",
          "published_at": "2023-08-06T22:56:57Z"
        },
        {
          "tag": "2.1.12",
          "kind": "patch",
          "published_at": "2023-08-06T22:56:16Z"
        },
        {
          "tag": "2.1.11",
          "kind": "patch",
          "published_at": "2023-07-26T00:48:27Z"
        },
        {
          "tag": "2.1.10",
          "kind": "patch",
          "published_at": "2023-07-09T11:28:43Z"
        },
        {
          "tag": "2.1.9",
          "kind": "patch",
          "published_at": "2023-06-28T01:19:34Z"
        },
        {
          "tag": "2.1.8",
          "kind": "patch",
          "published_at": "2023-05-31T00:16:20Z"
        },
        {
          "tag": "2.1.7",
          "kind": "patch",
          "published_at": "2023-05-28T14:34:29Z"
        },
        {
          "tag": "2.1.6",
          "kind": "patch",
          "published_at": "2023-04-11T15:10:11Z"
        },
        {
          "tag": "2.1.5",
          "kind": "patch",
          "published_at": "2023-04-06T14:22:49Z"
        },
        {
          "tag": "2.1.4",
          "kind": "patch",
          "published_at": "2023-03-29T00:44:36Z"
        },
        {
          "tag": "2.1.3",
          "kind": "patch",
          "published_at": "2023-03-26T20:54:18Z"
        },
        {
          "tag": "2.1.2",
          "kind": "patch",
          "published_at": "2023-03-26T19:48:07Z"
        },
        {
          "tag": "2.1.1",
          "kind": "patch",
          "published_at": "2023-03-19T18:52:22Z"
        },
        {
          "tag": "2.0.12",
          "kind": "patch",
          "published_at": "2023-02-11T02:33:08Z"
        },
        {
          "tag": "2.0.11",
          "kind": "patch",
          "published_at": "2023-01-31T17:03:51Z"
        },
        {
          "tag": "2.0.10",
          "kind": "patch",
          "published_at": "2023-01-29T23:11:02Z"
        },
        {
          "tag": "2.0.9",
          "kind": "patch",
          "published_at": "2023-01-07T21:34:19Z"
        },
        {
          "tag": "2.0.8",
          "kind": "patch",
          "published_at": "2022-12-28T16:44:15Z"
        },
        {
          "tag": "2.0.7",
          "kind": "patch",
          "published_at": "2022-12-27T21:24:36Z"
        },
        {
          "tag": "2.0.6",
          "kind": "patch",
          "published_at": "2022-12-10T01:47:06Z"
        },
        {
          "tag": "2.0.5",
          "kind": "patch",
          "published_at": "2022-11-27T19:15:09Z"
        },
        {
          "tag": "2.0.4",
          "kind": "patch",
          "published_at": "2022-11-22T17:06:39Z"
        },
        {
          "tag": "2.0.3",
          "kind": "patch",
          "published_at": "2022-11-10T03:26:33Z"
        },
        {
          "tag": "2.0.2",
          "kind": "patch",
          "published_at": "2022-11-03T13:11:51Z"
        },
        {
          "tag": "2.0.1",
          "kind": "patch",
          "published_at": "2022-11-01T12:47:50Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "ae710478fb62924ee56f61f9c339f0aac018af82",
          "body": null,
          "is_bot": false,
          "headline": "update pyarrow for python 3.14 specifically, separately",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-22T19:46:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b084d7df29e4efa446f6b1c84793d01880e0cc1",
          "body": "…ooner if there's issues in those",
          "is_bot": false,
          "headline": "Install with extras and dev/powermon in validate to stop build jobs s…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-22T19:18:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f62c099ae0024af7d2fb46f0993db0563584059",
          "body": "…arallel with make",
          "is_bot": false,
          "headline": "More CI optimization: run tests only once, run pylint/mypy/tests in p…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-22T19:14:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a509bca86d2aa0bafb022ad25e06da2bbe91ed18",
          "body": null,
          "is_bot": false,
          "headline": "Increase pyarrow version for a pkg_resources dependency issue",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-22T18:55:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dca0b1fced6e16173e33acfc0db9bafcbfc2dd68",
          "body": null,
          "is_bot": false,
          "headline": "Improve CI job to fail faster/use up fewer runners when things fail",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-22T18:40:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "11b71e9587b8c9ea23a4b696c685edd211ca66e6",
          "body": "…t mad at us",
          "is_bot": false,
          "headline": "Convey bitfield forward in firmware harness so prehop drop doesn't ge…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-22T18:20:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "19d066970e652a5a72a18718149b638e3473a6eb",
          "body": null,
          "is_bot": false,
          "headline": "bump version to 2.7.11",
          "author_name": "github-actions",
          "author_login": null,
          "committed_at": "2026-07-17T17:37:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "485d860911184c66f6713c5a5e76d921136f3b55",
          "body": null,
          "is_bot": false,
          "headline": "use right repository name for daily simradio testing",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-17T17:32:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e6f07123f66ab5468a986ec593f524f64f42add3",
          "body": "Half-close TCP connections so the last write is not lost",
          "is_bot": false,
          "headline": "Merge pull request #958 from meshtastic/tcp-graceful-close",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-17T17:29:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f62373269435a3afbee94b7412e93c49d7833fa9",
          "body": "close() went straight to shutdown(SHUT_RDWR) + close(). Doing that while either\nside still has unread data makes the stack send RST rather than FIN, and the\ndevice's FromRadio stream means there is essentially always unread data.\n\nWinsock discards data that was received but not yet read when an RST \n[…]\ntdown is kept so a reader still blocked in recv()\nis unblocked for the join in StreamInterface.close(). The wait is bounded: the\ndevice is not obliged to close just because we half-closed.\n\nFixes #957",
          "is_bot": false,
          "headline": "Half-close TCP connections so the last write is not lost",
          "author_name": "Thomas Göttgens",
          "author_login": "caveman99",
          "committed_at": "2026-07-17T12:34:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "82220ba49b56fa398b765550b029a1d91e8d7574",
          "body": "Initial implementation of simradio-based testing with a multi-node simulated mesh",
          "is_bot": false,
          "headline": "Merge pull request #946 from ianmcorvidae/sim-based-testing",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-14T16:16:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4339cda6bd916ec22184c2acddae9a74f8480edb",
          "body": null,
          "is_bot": false,
          "headline": "Run smoke tests daily to find regressions",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-07T21:45:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5760fb3ad945771da110fd13144fe972fd6d0b00",
          "body": null,
          "is_bot": false,
          "headline": "Add reconnect for firmware_node",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-07T19:40:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2281ea5b647a370f94c7ee1fd0da295afa8718d2",
          "body": "…ther than LONG_FAST properly",
          "is_bot": false,
          "headline": "Set the region on the simradio nodes so we can test setting presets o…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-07T19:17:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7950798378fe676a66861bacee65edfc1440f326",
          "body": null,
          "is_bot": false,
          "headline": "quick-win review fixes",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-06T21:36:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bffaff1c7168d4afe7ad509cbd37e1092f187df1",
          "body": null,
          "is_bot": false,
          "headline": "Update ch-preset shorthand arguments",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-06T21:16:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ceca7b3b1071bef9e1151d28a870d0bbc02842df",
          "body": null,
          "is_bot": false,
          "headline": "Add a few extra tests of the revamped channel deletion behavior",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-06T18:26:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15438c8a6e40c05f7982942126bc4badca299fec",
          "body": null,
          "is_bot": false,
          "headline": "matrix up daily/alpha/beta",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-04T09:41:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2f9b285dd56eb953dc6123b48e140da926d721b5",
          "body": null,
          "is_bot": false,
          "headline": "Give the simradio testing a better name in the action",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-04T09:38:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b892711dfba036576327fea9ab5bbd0bbeff075",
          "body": "…ghly",
          "is_bot": false,
          "headline": "Restructure tests, fix up a few other things, rework smokevirt thorou…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-04T09:37:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1cd1aed33cc03a9128dccd9c11acdcc90634c90d",
          "body": null,
          "is_bot": false,
          "headline": "Fix pylint/mypy stuff",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-03T06:31:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab14fb2a861f43508f1394b4ffad1a4944f96fc2",
          "body": "…mulated mesh",
          "is_bot": false,
          "headline": "Initial implementation of simradio-based testing with a multi-node si…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-03T05:48:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a7353ca15500572c53d44ff90195a6196e8cb5a",
          "body": null,
          "is_bot": false,
          "headline": "fix auto review skip-certain-authors key in coderabbit config",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-02T16:17:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e2844cb8d6fa3cf544e820c5d9f6033f805cec67",
          "body": "add support for .cfg export/import",
          "is_bot": false,
          "headline": "Merge pull request #944 from tylerpieper/master",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-02T04:17:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "441c6e80a12e056acb4c5986ff51ca79156c4604",
          "body": null,
          "is_bot": false,
          "headline": "coderabbit yaml, primarily to disable the stupid poem",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-01T23:34:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b05e5453969b8184ce064bd4d124c0cfbb6d7177",
          "body": "Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>",
          "is_bot": false,
          "headline": "guard against None",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-01T22:21:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b6a13d58fe080ddec57eced9bf3e5efda18e787c",
          "body": "- Unify parsing for yaml/DeviceProfile paths\n- Improve autodetection\n- Ensure partial-config behavior with yaml\n- gate configuration to local node (avoiding some pre-existing bugs)\n- gate fixed position updates behind explicit opt-in via position settings field\n- use setOwner properly\n- tests, tests, and more tests",
          "is_bot": false,
          "headline": "Refactor DeviceProfile import/export and harden handling",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-07-01T20:57:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c5efb926c2c19a139d6ef6d628c5745a13f359a",
          "body": "adds binary import and export to mirror functionality of android (and soon ios) app",
          "is_bot": false,
          "headline": "add support for .cfg export/import",
          "author_name": "tylerpieper",
          "author_login": "tylerpieper",
          "committed_at": "2026-06-29T21:41:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6d76edf8a7b192c51e3a5d26bc5868da556ac3d9",
          "body": null,
          "is_bot": false,
          "headline": "bump version to 2.7.10",
          "author_name": "github-actions",
          "author_login": null,
          "committed_at": "2026-06-29T20:45:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74cce6bab9408b12891c5caa275c9941d63387c5",
          "body": null,
          "is_bot": false,
          "headline": "protobufs: v2.7.26",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-26T19:51:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1309f4f3449d7e9f16e0476da04c6dee1e383fc4",
          "body": "feat: add named-flag/power-of-2 bitfield support to --set",
          "is_bot": false,
          "headline": "Merge pull request #943 from ianmcorvidae/flag-int-improvements",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-26T18:13:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fa01cb7a5d8df08aed699242e65f406ba2c9e866",
          "body": null,
          "is_bot": false,
          "headline": "Fix mypy complaint",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-26T18:09:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dcdbda0524ff7e974080054d3285748b1b2073cc",
          "body": "This enables e.g. `--set position.position_flags ALTITUDE,SPEED`\nrather than the dedicated `--pos-flags`, and similarly for\n`network.enabled_protocols`.\n\nDisplaying these named values when printing out configurations\nis not yet implemented.",
          "is_bot": false,
          "headline": "feat: add named-flag/power-of-2 bitfield support to --set",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-26T18:01:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9479fb2a774a12aa525847865bbf2ec705199dd0",
          "body": "Better document how to specify a port when using TCP connection",
          "is_bot": false,
          "headline": "Merge pull request #942 from ianmcorvidae/document-port",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-25T21:47:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "990ecc23506cea115cc41a2856da9d3453df98bf",
          "body": "Fixes #868\n\nAlso, fix a pylint complaint.",
          "is_bot": false,
          "headline": "Better document how to specify a port when using TCP connection",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-25T21:46:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7fc69e957c637b9582361540ba6932b75bd10301",
          "body": null,
          "is_bot": false,
          "headline": "Fail earlier if the ota update file isn't found",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-25T21:28:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0de977be50835f363a37d469c3e9d6bfcd2f679",
          "body": null,
          "is_bot": false,
          "headline": "Some more test improvements",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-25T21:07:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c1183349335f2cbd96520f9d25100376a739cf08",
          "body": null,
          "is_bot": false,
          "headline": "Add tests for the flags_to_list util function",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-19T03:55:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "307d8d81e79cff9ed89041ac2dd68c91afe3f9cb",
          "body": "Add support for adding contacts using the CLI, including remotely",
          "is_bot": false,
          "headline": "Merge pull request #933 from ianmcorvidae/shared-contact",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-17T14:42:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "405a6bbc5d0702113e193fbcc2089656cc065e4d",
          "body": null,
          "is_bot": false,
          "headline": "Fix an issue in to_node_num and add a bunch of tests to it as well",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-17T03:36:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db746a09812cbb248f051b8ef64728a68ef4ee76",
          "body": null,
          "is_bot": false,
          "headline": "pylint appeasement",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-17T03:32:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "13b8cdcb0482f93465449d438cff660741226ce7",
          "body": null,
          "is_bot": false,
          "headline": "Improve test coverage, use property-based tests",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-17T03:27:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9d445098f4fd40e92e7a9c0878dcd2418fcc849d",
          "body": null,
          "is_bot": false,
          "headline": "small fixes",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-15T03:39:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c84074c1d1df99b11321433fbcaa8f0a43adf0b",
          "body": null,
          "is_bot": false,
          "headline": "pylint appeasement",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-15T02:06:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1cffae6adddd3212678b635019a895ae020fbf91",
          "body": null,
          "is_bot": false,
          "headline": "Add support for adding contacts using the CLI, including remotely",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-14T22:28:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e4f0fb222b55796448df5808ca622a59eac97ab0",
          "body": "…sponse\n\nHandle ROUTING_APP error response in onResponseTraceRoute",
          "is_bot": false,
          "headline": "Merge pull request #930 from pieceofr/fix/traceroute-routing-error-re…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-12T20:17:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6eeb90066cd5d8437b4bb60e70a3691b74e6628d",
          "body": null,
          "is_bot": false,
          "headline": "bump version to 2.7.9",
          "author_name": "github-actions",
          "author_login": null,
          "committed_at": "2026-06-09T02:01:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e216848c9128e6af08ac1a8f712bbf61322a1b98",
          "body": "Fix up the container build",
          "is_bot": false,
          "headline": "Merge pull request #932 from ianmcorvidae/fixup-container",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-08T20:33:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd1df473c76cbdc71b679c41e9e3fdd2bf116f30",
          "body": "…and most importantly actually keep the library in the final image (fixes #931)",
          "is_bot": false,
          "headline": "Fix up the container build to use a multi-stage build, cache better, …",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-08T20:28:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "953d01206bbc5f3ee3cee32422a359cd3f459e63",
          "body": "ROUTING_APP with errorReason NONE is an ACK (success), not an error.\nOnly print failure message for non-NONE error reasons.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Handle NONE errorReason in onResponseTraceRoute and add regression test",
          "author_name": "Nox",
          "author_login": "NoctisSentinel",
          "committed_at": "2026-06-04T13:03:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c71d3df3322cb2168395ff29f753c08cd43d8045",
          "body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add unit test for onResponseTraceRoute ROUTING_APP error handling",
          "author_name": "Nox",
          "author_login": "NoctisSentinel",
          "committed_at": "2026-06-04T04:45:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0413d00825fea5e3aa2230278852bb2292bbb774",
          "body": "Previously, receiving a ROUTING_APP packet in response to a traceroute\nwould cause the function to attempt parsing it as a RouteDiscovery\npayload, resulting in a crash or silent failure followed by a timeout.\n\nThis mirrors the error handling already present in onResponseTelemetry\nand onResponseWaypo\n[…]\neason instead\nof a hardcoded firmware version message, since traceroute is a\ndiagnostic tool where the exact failure reason is more valuable.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Handle ROUTING_APP error response in onResponseTraceRoute",
          "author_name": "Nox",
          "author_login": "NoctisSentinel",
          "committed_at": "2026-06-03T14:50:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8f0faf5c3f81ae59f130783b564324e65a9dabfd",
          "body": null,
          "is_bot": false,
          "headline": "One more dependency update",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T03:22:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab656d54a8ed024b89412554ee8f0a54c6abe024",
          "body": null,
          "is_bot": false,
          "headline": "More lockfile updates now that dependabot woke up",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T03:17:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c575547faee926e6c09dcfa2ff05a4e58fc6a64f",
          "body": "Closes #894",
          "is_bot": false,
          "headline": "Merge branch 'review/pr-894'",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T01:10:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0bef1370d7bd9c8eb5ee7c287008982e72f0bb11",
          "body": null,
          "is_bot": false,
          "headline": "tests of new BLEError functionality",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T01:10:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9a13578160d8a57e89b2d95832540b285c19687",
          "body": null,
          "is_bot": false,
          "headline": "Add a BLEError 'kind' field and branch on it instead of string matching",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T01:03:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d1f3552f641a3e3317de89eb289462d186e2a352",
          "body": "Make examples more regularized and focused, and add contribution guidelines for the examples folder",
          "is_bot": false,
          "headline": "Merge pull request #928 from ianmcorvidae/examples",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T00:59:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "81ae8b6c87ba84a62661bd377275c7381407a991",
          "body": "…elines for the examples folder",
          "is_bot": false,
          "headline": "Make examples more regularized and focused, and add contribution guid…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T00:50:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c1573f1b3b284843f7a978cb94f887528472842",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'review/pr-739' into tmp/examples-consolidation",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T00:19:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ff26f9769d8ed474ac5d6fe21a7d744600f59d24",
          "body": null,
          "is_bot": false,
          "headline": "Remove arm/v7 from the container build right now, can't be bothered",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-06-01T00:02:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e5449be38ec5ad0340b4847c8359188fd1257754",
          "body": null,
          "is_bot": false,
          "headline": "tryfix container build issue",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T23:54:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e350c238c5e0fd6163921bd32a049029426722f1",
          "body": null,
          "is_bot": false,
          "headline": "A bunch of dependency updates in poetry.lock (to shut up Dependabot)",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T23:43:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2fca36b3feb282d9e3d2ee7e2cf32bc0e40d1969",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'review/pr-847'",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T22:45:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b16441378e54073e6c8a6670940070e92ba2dcbc",
          "body": null,
          "is_bot": false,
          "headline": "Harden a bit, update some sections, add a README section",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T22:45:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "603794421517afdc84ad8138e0f65aaf18958960",
          "body": "Closes #901",
          "is_bot": false,
          "headline": "Merge branch 'review/pr-901'",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T22:13:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6909d3d21fc33074e0b01fc4c73aa0477d09a1f0",
          "body": null,
          "is_bot": false,
          "headline": "make test more deterministic for reconnect count testing",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T22:10:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dbf4cabee1a8b9fc9856aacb5fccc5cfc85f7119",
          "body": "…n't reconnect when _wantExit",
          "is_bot": false,
          "headline": "Avoid deadlocking on potentially re-entrant _startConfig call, and do…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T22:03:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "435e53eae2dcafb9f5601da4cf1ab52c8fb4c434",
          "body": "…till reconnect. TBD if this is quite the right approach.",
          "is_bot": false,
          "headline": "Re-establish the OSError being raised to match former behavior, but s…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T21:53:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "12509bef30faa984ccf35e60c84e7ad71c026065",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'master' into review/pr-901",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T21:30:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02485a88fbc682647163d28f08d374e7bc480421",
          "body": null,
          "is_bot": false,
          "headline": "some pre-merge cleanup",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T21:23:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d3553b955a405921ac1c056ebc6db3c225d1503",
          "body": null,
          "is_bot": false,
          "headline": "pylint/test fixes",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T21:06:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95bd3ea7af825cd1321458c18068d8b06f0ed91d",
          "body": null,
          "is_bot": false,
          "headline": "pylint strikes again",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T20:53:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c443c082d3fd115c73cbf0d7d3d1eaa9a49825c",
          "body": "Fix some leaks/hangs on close: unstarted StreamInterface streams & TCP reader unblock",
          "is_bot": false,
          "headline": "Merge pull request #923 from ianmcorvidae/close-fixes",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T20:48:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce5bbcda68e9c7210bcf36afb28de569cc43cd1d",
          "body": "…P reader unblock",
          "is_bot": false,
          "headline": "Fix some leaks/hangs on close: unstarted StreamInterface streams & TC…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T20:48:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c2a01f82943d5fb16f9ed4fc328f67ac6e3b7cc9",
          "body": null,
          "is_bot": false,
          "headline": "fix a missing paren in a comment",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T20:35:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "14f53398d710aae214dca41c6a2f6362643d2c1d",
          "body": "…o tmp/merge-918-857",
          "is_bot": false,
          "headline": "Merge commit 'refs/pull/857/head' of github.com:meshtastic/python int…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:52:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d8091a7e3fa10db9b19e1964e53ff1b82ac658d",
          "body": "…o tmp/merge-918-857",
          "is_bot": false,
          "headline": "Merge commit 'refs/pull/918/head' of github.com:meshtastic/python int…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:52:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15ce4968dbb4d116874a6f50dd268f3c9120b14b",
          "body": null,
          "is_bot": false,
          "headline": "pylint fix",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:48:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c0b25310307c376fa971deaaf828a6c1de77876",
          "body": "Closes #883",
          "is_bot": false,
          "headline": "Merge branch 'review/pr-883'",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:43:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7f43b3100c55b3fba45232ef5ab0229dfd844c2",
          "body": null,
          "is_bot": false,
          "headline": "Document the use of --ch-index along with --reply a little",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:43:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8c7eb118fc4972688987b5ee7e2bcbe1ac72ee56",
          "body": "Closes #917",
          "is_bot": false,
          "headline": "Merge branch 'review/pr-917'",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:30:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "badf7279af12db7d7efcd039976f360daf02948b",
          "body": null,
          "is_bot": false,
          "headline": "Update the other factory reset to use integer too",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:30:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "13c9f3458914c747d408ea2ffbc4d9d912576cb8",
          "body": "Fix position overwrite by lower-precision data",
          "is_bot": false,
          "headline": "Merge pull request #911 from syn-ack-ai/fix/position-precision-overwrite",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:21:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "781764553eeede5054f8eeb9c28549714c5d3bbb",
          "body": null,
          "is_bot": false,
          "headline": "fix import order",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T19:01:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f5e7faea3b3c58da2793d1957d953ba598e3e521",
          "body": "…sage-demo\n\nAdd textchat.py and replymessage.py examples",
          "is_bot": false,
          "headline": "Merge pull request #913 from SilverBull239/examples/textchat-replymes…",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T18:47:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e86a495b503059405800e0e8cc824c5e73cffb0a",
          "body": "Refactor the Meshtastic TCP pub/sub example to ensure proper resource cleanup and clearer exception handling.",
          "is_bot": false,
          "headline": "Merge pull request #899 from dim5x/master",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T18:18:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5dde67ef822668f0e8cc939544d5a0914244e7fd",
          "body": "Inject options in nanopb .options files into the protobuf files used for code generation",
          "is_bot": false,
          "headline": "Merge pull request #922 from ianmcorvidae/nanopb-options-inject",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T17:27:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a7d13eb2c1cf0b968f104953d5a11ceeaaa8c25e",
          "body": null,
          "is_bot": false,
          "headline": "the fuzz",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T17:17:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3916009dbd0bba603af8dabdfcc66e98a7218eed",
          "body": null,
          "is_bot": false,
          "headline": "pylint cleanups",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T17:01:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "280323da8b6bf8922e35d18ddfb81ac52aabc1b3",
          "body": null,
          "is_bot": false,
          "headline": "Add tests of nanopb options injection",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T16:52:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "89d81c9c7aac825c687f588c08a6e225659b7ad3",
          "body": "…for code generation",
          "is_bot": false,
          "headline": "Inject options in nanopb .options files into the protobuf files used …",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T16:42:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fddaad316a76d67f02229f311c38ac2122953110",
          "body": null,
          "is_bot": false,
          "headline": "protobufs: v2.7.24",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-05-31T16:00:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfe38ac0c7c070654da1d0d1a9e6e96f9d53e8d0",
          "body": "…re in __init__\n\nIf connect() or waitForConfig() raises during __init__ (handshake timeout,\nbad stream, config error), the reader thread started by connect() keeps\nrunning and the underlying stream/socket stays open — but the caller never\nreceives a reference to the half-initialized instance, so the\n[…]\nderef bugs in Router::perhapsDecode / MeshService\n(firmware side fixed in meshtastic/firmware#10226 and #10229). The\nclient-side leak is independent of those firmware bugs and worth fixing\non its own.",
          "is_bot": false,
          "headline": "StreamInterface: prevent socket/reader-thread leak on handshake failu…",
          "author_name": "nightjoker7",
          "author_login": "nightjoker7",
          "committed_at": "2026-04-25T20:02:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c5fc51ea37dd2cf6446f137998376f2ef5f6c237",
          "body": null,
          "is_bot": false,
          "headline": "Update factory reset to use integer for config reset",
          "author_name": "Ben Meadors",
          "author_login": "thebentern",
          "committed_at": "2026-04-17T10:03:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cec79a7c1f10c189588f3aae2a7370f9ce9904de",
          "body": null,
          "is_bot": false,
          "headline": "poetry lock",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-04-10T18:42:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6805fee667978671fac4abb2d38893e3def0b9c4",
          "body": null,
          "is_bot": false,
          "headline": "loosen packaging version requirement",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-04-10T18:41:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3cb9ce2a56694553d60b7c5be65309438e0f665f",
          "body": null,
          "is_bot": false,
          "headline": "protobufs: v2.7.21",
          "author_name": "Ian McEwen",
          "author_login": "ianmcorvidae",
          "committed_at": "2026-04-10T18:40:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b05a6a6017152b15acaf45f740254c3186a4ff4c",
          "body": null,
          "is_bot": false,
          "headline": "Added textchat.py and replymessage.py example scripts from TODO",
          "author_name": "Aron Tkachuk",
          "author_login": "SilverBull239",
          "committed_at": "2026-04-05T23:23:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8a842ed82b3e3ff7de840d092e38c9fe0e92e9f4",
          "body": "When other nodes relay our position via map reports, they send it at\nreduced precision (e.g., 13 bits). _onPositionReceive() was blindly\noverwriting our locally-stored high-precision GPS position (32 bits)\nwith these degraded echoes.\n\nThe fix only protects the local node's position — since we have t\n[…]\nh data. Remote node positions are still updated\nnormally, as any position they broadcast reflects their current state.\n\nFixes #910\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix local node position overwrite by low-precision echoes",
          "author_name": "Benjamin Babeshkin",
          "author_login": "syn-ack-ai",
          "committed_at": "2026-03-19T18:18:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 100,
      "commits_last_year": 228,
      "latest_release_at": "2026-07-17T17:39:05Z",
      "latest_release_tag": "2.7.11",
      "releases_from_tags": false,
      "days_since_last_push": 2,
      "active_weeks_last_year": 36,
      "days_since_latest_release": 8,
      "mean_days_between_releases": 34.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "meshtastic",
          "exists": true,
          "license": "GPL-3.0-only",
          "keywords": [
            "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Programming Language :: Python :: 3.14",
            "Programming Language :: Python :: 3.9"
          ],
          "ecosystem": "pypi",
          "matches_repo": null,
          "registry_url": "https://pypi.org/project/meshtastic/",
          "is_deprecated": false,
          "latest_version": "2.7.11",
          "repository_url": null,
          "versions_count": 276,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2020-04-28T22:32:16.639846Z",
          "latest_published_at": "2026-07-17T17:37:11.881185Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 8
        }
      ]
    },
    "popularity": {
      "forks": 334,
      "stars": 826,
      "watchers": 36,
      "fork_history": {
        "days": [
          {
            "date": "2020-06-08",
            "count": 2
          },
          {
            "date": "2020-06-14",
            "count": 1
          },
          {
            "date": "2020-06-20",
            "count": 1
          },
          {
            "date": "2020-06-21",
            "count": 1
          },
          {
            "date": "2020-06-27",
            "count": 1
          },
          {
            "date": "2020-07-14",
            "count": 1
          },
          {
            "date": "2020-07-29",
            "count": 1
          },
          {
            "date": "2020-08-08",
            "count": 1
          },
          {
            "date": "2020-08-13",
            "count": 1
          },
          {
            "date": "2020-08-20",
            "count": 2
          },
          {
            "date": "2020-08-23",
            "count": 1
          },
          {
            "date": "2020-09-01",
            "count": 1
          },
          {
            "date": "2020-09-05",
            "count": 1
          },
          {
            "date": "2020-09-10",
            "count": 1
          },
          {
            "date": "2020-09-16",
            "count": 2
          },
          {
            "date": "2020-09-19",
            "count": 1
          },
          {
            "date": "2020-10-02",
            "count": 1
          },
          {
            "date": "2020-10-29",
            "count": 1
          },
          {
            "date": "2020-11-10",
            "count": 1
          },
          {
            "date": "2020-11-17",
            "count": 1
          },
          {
            "date": "2020-12-04",
            "count": 2
          },
          {
            "date": "2020-12-11",
            "count": 1
          },
          {
            "date": "2020-12-19",
            "count": 1
          },
          {
            "date": "2020-12-30",
            "count": 2
          },
          {
            "date": "2021-01-03",
            "count": 1
          },
          {
            "date": "2021-01-12",
            "count": 1
          },
          {
            "date": "2021-01-16",
            "count": 1
          },
          {
            "date": "2021-01-26",
            "count": 1
          },
          {
            "date": "2021-02-23",
            "count": 1
          },
          {
            "date": "2021-03-07",
            "count": 1
          },
          {
            "date": "2021-03-12",
            "count": 1
          },
          {
            "date": "2021-03-21",
            "count": 1
          },
          {
            "date": "2021-03-23",
            "count": 1
          },
          {
            "date": "2021-03-25",
            "count": 1
          },
          {
            "date": "2021-05-03",
            "count": 1
          },
          {
            "date": "2021-05-25",
            "count": 1
          },
          {
            "date": "2021-05-29",
            "count": 1
          },
          {
            "date": "2021-07-09",
            "count": 1
          },
          {
            "date": "2021-07-13",
            "count": 1
          },
          {
            "date": "2021-08-13",
            "count": 1
          },
          {
            "date": "2021-08-18",
            "count": 1
          },
          {
            "date": "2021-10-29",
            "count": 1
          },
          {
            "date": "2021-12-04",
            "count": 1
          },
          {
            "date": "2021-12-06",
            "count": 1
          },
          {
            "date": "2021-12-08",
            "count": 1
          },
          {
            "date": "2021-12-24",
            "count": 1
          },
          {
            "date": "2021-12-28",
            "count": 1
          },
          {
            "date": "2021-12-30",
            "count": 1
          },
          {
            "date": "2022-01-15",
            "count": 1
          },
          {
            "date": "2022-01-20",
            "count": 1
          },
          {
            "date": "2022-01-21",
            "count": 1
          },
          {
            "date": "2022-02-02",
            "count": 1
          },
          {
            "date": "2022-02-06",
            "count": 1
          },
          {
            "date": "2022-02-08",
            "count": 1
          },
          {
            "date": "2022-02-20",
            "count": 1
          },
          {
            "date": "2022-02-28",
            "count": 1
          },
          {
            "date": "2022-03-11",
            "count": 1
          },
          {
            "date": "2022-03-15",
            "count": 1
          },
          {
            "date": "2022-03-18",
            "count": 1
          },
          {
            "date": "2022-03-30",
            "count": 1
          },
          {
            "date": "2022-04-02",
            "count": 1
          },
          {
            "date": "2022-04-10",
            "count": 1
          },
          {
            "date": "2022-04-11",
            "count": 1
          },
          {
            "date": "2022-06-26",
            "count": 1
          },
          {
            "date": "2022-07-02",
            "count": 1
          },
          {
            "date": "2022-07-21",
            "count": 1
          },
          {
            "date": "2022-07-27",
            "count": 1
          },
          {
            "date": "2022-08-14",
            "count": 1
          },
          {
            "date": "2022-08-28",
            "count": 1
          },
          {
            "date": "2022-09-02",
            "count": 1
          },
          {
            "date": "2022-09-06",
            "count": 1
          },
          {
            "date": "2022-09-09",
            "count": 1
          },
          {
            "date": "2022-10-01",
            "count": 1
          },
          {
            "date": "2022-10-03",
            "count": 1
          },
          {
            "date": "2022-10-08",
            "count": 1
          },
          {
            "date": "2022-10-16",
            "count": 1
          },
          {
            "date": "2022-10-23",
            "count": 1
          },
          {
            "date": "2022-11-02",
            "count": 1
          },
          {
            "date": "2022-11-30",
            "count": 1
          },
          {
            "date": "2022-12-23",
            "count": 1
          },
          {
            "date": "2023-01-16",
            "count": 1
          },
          {
            "date": "2023-02-09",
            "count": 1
          },
          {
            "date": "2023-03-06",
            "count": 1
          },
          {
            "date": "2023-03-25",
            "count": 1
          },
          {
            "date": "2023-04-06",
            "count": 1
          },
          {
            "date": "2023-04-26",
            "count": 1
          },
          {
            "date": "2023-04-28",
            "count": 1
          },
          {
            "date": "2023-06-13",
            "count": 1
          },
          {
            "date": "2023-06-28",
            "count": 1
          },
          {
            "date": "2023-07-07",
            "count": 1
          },
          {
            "date": "2023-07-15",
            "count": 1
          },
          {
            "date": "2023-07-23",
            "count": 1
          },
          {
            "date": "2023-08-11",
            "count": 1
          },
          {
            "date": "2023-09-06",
            "count": 1
          },
          {
            "date": "2023-10-07",
            "count": 1
          },
          {
            "date": "2023-11-16",
            "count": 1
          },
          {
            "date": "2023-11-22",
            "count": 1
          },
          {
            "date": "2023-12-14",
            "count": 1
          },
          {
            "date": "2024-01-03",
            "count": 1
          },
          {
            "date": "2024-01-07",
            "count": 1
          },
          {
            "date": "2024-01-20",
            "count": 1
          },
          {
            "date": "2024-02-10",
            "count": 1
          },
          {
            "date": "2024-02-11",
            "count": 1
          },
          {
            "date": "2024-02-15",
            "count": 1
          },
          {
            "date": "2024-02-25",
            "count": 1
          },
          {
            "date": "2024-03-12",
            "count": 1
          },
          {
            "date": "2024-03-14",
            "count": 1
          },
          {
            "date": "2024-03-18",
            "count": 2
          },
          {
            "date": "2024-03-19",
            "count": 1
          },
          {
            "date": "2024-03-21",
            "count": 1
          },
          {
            "date": "2024-03-29",
            "count": 1
          },
          {
            "date": "2024-03-30",
            "count": 1
          },
          {
            "date": "2024-04-10",
            "count": 1
          },
          {
            "date": "2024-04-13",
            "count": 1
          },
          {
            "date": "2024-04-21",
            "count": 1
          },
          {
            "date": "2024-04-24",
            "count": 2
          },
          {
            "date": "2024-04-30",
            "count": 1
          },
          {
            "date": "2024-05-03",
            "count": 1
          },
          {
            "date": "2024-05-12",
            "count": 1
          },
          {
            "date": "2024-05-16",
            "count": 1
          },
          {
            "date": "2024-05-23",
            "count": 1
          },
          {
            "date": "2024-05-24",
            "count": 1
          },
          {
            "date": "2024-05-28",
            "count": 1
          },
          {
            "date": "2024-06-04",
            "count": 1
          },
          {
            "date": "2024-06-10",
            "count": 2
          },
          {
            "date": "2024-06-13",
            "count": 1
          },
          {
            "date": "2024-06-15",
            "count": 1
          },
          {
            "date": "2024-06-23",
            "count": 2
          },
          {
            "date": "2024-06-24",
            "count": 1
          },
          {
            "date": "2024-06-25",
            "count": 1
          },
          {
            "date": "2024-07-02",
            "count": 1
          },
          {
            "date": "2024-07-08",
            "count": 1
          },
          {
            "date": "2024-07-29",
            "count": 1
          },
          {
            "date": "2024-08-01",
            "count": 1
          },
          {
            "date": "2024-08-28",
            "count": 1
          },
          {
            "date": "2024-09-03",
            "count": 1
          },
          {
            "date": "2024-09-04",
            "count": 1
          },
          {
            "date": "2024-09-11",
            "count": 1
          },
          {
            "date": "2024-09-17",
            "count": 1
          },
          {
            "date": "2024-09-30",
            "count": 2
          },
          {
            "date": "2024-10-10",
            "count": 1
          },
          {
            "date": "2024-10-14",
            "count": 3
          },
          {
            "date": "2024-10-18",
            "count": 1
          },
          {
            "date": "2024-10-19",
            "count": 1
          },
          {
            "date": "2024-10-23",
            "count": 1
          },
          {
            "date": "2024-10-31",
            "count": 1
          },
          {
            "date": "2024-11-02",
            "count": 1
          },
          {
            "date": "2024-11-04",
            "count": 1
          },
          {
            "date": "2024-11-26",
            "count": 2
          },
          {
            "date": "2024-12-01",
            "count": 1
          },
          {
            "date": "2024-12-03",
            "count": 1
          },
          {
            "date": "2024-12-04",
            "count": 1
          },
          {
            "date": "2024-12-14",
            "count": 1
          },
          {
            "date": "2024-12-17",
            "count": 1
          },
          {
            "date": "2024-12-18",
            "count": 1
          },
          {
            "date": "2024-12-28",
            "count": 1
          },
          {
            "date": "2025-01-01",
            "count": 1
          },
          {
            "date": "2025-01-03",
            "count": 1
          },
          {
            "date": "2025-01-06",
            "count": 1
          },
          {
            "date": "2025-01-13",
            "count": 1
          },
          {
            "date": "2025-01-16",
            "count": 1
          },
          {
            "date": "2025-01-18",
            "count": 1
          },
          {
            "date": "2025-01-22",
            "count": 1
          },
          {
            "date": "2025-02-08",
            "count": 1
          },
          {
            "date": "2025-02-09",
            "count": 1
          },
          {
            "date": "2025-02-19",
            "count": 1
          },
          {
            "date": "2025-02-28",
            "count": 1
          },
          {
            "date": "2025-03-01",
            "count": 1
          },
          {
            "date": "2025-03-07",
            "count": 2
          },
          {
            "date": "2025-03-09",
            "count": 1
          },
          {
            "date": "2025-03-11",
            "count": 1
          },
          {
            "date": "2025-03-13",
            "count": 1
          },
          {
            "date": "2025-03-25",
            "count": 1
          },
          {
            "date": "2025-03-28",
            "count": 1
          },
          {
            "date": "2025-03-30",
            "count": 1
          },
          {
            "date": "2025-04-02",
            "count": 1
          },
          {
            "date": "2025-04-07",
            "count": 1
          },
          {
            "date": "2025-04-15",
            "count": 1
          },
          {
            "date": "2025-04-25",
            "count": 1
          },
          {
            "date": "2025-05-05",
            "count": 2
          },
          {
            "date": "2025-05-08",
            "count": 1
          },
          {
            "date": "2025-05-10",
            "count": 1
          },
          {
            "date": "2025-05-11",
            "count": 1
          },
          {
            "date": "2025-05-12",
            "count": 1
          },
          {
            "date": "2025-05-23",
            "count": 1
          },
          {
            "date": "2025-05-24",
            "count": 1
          },
          {
            "date": "2025-05-26",
            "count": 1
          },
          {
            "date": "2025-05-29",
            "count": 1
          },
          {
            "date": "2025-06-03",
            "count": 1
          },
          {
            "date": "2025-06-04",
            "count": 1
          },
          {
            "date": "2025-06-06",
            "count": 3
          },
          {
            "date": "2025-06-07",
            "count": 1
          },
          {
            "date": "2025-06-08",
            "count": 1
          },
          {
            "date": "2025-06-12",
            "count": 1
          },
          {
            "date": "2025-06-17",
            "count": 1
          },
          {
            "date": "2025-06-19",
            "count": 1
          },
          {
            "date": "2025-06-20",
            "count": 1
          },
          {
            "date": "2025-06-24",
            "count": 1
          },
          {
            "date": "2025-06-27",
            "count": 1
          },
          {
            "date": "2025-06-28",
            "count": 1
          },
          {
            "date": "2025-07-04",
            "count": 2
          },
          {
            "date": "2025-07-06",
            "count": 1
          },
          {
            "date": "2025-07-08",
            "count": 2
          },
          {
            "date": "2025-07-12",
            "count": 1
          },
          {
            "date": "2025-07-13",
            "count": 1
          },
          {
            "date": "2025-07-15",
            "count": 1
          },
          {
            "date": "2025-07-16",
            "count": 1
          },
          {
            "date": "2025-07-20",
            "count": 1
          },
          {
            "date": "2025-07-21",
            "count": 1
          },
          {
            "date": "2025-07-24",
            "count": 1
          },
          {
            "date": "2025-07-28",
            "count": 1
          },
          {
            "date": "2025-08-01",
            "count": 1
          },
          {
            "date": "2025-08-06",
            "count": 1
          },
          {
            "date": "2025-08-08",
            "count": 1
          },
          {
            "date": "2025-08-09",
            "count": 1
          },
          {
            "date": "2025-08-12",
            "count": 1
          },
          {
            "date": "2025-08-18",
            "count": 1
          },
          {
            "date": "2025-08-19",
            "count": 2
          },
          {
            "date": "2025-08-21",
            "count": 1
          },
          {
            "date": "2025-08-30",
            "count": 1
          },
          {
            "date": "2025-09-01",
            "count": 1
          },
          {
            "date": "2025-09-05",
            "count": 1
          },
          {
            "date": "2025-09-06",
            "count": 1
          },
          {
            "date": "2025-09-07",
            "count": 1
          },
          {
            "date": "2025-09-18",
            "count": 2
          },
          {
            "date": "2025-09-19",
            "count": 1
          },
          {
            "date": "2025-09-23",
            "count": 1
          },
          {
            "date": "2025-09-27",
            "count": 2
          },
          {
            "date": "2025-09-28",
            "count": 2
          },
          {
            "date": "2025-10-01",
            "count": 2
          },
          {
            "date": "2025-10-03",
            "count": 2
          },
          {
            "date": "2025-10-06",
            "count": 1
          },
          {
            "date": "2025-10-10",
            "count": 1
          },
          {
            "date": "2025-10-12",
            "count": 1
          },
          {
            "date": "2025-10-14",
            "count": 1
          },
          {
            "date": "2025-10-15",
            "count": 1
          },
          {
            "date": "2025-10-18",
            "count": 1
          },
          {
            "date": "2025-10-22",
            "count": 1
          },
          {
            "date": "2025-10-27",
            "count": 1
          },
          {
            "date": "2025-10-28",
            "count": 1
          },
          {
            "date": "2025-10-31",
            "count": 2
          },
          {
            "date": "2025-11-01",
            "count": 1
          },
          {
            "date": "2025-11-06",
            "count": 1
          },
          {
            "date": "2025-11-07",
            "count": 1
          },
          {
            "date": "2025-11-09",
            "count": 1
          },
          {
            "date": "2025-11-10",
            "count": 1
          },
          {
            "date": "2025-11-11",
            "count": 1
          },
          {
            "date": "2025-11-14",
            "count": 2
          },
          {
            "date": "2025-11-20",
            "count": 2
          },
          {
            "date": "2025-11-21",
            "count": 1
          },
          {
            "date": "2025-11-28",
            "count": 2
          },
          {
            "date": "2025-11-29",
            "count": 2
          },
          {
            "date": "2025-12-16",
            "count": 1
          },
          {
            "date": "2025-12-17",
            "count": 1
          },
          {
            "date": "2025-12-28",
            "count": 1
          },
          {
            "date": "2026-01-18",
            "count": 2
          },
          {
            "date": "2026-01-19",
            "count": 2
          },
          {
            "date": "2026-01-21",
            "count": 1
          },
          {
            "date": "2026-01-24",
            "count": 1
          },
          {
            "date": "2026-01-26",
            "count": 2
          },
          {
            "date": "2026-01-29",
            "count": 2
          },
          {
            "date": "2026-01-31",
            "count": 1
          },
          {
            "date": "2026-02-05",
            "count": 2
          },
          {
            "date": "2026-02-10",
            "count": 1
          },
          {
            "date": "2026-02-21",
            "count": 1
          },
          {
            "date": "2026-02-27",
            "count": 2
          },
          {
            "date": "2026-03-03",
            "count": 1
          },
          {
            "date": "2026-03-19",
            "count": 1
          },
          {
            "date": "2026-04-05",
            "count": 1
          },
          {
            "date": "2026-04-09",
            "count": 1
          },
          {
            "date": "2026-04-12",
            "count": 1
          },
          {
            "date": "2026-04-23",
            "count": 1
          },
          {
            "date": "2026-04-25",
            "count": 1
          },
          {
            "date": "2026-05-01",
            "count": 1
          },
          {
            "date": "2026-05-08",
            "count": 1
          },
          {
            "date": "2026-05-09",
            "count": 2
          },
          {
            "date": "2026-05-17",
            "count": 1
          },
          {
            "date": "2026-05-28",
            "count": 1
          },
          {
            "date": "2026-06-03",
            "count": 1
          },
          {
            "date": "2026-06-17",
            "count": 1
          },
          {
            "date": "2026-06-29",
            "count": 1
          },
          {
            "date": "2026-07-02",
            "count": 2
          },
          {
            "date": "2026-07-04",
            "count": 1
          },
          {
            "date": "2026-07-16",
            "count": 1
          },
          {
            "date": "2026-07-18",
            "count": 2
          },
          {
            "date": "2026-07-22",
            "count": 1
          },
          {
            "date": "2026-07-23",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 326,
        "total_forks": 334
      },
      "star_history": null,
      "open_issues_and_prs": 137
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 140787,
      "source_files_sampled": 98,
      "oversized_source_files": 4,
      "agent_instruction_files": [
        ".github/copilot-instructions.md"
      ],
      "agent_instruction_max_bytes": 6037
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 13,
        "malicious_count": 0,
        "assessed_package": "pypi:meshtastic@2.7.11",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "pyserial",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^3.5"
        },
        {
          "name": "protobuf",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=4.21.12"
        },
        {
          "name": "tabulate",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^0.9.0"
        },
        {
          "name": "requests",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^2.31.0"
        },
        {
          "name": "pyyaml",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^6.0.1"
        },
        {
          "name": "pypubsub",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^4.0.3"
        },
        {
          "name": "bleak",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.22.3"
        },
        {
          "name": "packaging",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=24.0"
        },
        {
          "name": "argcomplete",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^3.5.2"
        },
        {
          "name": "pyqrcode",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^1.2.1"
        },
        {
          "name": "dotmap",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^1.3.30"
        },
        {
          "name": "print-color",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^0.4.6"
        },
        {
          "name": "dash",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^2.17.1"
        },
        {
          "name": "pytap2",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^2.3.0"
        },
        {
          "name": "dash-bootstrap-components",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^1.6.0"
        },
        {
          "name": "pandas",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^2.2.2"
        },
        {
          "name": "pandas-stubs",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^2.2.2.240603"
        },
        {
          "name": "wcwidth",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "^0.2.13"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "argcomplete",
            "direct": true,
            "version": "3.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "bleak",
            "direct": true,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "dash",
            "direct": true,
            "version": "2.18.2",
            "ecosystem": "pypi"
          },
          {
            "name": "dash-bootstrap-components",
            "direct": true,
            "version": "1.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "dotmap",
            "direct": true,
            "version": "1.3.30",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": true,
            "version": "24.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pandas",
            "direct": true,
            "version": "2.3.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pandas-stubs",
            "direct": true,
            "version": "2.2.2.240807",
            "ecosystem": "pypi"
          },
          {
            "name": "print-color",
            "direct": true,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "protobuf",
            "direct": true,
            "version": "6.33.6",
            "ecosystem": "pypi"
          },
          {
            "name": "pypubsub",
            "direct": true,
            "version": "4.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyqrcode",
            "direct": true,
            "version": "1.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyserial",
            "direct": true,
            "version": "3.5",
            "ecosystem": "pypi"
          },
          {
            "name": "pytap2",
            "direct": true,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": true,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": true,
            "version": "2.32.5",
            "ecosystem": "pypi"
          },
          {
            "name": "tabulate",
            "direct": true,
            "version": "0.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "wcwidth",
            "direct": true,
            "version": "0.2.14",
            "ecosystem": "pypi"
          },
          {
            "name": "altgraph",
            "direct": false,
            "version": "0.17.4",
            "ecosystem": "pypi"
          },
          {
            "name": "anyio",
            "direct": false,
            "version": "4.11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "appnope",
            "direct": false,
            "version": "0.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "argon2-cffi",
            "direct": false,
            "version": "25.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "argon2-cffi-bindings",
            "direct": false,
            "version": "25.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "arrow",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "astroid",
            "direct": false,
            "version": "3.3.11",
            "ecosystem": "pypi"
          },
          {
            "name": "asttokens",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "async-lru",
            "direct": false,
            "version": "2.0.5",
            "ecosystem": "pypi"
          },
          {
            "name": "async-timeout",
            "direct": false,
            "version": "5.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "attrs",
            "direct": false,
            "version": "25.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "autopep8",
            "direct": false,
            "version": "2.3.2",
            "ecosystem": "pypi"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "beautifulsoup4",
            "direct": false,
            "version": "4.14.2",
            "ecosystem": "pypi"
          },
          {
            "name": "bleach",
            "direct": false,
            "version": "6.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "blinker",
            "direct": false,
            "version": "1.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2025.10.5",
            "ecosystem": "pypi"
          },
          {
            "name": "cffi",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "click",
            "direct": false,
            "version": "8.1.8",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "comm",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "contourpy",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "coverage",
            "direct": false,
            "version": "7.10.7",
            "ecosystem": "pypi"
          },
          {
            "name": "cycler",
            "direct": false,
            "version": "0.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "dash-core-components",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "dash-html-components",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "dash-table",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "dbus-fast",
            "direct": false,
            "version": "2.45.1",
            "ecosystem": "pypi"
          },
          {
            "name": "debugpy",
            "direct": false,
            "version": "1.8.17",
            "ecosystem": "pypi"
          },
          {
            "name": "decorator",
            "direct": false,
            "version": "5.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "defusedxml",
            "direct": false,
            "version": "0.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "dill",
            "direct": false,
            "version": "0.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "exceptiongroup",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "executing",
            "direct": false,
            "version": "2.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fastjsonschema",
            "direct": false,
            "version": "2.21.2",
            "ecosystem": "pypi"
          },
          {
            "name": "flask",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "fonttools",
            "direct": false,
            "version": "4.60.2",
            "ecosystem": "pypi"
          },
          {
            "name": "fqdn",
            "direct": false,
            "version": "1.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "h11",
            "direct": false,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "httpcore",
            "direct": false,
            "version": "1.0.9",
            "ecosystem": "pypi"
          },
          {
            "name": "httpx",
            "direct": false,
            "version": "0.28.1",
            "ecosystem": "pypi"
          },
          {
            "name": "hypothesis",
            "direct": false,
            "version": "6.141.1",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.17",
            "ecosystem": "pypi"
          },
          {
            "name": "importlib-metadata",
            "direct": false,
            "version": "8.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "importlib-resources",
            "direct": false,
            "version": "6.5.2",
            "ecosystem": "pypi"
          },
          {
            "name": "iniconfig",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ipykernel",
            "direct": false,
            "version": "6.31.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ipympl",
            "direct": false,
            "version": "0.9.8",
            "ecosystem": "pypi"
          },
          {
            "name": "ipython",
            "direct": false,
            "version": "8.18.1",
            "ecosystem": "pypi"
          },
          {
            "name": "ipython-pygments-lexers",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "ipywidgets",
            "direct": false,
            "version": "8.1.8",
            "ecosystem": "pypi"
          },
          {
            "name": "isoduration",
            "direct": false,
            "version": "20.11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "isort",
            "direct": false,
            "version": "6.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "itsdangerous",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jedi",
            "direct": false,
            "version": "0.19.2",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": false,
            "version": "3.1.6",
            "ecosystem": "pypi"
          },
          {
            "name": "json5",
            "direct": false,
            "version": "0.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonpointer",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonschema",
            "direct": false,
            "version": "4.25.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonschema-specifications",
            "direct": false,
            "version": "2025.9.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-client",
            "direct": false,
            "version": "8.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-core",
            "direct": false,
            "version": "5.8.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-events",
            "direct": false,
            "version": "0.12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-lsp",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-server",
            "direct": false,
            "version": "2.18.2",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyter-server-terminals",
            "direct": false,
            "version": "0.5.3",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab",
            "direct": false,
            "version": "4.5.7",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab-pygments",
            "direct": false,
            "version": "0.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab-server",
            "direct": false,
            "version": "2.28.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jupyterlab-widgets",
            "direct": false,
            "version": "3.0.16",
            "ecosystem": "pypi"
          },
          {
            "name": "kiwisolver",
            "direct": false,
            "version": "1.4.7",
            "ecosystem": "pypi"
          },
          {
            "name": "lark",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "macholib",
            "direct": false,
            "version": "1.16.3",
            "ecosystem": "pypi"
          },
          {
            "name": "mako",
            "direct": false,
            "version": "1.3.12",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown",
            "direct": false,
            "version": "3.9",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "matplotlib",
            "direct": false,
            "version": "3.9.4",
            "ecosystem": "pypi"
          },
          {
            "name": "matplotlib-inline",
            "direct": false,
            "version": "0.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mccabe",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mistune",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "modbus-tk",
            "direct": false,
            "version": "1.1.5",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy",
            "direct": false,
            "version": "1.18.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy-extensions",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy-protobuf",
            "direct": false,
            "version": "3.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "narwhals",
            "direct": false,
            "version": "2.11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "nbclient",
            "direct": false,
            "version": "0.10.2",
            "ecosystem": "pypi"
          },
          {
            "name": "nbconvert",
            "direct": false,
            "version": "7.17.1",
            "ecosystem": "pypi"
          },
          {
            "name": "nbformat",
            "direct": false,
            "version": "5.10.4",
            "ecosystem": "pypi"
          },
          {
            "name": "nest-asyncio",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "notebook-shim",
            "direct": false,
            "version": "0.2.4",
            "ecosystem": "pypi"
          },
          {
            "name": "numpy",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "overrides",
            "direct": false,
            "version": "7.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pandocfilters",
            "direct": false,
            "version": "1.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "parse",
            "direct": false,
            "version": "1.20.2",
            "ecosystem": "pypi"
          },
          {
            "name": "parso",
            "direct": false,
            "version": "0.8.5",
            "ecosystem": "pypi"
          },
          {
            "name": "pathspec",
            "direct": false,
            "version": "0.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pdoc3",
            "direct": false,
            "version": "0.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pefile",
            "direct": false,
            "version": "2023.2.7",
            "ecosystem": "pypi"
          },
          {
            "name": "pexpect",
            "direct": false,
            "version": "4.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pillow",
            "direct": false,
            "version": "11.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "platformdirs",
            "direct": false,
            "version": "4.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "plotly",
            "direct": false,
            "version": "6.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pluggy",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ppk2-api",
            "direct": false,
            "version": "0.9.2",
            "ecosystem": "pypi"
          },
          {
            "name": "prometheus-client",
            "direct": false,
            "version": "0.23.1",
            "ecosystem": "pypi"
          },
          {
            "name": "prompt-toolkit",
            "direct": false,
            "version": "3.0.52",
            "ecosystem": "pypi"
          },
          {
            "name": "psutil",
            "direct": false,
            "version": "7.1.3",
            "ecosystem": "pypi"
          },
          {
            "name": "ptyprocess",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pure-eval",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyarrow",
            "direct": false,
            "version": "18.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyarrow-stubs",
            "direct": false,
            "version": "10.0.1.9",
            "ecosystem": "pypi"
          },
          {
            "name": "pycodestyle",
            "direct": false,
            "version": "2.14.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pycparser",
            "direct": false,
            "version": "2.23",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.20.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyinstaller",
            "direct": false,
            "version": "6.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyinstaller-hooks-contrib",
            "direct": false,
            "version": "2025.9",
            "ecosystem": "pypi"
          },
          {
            "name": "pylint",
            "direct": false,
            "version": "3.3.9",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-core",
            "direct": false,
            "version": "12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-cocoa",
            "direct": false,
            "version": "12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-corebluetooth",
            "direct": false,
            "version": "12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-libdispatch",
            "direct": false,
            "version": "12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyparsing",
            "direct": false,
            "version": "3.2.5",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "8.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-cov",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dateutil",
            "direct": false,
            "version": "2.9.0.post0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-json-logger",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytz",
            "direct": false,
            "version": "2025.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pywin32",
            "direct": false,
            "version": "311",
            "ecosystem": "pypi"
          },
          {
            "name": "pywin32-ctypes",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pywinpty",
            "direct": false,
            "version": "3.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pyzmq",
            "direct": false,
            "version": "27.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "referencing",
            "direct": false,
            "version": "0.36.2",
            "ecosystem": "pypi"
          },
          {
            "name": "retrying",
            "direct": false,
            "version": "1.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3339-validator",
            "direct": false,
            "version": "0.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3986-validator",
            "direct": false,
            "version": "0.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3987-syntax",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "rpds-py",
            "direct": false,
            "version": "0.27.1",
            "ecosystem": "pypi"
          },
          {
            "name": "send2trash",
            "direct": false,
            "version": "1.8.3",
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": "82.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sniffio",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sortedcontainers",
            "direct": false,
            "version": "2.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "soupsieve",
            "direct": false,
            "version": "2.8",
            "ecosystem": "pypi"
          },
          {
            "name": "stack-data",
            "direct": false,
            "version": "0.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "terminado",
            "direct": false,
            "version": "0.18.1",
            "ecosystem": "pypi"
          },
          {
            "name": "tinycss2",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomlkit",
            "direct": false,
            "version": "0.13.3",
            "ecosystem": "pypi"
          },
          {
            "name": "tornado",
            "direct": false,
            "version": "6.5.6",
            "ecosystem": "pypi"
          },
          {
            "name": "traitlets",
            "direct": false,
            "version": "5.14.3",
            "ecosystem": "pypi"
          },
          {
            "name": "types-protobuf",
            "direct": false,
            "version": "5.29.1.20250403",
            "ecosystem": "pypi"
          },
          {
            "name": "types-pytz",
            "direct": false,
            "version": "2025.2.0.20251108",
            "ecosystem": "pypi"
          },
          {
            "name": "types-pyyaml",
            "direct": false,
            "version": "6.0.12.20250915",
            "ecosystem": "pypi"
          },
          {
            "name": "types-requests",
            "direct": false,
            "version": "2.32.4.20250913",
            "ecosystem": "pypi"
          },
          {
            "name": "types-setuptools",
            "direct": false,
            "version": "69.5.0.20240522",
            "ecosystem": "pypi"
          },
          {
            "name": "types-tabulate",
            "direct": false,
            "version": "0.9.0.20241207",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tzdata",
            "direct": false,
            "version": "2025.2",
            "ecosystem": "pypi"
          },
          {
            "name": "uri-template",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "webcolors",
            "direct": false,
            "version": "24.11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "webencodings",
            "direct": false,
            "version": "0.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "websocket-client",
            "direct": false,
            "version": "1.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "werkzeug",
            "direct": false,
            "version": "3.0.6",
            "ecosystem": "pypi"
          },
          {
            "name": "widgetsnbextension",
            "direct": false,
            "version": "4.0.15",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-runtime",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-devices-bluetooth",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-devices-bluetooth-advertisement",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-devices-bluetooth-genericattributeprofile",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-devices-enumeration",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-foundation",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-foundation-collections",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "winrt-windows-storage-streams",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "zipp",
            "direct": false,
            "version": "3.23.0",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 193,
        "direct_count": 18,
        "indirect_count": 175
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 21,
        "merged_prs": 433,
        "open_issues": 116,
        "closed_ratio": 0.726,
        "closed_issues": 308,
        "closed_unmerged_prs": 71
      },
      "bus_factor": 3,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "mkinney",
          "commits": 516,
          "avatar_url": "https://avatars.githubusercontent.com/u/2219838?v=4"
        },
        {
          "type": "User",
          "login": "geeksville",
          "commits": 514,
          "avatar_url": "https://avatars.githubusercontent.com/u/225513?v=4"
        },
        {
          "type": "User",
          "login": "ianmcorvidae",
          "commits": 491,
          "avatar_url": "https://avatars.githubusercontent.com/u/106004?v=4"
        },
        {
          "type": "User",
          "login": "thebentern",
          "commits": 199,
          "avatar_url": "https://avatars.githubusercontent.com/u/9000580?v=4"
        },
        {
          "type": "User",
          "login": "mc-hamster",
          "commits": 89,
          "avatar_url": "https://avatars.githubusercontent.com/u/12804989?v=4"
        },
        {
          "type": "User",
          "login": "pdxlocations",
          "commits": 37,
          "avatar_url": "https://avatars.githubusercontent.com/u/117498748?v=4"
        },
        {
          "type": "User",
          "login": "GUVWAF",
          "commits": 34,
          "avatar_url": "https://avatars.githubusercontent.com/u/78759985?v=4"
        },
        {
          "type": "User",
          "login": "caveman99",
          "commits": 28,
          "avatar_url": "https://avatars.githubusercontent.com/u/25002?v=4"
        },
        {
          "type": "User",
          "login": "migillett",
          "commits": 20,
          "avatar_url": "https://avatars.githubusercontent.com/u/51103663?v=4"
        },
        {
          "type": "User",
          "login": "sachaw",
          "commits": 17,
          "avatar_url": "https://avatars.githubusercontent.com/u/11172820?v=4"
        }
      ],
      "contributors_sampled": 99,
      "top_contributor_share": 0.235
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "cleanup_artifacts.yml",
        "container-build.yaml",
        "daily_simradio.yml",
        "release.yml",
        "update_protobufs.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [
        ".pylintrc",
        "ruff.toml"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "poetry.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "3 out of 3 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 1,
            "reason": "Found 2/15 approved changesets -- score normalized to 1",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 17 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "53 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "ae710478fb62924ee56f61f9c339f0aac018af82",
        "ran_at": "2026-07-25T19:39:07Z",
        "aggregate_score": 4.4,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-25T07:00:11Z",
      "oldest_open_prs": [
        {
          "number": 577,
          "created_at": "2024-05-16T15:04:42Z",
          "last_comment_at": "2024-05-21T07:51:07Z",
          "last_comment_author": "aikomastboom"
        },
        {
          "number": 595,
          "created_at": "2024-06-14T05:40:22Z",
          "last_comment_at": "2024-06-26T05:01:26Z",
          "last_comment_author": "nerdenator"
        },
        {
          "number": 745,
          "created_at": "2025-02-26T06:02:29Z",
          "last_comment_at": "2025-05-08T22:25:59Z",
          "last_comment_author": "ianmcorvidae"
        },
        {
          "number": 747,
          "created_at": "2025-03-03T12:48:36Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 787,
          "created_at": "2025-06-10T15:08:06Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 803,
          "created_at": "2025-07-09T19:58:12Z",
          "last_comment_at": "2025-07-09T19:58:18Z",
          "last_comment_author": "CLAassistant"
        },
        {
          "number": 836,
          "created_at": "2025-10-10T06:24:12Z",
          "last_comment_at": "2025-10-10T06:39:38Z",
          "last_comment_author": "jkrauska"
        },
        {
          "number": 846,
          "created_at": "2025-10-27T18:00:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 859,
          "created_at": "2025-11-12T00:49:03Z",
          "last_comment_at": "2025-11-23T19:46:05Z",
          "last_comment_author": "SpudGunMan"
        },
        {
          "number": 867,
          "created_at": "2025-11-22T13:10:01Z",
          "last_comment_at": "2025-11-22T13:10:07Z",
          "last_comment_author": "CLAassistant"
        },
        {
          "number": 872,
          "created_at": "2025-11-30T08:34:49Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 873,
          "created_at": "2025-12-03T13:59:24Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 903,
          "created_at": "2026-02-08T17:17:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 915,
          "created_at": "2026-04-13T00:09:51Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 936,
          "created_at": "2026-06-17T23:04:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 945,
          "created_at": "2026-07-02T18:19:06Z",
          "last_comment_at": "2026-07-02T18:19:47Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 953,
          "created_at": "2026-07-10T16:35:24Z",
          "last_comment_at": "2026-07-10T16:35:31Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 954,
          "created_at": "2026-07-10T17:30:01Z",
          "last_comment_at": "2026-07-10T17:30:07Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 960,
          "created_at": "2026-07-17T18:49:58Z",
          "last_comment_at": "2026-07-17T18:50:24Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 961,
          "created_at": "2026-07-18T23:04:51Z",
          "last_comment_at": "2026-07-18T23:05:15Z",
          "last_comment_author": "coderabbitai"
        }
      ],
      "last_merged_pr_at": "2026-07-17T17:29:15Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 155,
          "created_at": "2021-12-10T18:14:04Z",
          "last_comment_at": "2022-01-18T06:23:50Z",
          "last_comment_author": "mkinney"
        },
        {
          "number": 184,
          "created_at": "2021-12-29T06:19:35Z",
          "last_comment_at": "2025-07-12T14:59:54Z",
          "last_comment_author": "SubhaNAG2001"
        },
        {
          "number": 259,
          "created_at": "2022-02-02T19:55:06Z",
          "last_comment_at": "2022-03-18T19:35:43Z",
          "last_comment_author": "mkinney"
        },
        {
          "number": 393,
          "created_at": "2022-10-31T13:31:44Z",
          "last_comment_at": "2022-10-31T14:20:57Z",
          "last_comment_author": "charlesmarseille"
        },
        {
          "number": 435,
          "created_at": "2023-03-31T02:42:07Z",
          "last_comment_at": "2025-10-27T08:19:40Z",
          "last_comment_author": "juergenRe"
        },
        {
          "number": 437,
          "created_at": "2023-04-01T20:40:38Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 464,
          "created_at": "2023-11-16T01:25:08Z",
          "last_comment_at": "2025-10-26T09:33:09Z",
          "last_comment_author": "juergenRe"
        },
        {
          "number": 467,
          "created_at": "2023-12-04T12:42:21Z",
          "last_comment_at": "2024-03-17T06:40:59Z",
          "last_comment_author": "r-tierney"
        },
        {
          "number": 491,
          "created_at": "2024-02-25T21:38:24Z",
          "last_comment_at": "2024-06-08T14:36:21Z",
          "last_comment_author": "ianmcorvidae"
        },
        {
          "number": 493,
          "created_at": "2024-03-01T12:04:58Z",
          "last_comment_at": "2024-03-22T14:46:18Z",
          "last_comment_author": "francisuk1989"
        },
        {
          "number": 494,
          "created_at": "2024-03-02T01:09:12Z",
          "last_comment_at": "2024-03-05T05:26:28Z",
          "last_comment_author": "OpenSource-For-Freedom"
        },
        {
          "number": 500,
          "created_at": "2024-03-13T03:19:08Z",
          "last_comment_at": "2024-03-13T12:30:26Z",
          "last_comment_author": "clwgh"
        },
        {
          "number": 506,
          "created_at": "2024-03-15T06:02:17Z",
          "last_comment_at": "2025-02-16T18:49:57Z",
          "last_comment_author": "mgtz505"
        },
        {
          "number": 522,
          "created_at": "2024-03-21T20:32:32Z",
          "last_comment_at": "2024-04-03T16:05:34Z",
          "last_comment_author": "geeksville"
        },
        {
          "number": 537,
          "created_at": "2024-04-06T00:04:30Z",
          "last_comment_at": "2024-05-07T13:29:01Z",
          "last_comment_author": "CR-DMcDonald"
        },
        {
          "number": 542,
          "created_at": "2024-04-09T08:53:32Z",
          "last_comment_at": "2024-07-31T03:08:56Z",
          "last_comment_author": "jbroxson"
        },
        {
          "number": 547,
          "created_at": "2024-04-17T16:11:18Z",
          "last_comment_at": "2024-04-17T18:04:19Z",
          "last_comment_author": "thebentern"
        },
        {
          "number": 550,
          "created_at": "2024-04-21T10:17:29Z",
          "last_comment_at": "2025-10-23T22:34:08Z",
          "last_comment_author": "dr3x"
        },
        {
          "number": 566,
          "created_at": "2024-05-07T15:18:38Z",
          "last_comment_at": "2024-07-02T13:17:44Z",
          "last_comment_author": "holdenweb"
        },
        {
          "number": 567,
          "created_at": "2024-05-08T10:00:07Z",
          "last_comment_at": "2024-06-08T15:05:46Z",
          "last_comment_author": "ianmcorvidae"
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/meshtastic/python",
    "host": "github.com",
    "name": "python",
    "owner": "meshtastic"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 76,
      "inputs": {
        "security": 55,
        "vitality": 89,
        "community": 74,
        "governance": 80,
        "engineering": 76
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 89,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 89,
            "inputs": {
              "commits_last_year": 228,
              "human_commit_share": 1,
              "days_since_last_push": 2,
              "active_weeks_last_year": 36
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "36/52 weeks with commits",
                "points": 24.9,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 36
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "228 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 228
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 100,
              "latest_release_tag": "2.7.11",
              "releases_from_tags": false,
              "days_since_latest_release": 8,
              "mean_days_between_releases": 34.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 8 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~34.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 34.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 2,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 2 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "good",
        "name": "Community & Adoption",
        "value": 74,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "good",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 77,
            "inputs": {
              "forks": 334,
              "stars": 826,
              "watchers": 36,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "826 stars",
                "points": 47.3,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 826
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "334 forks",
                "points": 21,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 334
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "36 watchers",
                "points": 8.6,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 36
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (GPL-3.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "GPL-3.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "good",
        "name": "Sustainability & Governance",
        "value": 80,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "good",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 77,
            "inputs": {
              "bus_factor": 3,
              "contributors_sampled": 99,
              "top_contributor_share": 0.235
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "3 contributor(s) cover half of all commits",
                "points": 36,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 24% of commits",
                "points": 17.2,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 24
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "99 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 99
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 17 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "merged_prs": 433,
              "open_issues": 116,
              "closed_issues": 308,
              "issue_closed_ratio": 0.726,
              "closed_unmerged_prs": 71
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "73% of issues closed",
                "points": 33.9,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 73
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "433/504 decided PRs merged",
                "points": 32.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 433,
                      "decided": 504
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 2/15 approved changesets -- score normalized to 1",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "followers": 7009,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "meshtastic",
              "public_repos": 138,
              "account_age_days": 2338
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "7,009 followers of meshtastic",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 7009,
                      "login": "meshtastic"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "138 public repos, account ~6 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 138
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 6
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "meshtastic"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 8
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 8 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "276 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 276
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 76,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "6 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": ".pylintrc, ruff.toml",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".pylintrc, ruff.toml"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "3 out of 3 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [
                "meshtastic",
                "meshtastic-python"
              ],
              "has_wiki": false,
              "homepage": "https://meshtastic.org",
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://meshtastic.org",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "2 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 55,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 44,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 4.4
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "3 out of 3 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 2/15 approved changesets -- score normalized to 1",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 17 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "53 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the pypi:meshtastic@2.7.11 runtime dependency closure — what installing the published package pulls in — 13 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "pypi:meshtastic@2.7.11",
                  "assessed": 13
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 13,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 13,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 13
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 60,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "moderate",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 59,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.26,
              "agent_instruction_files": [
                ".github/copilot-instructions.md"
              ],
              "agent_instruction_max_bytes": 6037
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": ".github/copilot-instructions.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".github/copilot-instructions.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "26 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 13.9,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 26,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 71,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "poetry.lock"
              ],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0.05,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": ".pylintrc, ruff.toml",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".pylintrc, ruff.toml"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "5 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 5,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 53,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 140787,
              "source_files_sampled": 98,
              "oversized_source_files": 4
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "4/98 source files over 60KB",
                "points": 52.8,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 98,
                      "oversized": 4
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-25T19:39:30.675690Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/m/meshtastic/python.svg",
  "full_name": "meshtastic/python",
  "license_state": "standard",
  "license_spdx": "GPL-3.0"
}

Оцінки — це сигнали, а не гарантії. Вони відображають публічно видимі практики на GitHub — це не аудит коду й не гарантія безпеки.

Відсутні дані виключаються, а ваги перенормовуються — нуль за відсутність ніколи не ставиться. Методологія версіонована й відкрита: метрики v1.13.0, схема v0.27.0 — повна методологія · вікі метрик.

Як окремий результат виглядає на тлі всього реєстру: сукупна статистикаPyPI.