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

Tobi-De / fujin

Get your project up and running in minutes on your vps.

PythonMIT★ 15 зірок⑂ 0 форківз жовт. 2024 р.Переглянути на GitHub ↗
ТипБібліотекаяк це визначено

Tobi-De/fujin має індекс здоров’я 69 зі 100, що відповідає смузі «Добрий». Найвищий показник — Engineering Quality (95/100), найнижчий — Community & Adoption (33/100). Останнє оновлення було 31 день тому. Більшість нещодавньої роботи виконує один учасник.

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

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

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

69
Винятковий93-100Верхній щабель реєстру (≈ топ-5%); відповідає практично всім перевіреним критеріям
Відмінний80-92Сильний за всіма напрямами; незначні прогалини
Добрий65-79Здоровий; прогалини обмежені та керовані
Помірний50-64Прийнятний, але з помітними прогалинами; рекомендовано перевірку
Слабкий35-49Суттєві недоліки в кількох сферах
У зоні ризику20-34Суттєві слабкі місця; впровадження потребує обережності
Критичний1-19Серйозні проблеми (покинутий, єдиний мейнтейнер, без базової гігієни)
ЖиттєздатністьСпільнота тавпровадженняСталість таврядуванняІнженернаякістьБезпекаГотовність доШІ

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

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

Зважений загальний бал 62 калібровано до 69 за шкалою опублікованого індексу (калібрування реєстру 2026-08-02).

Власність

TobiОсобистий обліковий запис
167 підписників151 публічний репозиторійз черв. 2018 р.

Цей репозиторій належить особистому обліковому запису. Проєкт з єдиним власником несе більший ризик безперервності, ніж підтримуваний організацією.

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

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікаціяТеги
PyPIfujin-cli0.27.1-6131 день томуcaddydeploymentdjangofastapilitestarpythonsystemd

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

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

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

71Добрий · 21% загального індексу
Як обчислюється оцінка
18/36Свіжість push — останній push 31 дн. тому
11.8/36Ритм комітів — 17/52 тижнів із комітами
18/18Обсяг комітів — 226 комітів за останній рік
10/10OpenSSF Scorecard: Maintained — 17 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
Використані вхідні дані
commits_last_year226
human_commit_share1
days_since_last_push31
active_weeks_last_year17
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 51 релізів
36/36Свіжість релізів — останній реліз 31 дн. тому
27/27Ритм релізів — реліз кожні ~10,7 дн.
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Використані вхідні дані
releases_count51
latest_release_tagv0.27.1
releases_from_tagsні
days_since_latest_release31
mean_days_between_releases10,7

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

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

33У зоні ризику · 17% загального індексу
Як обчислюється оцінка
18.6/60Зірки — 15 зірок
0/25Форки — 0 форків
0/15Спостерігачі — 0 спостерігачів
Використані вхідні дані
forks0
stars15
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
0/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
readme_badges
has_contributingні
has_issue_templateні
has_code_of_conductні
readme_badge_services
has_pull_request_templateні

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

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

57Помірний · 23% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
0/22.5Розподіл комітів — головний контриб’ютор — автор 100% комітів
1.4/13.5Широта контриб’юторів — 1 контриб’юторів
10/10OpenSSF Scorecard: Contributors — project has 3 contributing companies or organizations -- score normalized to 10
Використані вхідні дані
bus_factor1
contributors_sampled1
top_contributor_share1
Як обчислюється оцінка
34.2/42Вирішення issue — закрито 81% issue
18/30Прийняття PR — злито 9/15 вирішених PR
0/13Newcomer PR acceptance — за 30 дн. не вирішено жодного PR від новачка
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Використані вхідні дані
merged_prs9
open_issues11
closed_issues48
prs_merged_7d
prs_decided_7d
prs_merged_30d
prs_decided_30d
issue_closed_ratio0,814
closed_unmerged_prs6
first_time_authors_30d
first_time_prs_merged_30d
first_time_prs_decided_30d
Виключено з оцінювання (немає даних або не застосовно): newcomer_pr_acceptance. Залишкові ваги перенормовано.
Як обчислюється оцінка
10/30Підтримка власника — особистий (користувацький) обліковий запис
0/20Верифікований домен — не застосовно до користувацьких облікових записів
16/25Охоплення власника — 167 підписників у Tobi-De
25/25Послужний список — 151 публічних репозиторіїв, вік облікового запису ~8 р.
Використані вхідні дані
followers167
owner_typeUser
is_verified
owner_loginTobi-De
public_repos151
account_age_days2 962
Виключено з оцінювання (немає даних або не застосовно): Верифікований домен. Залишкові ваги перенормовано.

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

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

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

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

95Винятковий · 19% загального індексу
Як обчислюється оцінка
24/24Процеси CI — 2 процес(ів) CI
24/24Наявні тести
16/16Конфігурація лінтера
9.6/9.6Pre-commit-хуки
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — немає даних
Використані вхідні дані
has_ciтак
has_testsтак
has_editorconfigні
has_linter_configтак
has_precommit_configтак
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: CI-Tests. Залишкові ваги перенормовано.

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

100Винятковий
Як обчислюється оцінка
30/30README
25/25Каталог документації
15/15Сайт документації / домашня сторінка — https://fujin.oluwatobi.dev/en/latest/
10/10Опис репозиторію
10/10Теми — 5 тем
10/10Wiki
Використані вхідні дані
topicsdeployment, django, fastapi, litestar, python-p
has_wikiтак
homepagehttps://fujin.oluwatobi.dev/en/latest/
has_readmeтак
has_docs_dirтак
has_descriptionтак

Безпека

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

47Слабкий · 16% загального індексу

Стан безпеки

34У зоні ризику
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — немає даних
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 3 contributing companies or organizations -- score normalized to 10
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
7.5/7.5Maintained — 17 commit(s) and 6 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 — no SAST tool detected
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 — 79 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate3,4
Виключено з оцінювання (немає даних або не застосовно): ci_tests. Залишкові ваги перенормовано.
Як обчислюється оцінка
35/35Прямі залежності без відомих сповіщень — жодна пряма залежність не має відомих сповіщень
25/25Непрямі залежності без відомих сповіщень — жодна непряма залежність не має відомих сповіщень
0/40Немає задавнених сповіщень — жодне сповіщення не має дати публікації
Використані вхідні дані
sourceosv
advisories0
affected_packages0
assessed_packages11
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Виключено з оцінювання (немає даних або не застосовно): Немає задавнених сповіщень. Залишкові ваги перенормовано. Звірено з runtime-замиканням залежностей pypi:fujin-cli@0.27.1 — тим, що тягне за собою встановлення опублікованого пакета, — 11 пакетів. Досяжність не аналізується.

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

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Має свідомо малу вагу (4%): агентний інструментарій — реальний сигнал супроводу, але репозиторій без нього все одно може отримати 100/100.

73Добрий · 4% загального індексу
Як обчислюється оцінка
45/45Інструкції для агентів — CLAUDE.md
0/15Машиночитана документація (llms.txt)
26.7/40Читабельна історія комітів — намір зазначено у 50 з 100 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,5
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes15 112
Як обчислюється оцінка
18/18Розгортання однією командою — justfile
22/22Автоматизовані тести
11/11Конфігурація лінтера / форматера
11/11Статична перевірка типів — plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed
10/10Відтворюване середовище — Dockerfile, lockfile
10/10Підтверджена практика роботи з агентами — 15 з останніх 100 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Використані вхідні дані
has_nixні
has_testsтак
lockfilesuv.lock
has_dockerfileтак
typed_languageні
bootstrap_filesjustfile
has_devcontainerні
has_linter_configтак
typecheck_configsplugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed
agent_commit_share0,15
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
27/45Типізований код — Python з конфігурацією перевірки типів (plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed)
55/55Керовані розміри файлів — 0/65 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languagePython
largest_source_bytes30 523
source_files_sampled65
oversized_source_files0
Як обчислюється оцінка
0/40Схема API (OpenAPI/GraphQL/proto)
0/20Сервер MCP
40/40Придатні до запуску приклади — examples
Використані вхідні дані
example_dirsexamples
has_mcp_signalні
api_schema_files

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

15зірок GitHub
1контриб'юторів
226комітів за останні 12 місяців
31днів від останнього пушу
51релізів
1бас-фактор
11відкритих issue
PyPIпакетних екосистем

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

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

Докладніше

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

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
н/дCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
10Contributorsproject has 3 contributing companies or organizations -- score normalized to 10
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained17 commit(s) and 6 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
0SASTno SAST tool detected
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
0Vulnerabilities79 existing vulnerabilities detected
Прямі залежності 5
РеєстрПакетОбмеження версіїМаніфест
PyPIcappa>=0.31pyproject.toml
PyPImsgspec>=0.20pyproject.toml
PyPIpython-dotenv>=1.2.1pyproject.toml
PyPIrich>=14.3.1pyproject.toml
PyPIssh2-python>=1.2.0.post1pyproject.toml
Усі залежності 174

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

РеєстрПакетВерсіяЗв'язок
PyPIcappa0.25.1пряма
PyPIcappa0.31.0пряма
PyPImsgspec0.18.6пряма
PyPImsgspec0.20.0пряма
PyPIpython-dotenvпряма
PyPIpython-dotenv1.0.1пряма
PyPIpython-dotenv1.2.2пряма
PyPIrich13.9.4пряма
PyPIrich14.3.3пряма
PyPIssh2-python1.2.0.post1пряма
PyPIalabaster1.0.0непряма
PyPIannotated-types0.7.0непряма
PyPIanyio4.12.1непряма
PyPIanyio4.6.2.post1непряма
PyPIasgiref3.11.0непряма
PyPIasgiref3.11.1непряма
PyPIasgiref3.8.1непряма
PyPIastroid3.3.11непряма
PyPIastroid3.3.5непряма
PyPIbabel2.16.0непряма
PyPIbabel2.18.0непряма
PyPIbcrypt4.2.1непряма
PyPIbookstore0.1.2непряма
PyPIbracex2.5.post1непряма
PyPIbump-my-version0.28.1непряма
PyPIcertifi2024.8.30непряма
PyPIcertifi2026.2.25непряма
PyPIcffi1.17.1непряма
PyPIcharset-normalizer3.4.0непряма
PyPIcharset-normalizer3.4.6непряма
PyPIclick8.1.7непряма
PyPIclick8.3.1непряма
PyPIcolorama0.4.6непряма
PyPIcryptography43.0.3непряма
PyPIdecorator5.1.1непряма
PyPIdeprecated1.2.15непряма
PyPIdjangoнепряма
PyPIdjango5.1.3непряма
PyPIdjango5.2.12непряма
PyPIdjango6.0непряма
PyPIdjango6.0.3непряма
PyPIdjango-stubs-ext5.1.1непряма
PyPIdjango-stubs-ext6.0.1непряма
PyPIdjango-tasksнепряма
PyPIdjango-tasks0.10.0непряма
PyPIdjango-tasks0.12.0непряма
PyPIdocutils0.21.2непряма
PyPIdocutils0.22.4непряма
PyPIexceptiongroup1.2.2непряма
PyPIexceptiongroup1.3.1непряма
PyPIfabric3.2.2непряма
PyPIfaker33.0.0непряма
PyPIfastapi0.115.5непряма
PyPIfujin-cliнепряма
PyPIfujin-cli0.27.0непряма
PyPIfujin-secrets-1password0.26.1непряма
PyPIfujin-secrets-bitwarden0.26.1непряма
PyPIfujin-secrets-doppler0.26.1непряма
PyPIfujin-secrets-env0.26.1непряма
PyPIgevent24.11.1непряма
PyPIgit-cliff2.7.0непряма
PyPIgreenlet3.1.1непряма
PyPIgunicornнепряма
PyPIgunicorn23.0.0непряма
PyPIgunicorn25.1.0непряма
PyPIh110.14.0непряма
PyPIh110.16.0непряма
PyPIhttpcore1.0.7непряма
PyPIhttpx0.27.2непряма
PyPIidna3.10непряма
PyPIidna3.11непряма
PyPIimagesize1.4.1непряма
PyPIimagesize2.0.0непряма
PyPIiniconfig2.3.0непряма
PyPIinvoke2.2.0непряма
PyPIjinja23.1.4непряма
PyPIjinja23.1.6непряма
PyPIlitestar2.13.0непряма
PyPIlitestar-htmx0.3.0непряма
PyPImarkdown-it-py3.0.0непряма
PyPImarkdown-it-py4.0.0непряма
PyPImarkupsafe3.0.2непряма
PyPImarkupsafe3.0.3непряма
PyPImdit-py-plugins0.4.2непряма
PyPImdit-py-plugins0.5.0непряма
PyPImdurl0.1.2непряма
PyPImultidict6.1.0непряма
PyPImyst-parser4.0.0непряма
PyPImyst-parser4.0.1непряма
PyPImyst-parser5.0.0непряма
PyPIpackaging24.1непряма
PyPIpackaging24.2непряма
PyPIpackaging26.0непряма
PyPIparamiko3.5.0непряма
PyPIpluggy1.6.0непряма
PyPIpolyfactory2.18.0непряма
PyPIprompt-toolkit3.0.48непряма
PyPIpsutil6.1.0непряма
PyPIpycparser2.22непряма
PyPIpydantic2.10.1непряма
PyPIpydantic-core2.27.1непряма
PyPIpydantic-settings2.6.1непряма
PyPIpygments2.18.0непряма
PyPIpygments2.19.2непряма
PyPIpygments-styles0.3.0непряма
PyPIpynacl1.5.0непряма
PyPIpytest9.0.2непряма
PyPIpython-dateutil2.9.0.post0непряма
PyPIpyyaml6.0.2непряма
PyPIpyyaml6.0.3непряма
PyPIquestionary1.10.0непряма
PyPIrequests2.32.3непряма
PyPIrequests2.32.5непряма
PyPIrich-click1.8.4непряма
PyPIroman-numerals4.1.0непряма
PyPIsetuptools75.6.0непряма
PyPIsetuptools82.0.1непряма
PyPIshibuya2024.10.15непряма
PyPIshibuya2026.1.9непряма
PyPIsix1.16.0непряма
PyPIsniffio1.3.1непряма
PyPIsnowballstemmer2.2.0непряма
PyPIsnowballstemmer3.0.1непряма
PyPIsphinx8.1.3непряма
PyPIsphinx9.0.4непряма
PyPIsphinx9.1.0непряма
PyPIsphinx-autobuild2024.10.3непряма
PyPIsphinx-autobuild2025.8.25непряма
PyPIsphinx-autodoc20.5.0непряма
PyPIsphinx-copybutton0.5.2непряма
PyPIsphinx-design0.6.1непряма
PyPIsphinx-design0.7.0непряма
PyPIsphinx-exec-code0.14непряма
PyPIsphinx-exec-code0.18непряма
PyPIsphinx-togglebutton0.3.2непряма
PyPIsphinx-togglebutton0.4.4непряма
PyPIsphinxcontrib-applehelp2.0.0непряма
PyPIsphinxcontrib-devhelp2.0.0непряма
PyPIsphinxcontrib-htmlhelp2.1.0непряма
PyPIsphinxcontrib-jsmath1.0.1непряма
PyPIsphinxcontrib-qthelp2.0.0непряма
PyPIsphinxcontrib-serializinghtml2.0.0непряма
PyPIsqlparse0.5.1непряма
PyPIsqlparse0.5.2непряма
PyPIsqlparse0.5.5непряма
PyPIstarlette0.41.3непряма
PyPIstarlette0.52.1непряма
PyPItomli2.1.0непряма
PyPItomli2.4.0непряма
PyPItomli-w1.1.0непряма
PyPItomli-w1.2.0непряма
PyPItomlkit0.13.2непряма
PyPItype-lens0.2.3непряма
PyPItype-lens0.2.6непряма
PyPItyping-extensions4.12.2непряма
PyPItyping-extensions4.15.0непряма
PyPItzdata2024.2непряма
PyPItzdata2025.3непряма
PyPIurllib32.2.3непряма
PyPIurllib32.6.3непряма
PyPIuv-buildнепряма
PyPIuvicorn0.32.1непряма
PyPIuvicorn0.42.0непряма
PyPIwatchfiles0.24.0непряма
PyPIwatchfiles1.1.1непряма
PyPIwcmatch10.0непряма
PyPIwcwidth0.2.13непряма
PyPIwebsockets14.1непряма
PyPIwebsockets16.0непряма
PyPIwheel0.45.1непряма
PyPIwheel0.46.3непряма
PyPIwrapt1.17.0непряма
PyPIzope-event5.0непряма
PyPIzope-interface7.1.1непряма
Сповіщення про залежності 0

Встановлення pypi:fujin-cli@0.27.1 тягне 11 пакетів, прямих і транзитивних: 0 мають відомі сповіщення, з них 0 — прямі залежності.

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

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

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [
        "deployment",
        "django",
        "fastapi",
        "litestar",
        "python-p"
      ],
      "is_fork": false,
      "size_kb": 27082,
      "has_wiki": true,
      "homepage": "https://fujin.oluwatobi.dev/en/latest/",
      "languages": {
        "Just": 6912,
        "Python": 417967,
        "Dockerfile": 2223
      },
      "pushed_at": "2026-06-25T21:00:02Z",
      "created_at": "2024-10-13T07:06:29Z",
      "owner_type": "User",
      "updated_at": "2026-06-25T16:10:22Z",
      "description": "Get your project up and running in minutes on your vps.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "oluwatobi.dev",
      "name": "Tobi",
      "type": "User",
      "login": "Tobi-De",
      "company": null,
      "location": "Other World - Snake Way",
      "followers": 167,
      "avatar_url": "https://avatars.githubusercontent.com/u/40334729?v=4",
      "created_at": "2018-06-17T10:49:42Z",
      "is_verified": null,
      "public_repos": 151,
      "account_age_days": 2962
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.27.1",
          "kind": "patch",
          "published_at": "2026-06-25T16:13:31Z"
        },
        {
          "tag": "v0.27.0",
          "kind": "minor",
          "published_at": "2026-06-13T10:24:25Z"
        },
        {
          "tag": "v0.26.1",
          "kind": "patch",
          "published_at": "2026-06-09T17:01:12Z"
        },
        {
          "tag": "v0.26.0",
          "kind": "minor",
          "published_at": "2026-06-05T10:45:31Z"
        },
        {
          "tag": "v0.25.2",
          "kind": "patch",
          "published_at": "2026-03-31T14:08:01Z"
        },
        {
          "tag": "v0.25.1",
          "kind": "patch",
          "published_at": "2026-03-21T17:34:47Z"
        },
        {
          "tag": "v0.25.0",
          "kind": "minor",
          "published_at": "2026-03-21T16:18:57Z"
        },
        {
          "tag": "v0.24.0",
          "kind": "minor",
          "published_at": "2026-03-21T08:53:06Z"
        },
        {
          "tag": "v0.23.0",
          "kind": "minor",
          "published_at": "2026-03-21T08:05:05Z"
        },
        {
          "tag": "v0.22.2",
          "kind": "patch",
          "published_at": "2026-03-21T07:27:02Z"
        },
        {
          "tag": "v0.22.1",
          "kind": "patch",
          "published_at": "2026-03-21T06:19:16Z"
        },
        {
          "tag": "v0.22.0",
          "kind": "minor",
          "published_at": "2026-03-20T10:22:56Z"
        },
        {
          "tag": "v0.21.4",
          "kind": "patch",
          "published_at": "2026-02-14T07:28:11Z"
        },
        {
          "tag": "v0.21.3",
          "kind": "patch",
          "published_at": "2026-02-12T17:31:41Z"
        },
        {
          "tag": "v0.21.2",
          "kind": "patch",
          "published_at": "2026-02-08T07:46:37Z"
        },
        {
          "tag": "v0.21.1",
          "kind": "patch",
          "published_at": "2026-02-08T07:24:32Z"
        },
        {
          "tag": "v0.21.0",
          "kind": "minor",
          "published_at": "2026-02-06T05:37:09Z"
        },
        {
          "tag": "v0.20.9",
          "kind": "patch",
          "published_at": "2026-02-03T06:43:11Z"
        },
        {
          "tag": "v0.20.8",
          "kind": "patch",
          "published_at": "2026-02-03T06:31:46Z"
        },
        {
          "tag": "v0.20.7",
          "kind": "patch",
          "published_at": "2026-02-03T06:03:12Z"
        },
        {
          "tag": "v0.20.6",
          "kind": "patch",
          "published_at": "2026-02-03T05:30:50Z"
        },
        {
          "tag": "v0.20.5",
          "kind": "patch",
          "published_at": "2026-02-01T17:12:43Z"
        },
        {
          "tag": "v0.20.4",
          "kind": "patch",
          "published_at": "2026-02-01T09:25:22Z"
        },
        {
          "tag": "v0.20.3",
          "kind": "patch",
          "published_at": "2026-02-01T08:41:38Z"
        },
        {
          "tag": "v0.20.2",
          "kind": "patch",
          "published_at": "2026-02-01T07:29:06Z"
        },
        {
          "tag": "v0.20.1",
          "kind": "patch",
          "published_at": "2026-01-31T16:38:03Z"
        },
        {
          "tag": "v0.20.0",
          "kind": "minor",
          "published_at": "2026-01-31T16:02:45Z"
        },
        {
          "tag": "v0.19.5",
          "kind": "patch",
          "published_at": "2026-01-25T11:43:21Z"
        },
        {
          "tag": "v0.19.4",
          "kind": "patch",
          "published_at": "2026-01-24T12:41:02Z"
        },
        {
          "tag": "v0.19.3",
          "kind": "patch",
          "published_at": "2026-01-22T15:21:08Z"
        },
        {
          "tag": "v0.19.2",
          "kind": "patch",
          "published_at": "2026-01-22T11:08:27Z"
        },
        {
          "tag": "v0.19.1",
          "kind": "patch",
          "published_at": "2026-01-21T22:47:08Z"
        },
        {
          "tag": "v0.19.0",
          "kind": "minor",
          "published_at": "2026-01-20T21:53:43Z"
        },
        {
          "tag": "v0.18.0",
          "kind": "minor",
          "published_at": "2026-01-18T14:33:46Z"
        },
        {
          "tag": "v0.17.2",
          "kind": "patch",
          "published_at": "2026-01-11T16:51:00Z"
        },
        {
          "tag": "v0.17.1",
          "kind": "patch",
          "published_at": "2026-01-10T17:40:50Z"
        },
        {
          "tag": "v0.17.0",
          "kind": "minor",
          "published_at": "2026-01-09T17:45:09Z"
        },
        {
          "tag": "v0.16.0",
          "kind": "minor",
          "published_at": "2025-12-28T21:47:52Z"
        },
        {
          "tag": "v0.14.1",
          "kind": "patch",
          "published_at": "2025-12-08T20:09:04Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2025-12-08T18:55:47Z"
        },
        {
          "tag": "v0.13.2",
          "kind": "patch",
          "published_at": "2025-11-29T10:37:49Z"
        },
        {
          "tag": "v0.13.1",
          "kind": "patch",
          "published_at": "2025-11-28T08:33:32Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2025-11-27T23:03:37Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2025-03-08T21:48:01Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2024-11-24T18:09:32Z"
        },
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2024-11-23T10:47:00Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2024-11-23T09:19:00Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2024-11-23T07:38:23Z"
        },
        {
          "tag": "v0.7.1",
          "kind": "patch",
          "published_at": "2024-11-23T07:02:06Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2024-11-22T18:01:52Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2024-11-19T17:45:17Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "461b12d8bed851cc936b6ae50e2e40ff9571fce0",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.27.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-25T16:10:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6dd69046cb68b6d5259a75501c10a5de2a557ef3",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.27.0 → 0.27.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-25T16:10:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a600456685b81817de90eeb4e09f248df69d4d0",
          "body": null,
          "is_bot": false,
          "headline": "perf: simplify installer",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-25T16:10:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7530549e4304dd63d5eef9de7c5123dc0c88506",
          "body": null,
          "is_bot": false,
          "headline": "perf: improve ssh connection handling",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-25T15:32:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "05aef68e6be92eb564e16052fd4cdacdeb6ae9bc",
          "body": null,
          "is_bot": false,
          "headline": "fix: remove falco profile from test parametrization",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-13T10:30:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f004ff56c29b1843119d522b66adfca3a9e3b2e",
          "body": null,
          "is_bot": false,
          "headline": "chore: release v0.27.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-13T10:23:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bae1b9cc7f6dfb7fe0e0495696e29a6d23dad5ec",
          "body": null,
          "is_bot": false,
          "headline": "chore: remove falco preset from init command",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-13T10:02:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9af9d28b8ba7bea8cd02742e40a824222a025f4f",
          "body": null,
          "is_bot": false,
          "headline": "improve falco template",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-13T09:30:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "afe369b7720fd3cbbe15e1649324bac4787237b7",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.26.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-09T16:57:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "021421e5342024a20d550469f43a44353507ddac",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.26.0 → 0.26.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-09T16:57:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "219ddebe45ce8e0e78770892590465fa3283a560",
          "body": "Oneshot services have no long-running process to reload or restart — they\ncomplete and exit. Restarting them during deploy is unnecessary and can\ncause spurious failures that trigger rollbacks.\n\nAdd _get_oneshot_units() to detect Type=oneshot by reading the deployed\nservice file, and skip their serv\n[…]\nTheir timers and sockets are still enabled and restarted as usual.\n\nAlso guard against empty active_units list (all units oneshot without\ntimers/sockets) to avoid 'systemctl enable' with no arguments.",
          "is_bot": false,
          "headline": "fix(deploy): skip reload-or-restart for Type=oneshot services",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-09T16:56:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c0184bf330148caa6c71dcec59cf36891a1f01ff",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.26.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-05T10:42:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "22603a6824b0c19d83f4ddcf5e0ed6e4ec4a0645",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.25.2 → 0.26.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-05T10:40:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d39dfa3b6349eb962a0a84edb94d838dc7c020d0",
          "body": null,
          "is_bot": false,
          "headline": "cleanup",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-05T10:31:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5b8ad315f13ea1fd9386f3b1c0c1ce745d1b010c",
          "body": null,
          "is_bot": false,
          "headline": "feat: hooks system",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-05T08:04:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4263ea9666cd82be741383b7697147dd98422894",
          "body": "- prevent concurrent deployment\n- restore env file on rollback\n- verify units file before starting/enabling services",
          "is_bot": false,
          "headline": "feat: improve reliability",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-05T07:23:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58e49c3daa12b5a2e99a0a1a6bfa44657da3e209",
          "body": null,
          "is_bot": false,
          "headline": "perf: ssh and deploy units cache",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-06-05T06:48:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0e22f2fb4a43cd6997fe9babfaa66b9c0744ba69",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.25.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-31T14:04:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "adcc7d82adb01e68773f22920cf3162c5aeafca3",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.25.1 → 0.25.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-31T14:04:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0e20c54cfded16bec238684541bfce5058f07562",
          "body": null,
          "is_bot": false,
          "headline": "feat: bash function to edit source",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-31T14:04:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f8854432c589cfcb009294993fb6e8d1e15174a0",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.25.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T17:31:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7edfdb016c8da2ccb136c7764b620f83fba0521",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.25.0 → 0.25.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T17:31:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "56d7dc9192f4f2829c4b6fbdb7ca95ca089fcd66",
          "body": null,
          "is_bot": false,
          "headline": "fix: restart on env change failing for first deployment",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T17:31:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "92cee98e8369c7dfee18ac15ea787598e8956b5a",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.25.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T16:15:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "06f69eb800b0d95d14953d13d1e432eb84d0b91d",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.24.0 → 0.25.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T16:15:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ecfd79e92f2b97d5d6e87e0cbdc936ca2dffd868",
          "body": null,
          "is_bot": false,
          "headline": "feat: added restart-on-env-change deploy flag",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T16:15:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b569d288f6c3f07caf745a34fec97d64fcf4ba45",
          "body": null,
          "is_bot": false,
          "headline": "fix plugins sync script and update the env plugin version",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T09:02:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "24e530852297dcd32821e90c9d584f18572af514",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.24.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:49:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "89a56d99c48b8e0405077f2e53a6a682b064cb1d",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.23.0 → 0.24.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:49:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fbdc09a14c1cc7864025a0fb46343c12c45cb981",
          "body": "Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: add fujin-secrets-env to publish workflow",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:49:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4d5d3c761801bf9cf633974afcf8850ae9dbb91d",
          "body": "Add new environment variable adapter for CI systems like GitHub Actions.\nReads secrets from a JSON-formatted environment variable.\n\nConfiguration:\n  [secrets]\n  adapter = \"env\"\n  [secrets.options]\n  source = \"FUJIN_SECRETS\"\n\nGitHub Actions usage:\n  env:\n    FUJIN_SECRETS: ${{ toJSON(secrets) }}\n\nAls\n[…]\ntheir own config needs without modifying\nthe core fujin config schema.\n\nBREAKING: `password_env` moved to `options.password_env` for bitwarden.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add env secrets adapter and refactor adapter config",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:38:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c9263ee3ffbe42d35b05d576f7a1fedd38ccd7c5",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.23.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:01:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "87f1dbb74b1134ed13a22dd54fc5ffd2f6a6487d",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.22.2 → 0.23.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:01:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eee64c4e9f8eb3b3bff4a1eab11f175f0fe18af7",
          "body": "For security, the .env file (containing secrets) is now streamed\ndirectly to the server via base64-encoded command, rather than\nbeing included in the deployment bundle. This prevents secrets\nfrom being exposed when the bundle is preserved as an artifact.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: stream .env directly to server instead of bundling",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T08:00:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5a60e3d1b59ce3a6179056e84ddea0093c6bfdf2",
          "body": "Allows specifying a directory where the deployment bundle will be\ncreated and preserved after deploy. Useful for CI/CD workflows that\nwant to save the bundle as an artifact. The directory must not exist\n(fails if it does).\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add --bundle-dir option to preserve deployment bundle",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T07:44:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "922f06725c6d9b98f29529819719726971ecd6e7",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.22.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T07:23:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "35d852863457af9bcce6b09018dbc5b90e1bef64",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.22.1 → 0.22.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T07:23:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb83b3773d75f2e52f7d51bbcb924b28f052b4e1",
          "body": "When a group with the app name already exists (e.g., from a previous\npartial install), useradd fails silently because it tries to create\na user private group with the same name. Now checks for existing group\nand uses --no-user-group -g flags to reuse it. Also adds check=True\nto catch useradd failures.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: handle pre-existing group when creating app user",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T07:22:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "030643f0bd570299050242805223d6495b99bc66",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.22.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T06:16:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "492a22394ec936ddbcc9b4fd9f91329d2bc7ba85",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.22.0 → 0.22.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T06:16:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "954e4eb73b621e34bc18d95a1fed76c3d1e7540c",
          "body": null,
          "is_bot": false,
          "headline": "fix: use native ssh auth first when needed",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-21T06:15:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfff94700b37cc7fe725a72128cb83935685e422",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.22.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-20T10:19:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e220ae649ee689961634058d09e90d42bef9b6f",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.21.4 → 0.22.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-20T10:19:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ed0aad997af61561bf89f5f199bea9dc81240d69",
          "body": null,
          "is_bot": false,
          "headline": "feat: ssh keys management",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-20T10:19:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8597210c620c146176af7edf4815bbb7a2367a39",
          "body": null,
          "is_bot": false,
          "headline": "feat: try system ssh interactive auth if using agent fails",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-20T09:45:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c936fc6ab2e0df951e563843b4bc2755ad0e578",
          "body": null,
          "is_bot": false,
          "headline": "fix: falco templates bad config",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-03-08T06:19:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa319d39102d8989d559267c2616f7ea1f0f800d",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.21.4",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-14T07:25:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3484e5ba621dae4be2f6b991cbcd0f92ec7f421b",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.21.3 → 0.21.4",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-14T07:25:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "45bdc5f9bfa012f902e343c8c2005f88523bce65",
          "body": null,
          "is_bot": false,
          "headline": "refactor: simplify  command with positional kind argument",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-14T07:24:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93db1d40f0e4ca2941e2d9c354b9c9ce02e85d8e",
          "body": null,
          "is_bot": false,
          "headline": "feat: add caddy to www-data group for convenience",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-14T07:03:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dce1e1c686b12023da11800910766647b6d1946d",
          "body": null,
          "is_bot": false,
          "headline": "feat: improve falco templates",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-14T06:57:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c5d4bf828fa5d28d1e3e41a2cf0bcf2c89a6bc39",
          "body": "Adding and removing groups to the caddy user without\nrestart was useless,  groups are not picked up.\nThis was added to make it easier to for users to use\nsocket activation but writing good docs for this is better",
          "is_bot": false,
          "headline": "refactor: removing caddy group add",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-13T16:03:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db4212814dcdfe0b29600b20d2fcd14aeb8d3786",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.21.3",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-12T17:28:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "725d90ce605f1ed61955f720e3a8efe89256c8e6",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.21.2 → 0.21.3",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-12T17:28:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "483ceb6d5ce051b33c84c7638a06c2ec4aa31fad",
          "body": null,
          "is_bot": false,
          "headline": "fix: rsync upload was triggering on >30k instead of 30MB",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-12T17:28:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "71de328b17166d7bd5f996d40f00eb5cef4815db",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.21.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:43:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4cb134073d037c80a28326d1b22c83525fbec3c2",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.21.1 → 0.21.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:43:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c8a25b1e26b9f4c9bd441c050d8b13b6a5dab3f",
          "body": null,
          "is_bot": false,
          "headline": "feat: use verbose parameter during rollback",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:43:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c70d0bda3a7cd41da1351aa195ceb9b5e891cf1",
          "body": null,
          "is_bot": false,
          "headline": "fix: requirements hash debug logging",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:37:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ae847f502c7adb5609e2fb8be76a4cca43d3ca2",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.21.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:21:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "487810685087ff7cb0973abfe1320889632a946b",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.21.0 → 0.21.1",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:21:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "adf64ce5334e1ad4ad7446b54fc9162048a911d0",
          "body": null,
          "is_bot": false,
          "headline": "fix: fail deploy with rollback",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:21:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e58ce14230e33cd0c56462cf03dfced21914f1c",
          "body": "…single SSH call\n\nAdd --strict/-s option that exits with code 1 when no rollback targets\nare available, useful for CI/CD pipelines. Also combine the separate\n`ls .versions` and `cat .version` SSH commands into a single roundtrip.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add --strict flag to rollback and combine version queries into …",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T07:18:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a4e0cd024d8c4c488bbcacaff80b4ecc22eb8035",
          "body": "Oneshot services (e.g., migrations) transition to \"inactive\" after\nsuccessful completion, which was incorrectly treated as a failure.\nUsing systemctl is-failed correctly distinguishes between completed\noneshot services and genuinely failed units.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: use is-failed instead of is-active for post-deploy service checks",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T06:41:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7af3e108897a9610f3a06b558258dd2b7f9e7f67",
          "body": null,
          "is_bot": false,
          "headline": "feat: log requirements hash in verbose mode",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-08T06:12:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a9b028003ff6d24a8d53b6f35e66b77ef462cd3a",
          "body": null,
          "is_bot": false,
          "headline": "fix integrations tests",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-06T06:50:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7dbac96b3a3aa0fb3c3a8ce1664b04f84f822661",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.21.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-06T05:33:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4a30ff176e410bc49b25fcf4dc13af322ceb790b",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.9 → 0.21.0",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-06T05:33:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "648ed3c2aafd4a00dad5e59d86b345ac09b17c40",
          "body": null,
          "is_bot": false,
          "headline": "feat: ignore service file starting with _",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-06T05:33:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "edf9ef739f998f8045478610a84b1be03b31193c",
          "body": null,
          "is_bot": false,
          "headline": "perf: improve installation speed",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-06T05:31:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce77d831e1c795148f2f79e4117dee99a6c445b2",
          "body": null,
          "is_bot": false,
          "headline": "feat: Better logging infrastructure",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-06T05:08:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "663bc2771bde18cff644173ff235e0f342cd94af",
          "body": "Moves the failed bundle removal to a finally block so it's cleaned up\nregardless of rollback outcome. This prevents broken versions from\nappearing in future rollback prompts.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(deploy): always remove failed bundle even on Ctrl+C during rollback",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-04T01:22:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5da17bada796fcbd583e46d398ad186a64d85fc6",
          "body": "Allows disabling the automatic rollback behavior on deployment failure.\nUseful when you want to debug a failed deployment without reverting.\n\nUsage: fujin deploy --no-rollback\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(deploy): add --no-rollback flag to disable automatic rollback",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-04T00:55:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "001d43b1a88c57a00a814a4bdce19fa74cb07487",
          "body": "Allows forcing a full restart instead of reload-or-restart during\ndeployment. Uses argparse in the installer for cleaner argument parsing.\n\nUsage: fujin deploy --full-restart\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(deploy): add --full-restart flag for forced service restarts",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-04T00:49:31Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b2c997c440c41f58be330ad5b39508a6aa95697f",
          "body": "…tatus\n\nCommands now accept multiple positional arguments, e.g.:\n  fujin app restart web worker\n  fujin app logs web worker\n  fujin app status web worker\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(app): allow multiple service names for start/stop/restart/logs/s…",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-04T00:31:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6076b910754623a3068c5d4cac0ac1f7b186784d",
          "body": null,
          "is_bot": false,
          "headline": "feat: app command can now receive multiple names",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-04T00:02:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c36ae68ccedde19ce168c3e3c60bc7b5aa697651",
          "body": "Wrap SCPProtocolError with a helpful UploadError that suggests common\ncauses like missing bootstrap, permission issues, or stale group\nmembership instead of showing a cryptic traceback.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: improve SCP upload error message with actionable hints",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T23:49:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1c0d4d2aa310034a1960ac3f6f5f787e36b98470",
          "body": null,
          "is_bot": false,
          "headline": "feat: Added short name for verbose option",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T23:16:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e122503b285029e6ac799976766b88bceff46033",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.9",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T06:39:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25cec7cc97f5709b5dec92209a3af2853ce4c93b",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.8 → 0.20.9",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T06:39:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1aa62c0405885c5c2f64780ce5de4dc66da810d9",
          "body": "Expose unit names as template variables for cross-service dependencies:\n- {name}_socket for services with sockets\n- {name}_timer for services with timers\n- {name} for single-replica services without socket/timer\n\nTemplate services (replicas > 1) without socket/timer are not exposed\nsince template names aren't useful as systemd dependency targets.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(deploy): add service unit names to template context",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T06:38:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8aa01d38ba01b7bac0a5b058da276ea1a9b88109",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.7 → 0.20.8",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T06:28:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b8af51d84708e006996875f995f21641f5a3ecfe",
          "body": "Expose unit names as template variables for cross-service dependencies:\n- {name}_socket for services with sockets\n- {name}_timer for services with timers\n- {name}_service only for single-replica services without socket/timer\n\nTemplate services (replicas > 1) without socket/timer are not exposed\nsince template names aren't useful as systemd dependency targets.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(deploy): add service unit names to template context",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T06:28:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0ea4e61a2be4d9d7c12831cf6ea22ffe2d3fd047",
          "body": "Allows forcing a full restart instead of the default reload-or-restart\nbehavior. Use `fujin app restart --force` or `-f` when a graceful reload\nis not sufficient.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(app): add --force flag to restart command",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T06:19:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "befb5f0ad391b1a09bc08b6e56e0bade06b7fea8",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.7",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T05:59:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ebb67d8636c8759872ea7f349f022d1a336ff043",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.6 → 0.20.7",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T05:59:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c900df68a0753fdb8cde3282d422c041e090ff6",
          "body": null,
          "is_bot": false,
          "headline": "feat: app command run reload-or-restart",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-03T05:59:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd4c1d9f82aeae9463d5ef7f69e7402bd43ea5fb",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.6",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-02T20:57:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a40e2fd6c6910cda24e0bbd18c48657b40d029f",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.5 → 0.20.6",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-02T20:57:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c04e38dd6501fe3b7916acbf7ab0958c25896b0",
          "body": null,
          "is_bot": false,
          "headline": "feat: improve installer to work with services supporting reload",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-02T20:56:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b79576f73ddfdaf0b5ee03878ebfa49ee546c0dc",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.5",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T17:09:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fa9cfc5f73fd31b354e9b836ba05b26bf0c5796b",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.4 → 0.20.5",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T17:09:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "05b9bbae5a211d341a18310df7f9d1413e0b679f",
          "body": null,
          "is_bot": false,
          "headline": "fix: fallback from rsync to scp even in case of upoad error",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T17:09:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "91c80509742052218df9d00be78d59e7825ee37e",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.4",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T09:21:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da5354840effe04a0407aac676ae501ff7156ad8",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.3 → 0.20.4",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T09:21:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "389f5e508a559c159e698967d4ab01716518b294",
          "body": null,
          "is_bot": false,
          "headline": "fix: fallback on put when rsync unavailable",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T09:21:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "81c58fdecc70c3b8d138183bb4a58d8a324628be",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.3",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T08:38:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd139982052a6995193cd14ad10794ce8a0cb12c",
          "body": null,
          "is_bot": false,
          "headline": "Bump version: 0.20.2 → 0.20.3",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T08:38:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83642f6a9c4886471ea1cedfaec4ef54b0fe1264",
          "body": null,
          "is_bot": false,
          "headline": "fix: previous bundle corruption due to hardlink",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T08:38:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "222df615fb4b29ca4ff882c43c936076ddb69139",
          "body": null,
          "is_bot": false,
          "headline": "Generate changelog for version 0.20.2",
          "author_name": "Tobi",
          "author_login": "Tobi-De",
          "committed_at": "2026-02-01T07:25:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 51,
      "commits_last_year": 226,
      "latest_release_at": "2026-06-25T16:13:31Z",
      "latest_release_tag": "v0.27.1",
      "releases_from_tags": false,
      "days_since_last_push": 31,
      "active_weeks_last_year": 17,
      "days_since_latest_release": 31,
      "mean_days_between_releases": 10.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "fujin-cli",
          "exists": true,
          "license": null,
          "keywords": [
            "caddy",
            "deployment",
            "django",
            "fastapi",
            "litestar",
            "python",
            "systemd",
            "Development Status :: 3 - Alpha",
            "Intended Audience :: Developers",
            "Natural Language :: English",
            "Programming Language :: Python",
            "Programming Language :: Python :: 3 :: Only",
            "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 :: Implementation :: CPython",
            "Programming Language :: Python :: Implementation :: PyPy"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/fujin-cli/",
          "is_deprecated": false,
          "latest_version": "0.27.1",
          "repository_url": "https://github.com/Tobi-De/fujin",
          "versions_count": 61,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2024-10-13T06:49:11.255167Z",
          "latest_published_at": "2026-06-25T16:13:36.836033Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 31
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 15,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 12
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "justfile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed",
        "plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed",
        "plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 30523,
      "source_files_sampled": 65,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 15112
    },
    "dependencies": {
      "manifests": [
        "docs/requirements.txt",
        "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": 11,
        "malicious_count": 0,
        "assessed_package": "pypi:fujin-cli@0.27.1",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "cappa",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.31"
        },
        {
          "name": "msgspec",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.20"
        },
        {
          "name": "python-dotenv",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.2.1"
        },
        {
          "name": "rich",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=14.3.1"
        },
        {
          "name": "ssh2-python",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.2.0.post1"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "cappa",
            "direct": true,
            "version": "0.25.1",
            "ecosystem": "pypi"
          },
          {
            "name": "cappa",
            "direct": true,
            "version": "0.31.0",
            "ecosystem": "pypi"
          },
          {
            "name": "msgspec",
            "direct": true,
            "version": "0.18.6",
            "ecosystem": "pypi"
          },
          {
            "name": "msgspec",
            "direct": true,
            "version": "0.20.0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dotenv",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "python-dotenv",
            "direct": true,
            "version": "1.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dotenv",
            "direct": true,
            "version": "1.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "rich",
            "direct": true,
            "version": "13.9.4",
            "ecosystem": "pypi"
          },
          {
            "name": "rich",
            "direct": true,
            "version": "14.3.3",
            "ecosystem": "pypi"
          },
          {
            "name": "ssh2-python",
            "direct": true,
            "version": "1.2.0.post1",
            "ecosystem": "pypi"
          },
          {
            "name": "alabaster",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "annotated-types",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "anyio",
            "direct": false,
            "version": "4.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "anyio",
            "direct": false,
            "version": "4.6.2.post1",
            "ecosystem": "pypi"
          },
          {
            "name": "asgiref",
            "direct": false,
            "version": "3.11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "asgiref",
            "direct": false,
            "version": "3.11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "asgiref",
            "direct": false,
            "version": "3.8.1",
            "ecosystem": "pypi"
          },
          {
            "name": "astroid",
            "direct": false,
            "version": "3.3.11",
            "ecosystem": "pypi"
          },
          {
            "name": "astroid",
            "direct": false,
            "version": "3.3.5",
            "ecosystem": "pypi"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "bcrypt",
            "direct": false,
            "version": "4.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "bookstore",
            "direct": false,
            "version": "0.1.2",
            "ecosystem": "pypi"
          },
          {
            "name": "bracex",
            "direct": false,
            "version": "2.5.post1",
            "ecosystem": "pypi"
          },
          {
            "name": "bump-my-version",
            "direct": false,
            "version": "0.28.1",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2024.8.30",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2026.2.25",
            "ecosystem": "pypi"
          },
          {
            "name": "cffi",
            "direct": false,
            "version": "1.17.1",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "click",
            "direct": false,
            "version": "8.1.7",
            "ecosystem": "pypi"
          },
          {
            "name": "click",
            "direct": false,
            "version": "8.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "cryptography",
            "direct": false,
            "version": "43.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "decorator",
            "direct": false,
            "version": "5.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "deprecated",
            "direct": false,
            "version": "1.2.15",
            "ecosystem": "pypi"
          },
          {
            "name": "django",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "django",
            "direct": false,
            "version": "5.1.3",
            "ecosystem": "pypi"
          },
          {
            "name": "django",
            "direct": false,
            "version": "5.2.12",
            "ecosystem": "pypi"
          },
          {
            "name": "django",
            "direct": false,
            "version": "6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "django",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "django-stubs-ext",
            "direct": false,
            "version": "5.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "django-stubs-ext",
            "direct": false,
            "version": "6.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "django-tasks",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "django-tasks",
            "direct": false,
            "version": "0.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "django-tasks",
            "direct": false,
            "version": "0.12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "docutils",
            "direct": false,
            "version": "0.21.2",
            "ecosystem": "pypi"
          },
          {
            "name": "docutils",
            "direct": false,
            "version": "0.22.4",
            "ecosystem": "pypi"
          },
          {
            "name": "exceptiongroup",
            "direct": false,
            "version": "1.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "exceptiongroup",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fabric",
            "direct": false,
            "version": "3.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "faker",
            "direct": false,
            "version": "33.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "fastapi",
            "direct": false,
            "version": "0.115.5",
            "ecosystem": "pypi"
          },
          {
            "name": "fujin-cli",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "fujin-cli",
            "direct": false,
            "version": "0.27.0",
            "ecosystem": "pypi"
          },
          {
            "name": "fujin-secrets-1password",
            "direct": false,
            "version": "0.26.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fujin-secrets-bitwarden",
            "direct": false,
            "version": "0.26.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fujin-secrets-doppler",
            "direct": false,
            "version": "0.26.1",
            "ecosystem": "pypi"
          },
          {
            "name": "fujin-secrets-env",
            "direct": false,
            "version": "0.26.1",
            "ecosystem": "pypi"
          },
          {
            "name": "gevent",
            "direct": false,
            "version": "24.11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "git-cliff",
            "direct": false,
            "version": "2.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "greenlet",
            "direct": false,
            "version": "3.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "gunicorn",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "gunicorn",
            "direct": false,
            "version": "23.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "gunicorn",
            "direct": false,
            "version": "25.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "h11",
            "direct": false,
            "version": "0.14.0",
            "ecosystem": "pypi"
          },
          {
            "name": "h11",
            "direct": false,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "httpcore",
            "direct": false,
            "version": "1.0.7",
            "ecosystem": "pypi"
          },
          {
            "name": "httpx",
            "direct": false,
            "version": "0.27.2",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.10",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.11",
            "ecosystem": "pypi"
          },
          {
            "name": "imagesize",
            "direct": false,
            "version": "1.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "imagesize",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "iniconfig",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "invoke",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": false,
            "version": "3.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": false,
            "version": "3.1.6",
            "ecosystem": "pypi"
          },
          {
            "name": "litestar",
            "direct": false,
            "version": "2.13.0",
            "ecosystem": "pypi"
          },
          {
            "name": "litestar-htmx",
            "direct": false,
            "version": "0.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown-it-py",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown-it-py",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "mdit-py-plugins",
            "direct": false,
            "version": "0.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mdit-py-plugins",
            "direct": false,
            "version": "0.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mdurl",
            "direct": false,
            "version": "0.1.2",
            "ecosystem": "pypi"
          },
          {
            "name": "multidict",
            "direct": false,
            "version": "6.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "myst-parser",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "myst-parser",
            "direct": false,
            "version": "4.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "myst-parser",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "24.1",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "24.2",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "26.0",
            "ecosystem": "pypi"
          },
          {
            "name": "paramiko",
            "direct": false,
            "version": "3.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pluggy",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "polyfactory",
            "direct": false,
            "version": "2.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "prompt-toolkit",
            "direct": false,
            "version": "3.0.48",
            "ecosystem": "pypi"
          },
          {
            "name": "psutil",
            "direct": false,
            "version": "6.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pycparser",
            "direct": false,
            "version": "2.22",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic",
            "direct": false,
            "version": "2.10.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic-core",
            "direct": false,
            "version": "2.27.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic-settings",
            "direct": false,
            "version": "2.6.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.19.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments-styles",
            "direct": false,
            "version": "0.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pynacl",
            "direct": false,
            "version": "1.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "9.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dateutil",
            "direct": false,
            "version": "2.9.0.post0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "questionary",
            "direct": false,
            "version": "1.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": false,
            "version": "2.32.3",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": false,
            "version": "2.32.5",
            "ecosystem": "pypi"
          },
          {
            "name": "rich-click",
            "direct": false,
            "version": "1.8.4",
            "ecosystem": "pypi"
          },
          {
            "name": "roman-numerals",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": "75.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": "82.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "shibuya",
            "direct": false,
            "version": "2024.10.15",
            "ecosystem": "pypi"
          },
          {
            "name": "shibuya",
            "direct": false,
            "version": "2026.1.9",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sniffio",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "snowballstemmer",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "snowballstemmer",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx",
            "direct": false,
            "version": "8.1.3",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx",
            "direct": false,
            "version": "9.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx",
            "direct": false,
            "version": "9.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-autobuild",
            "direct": false,
            "version": "2024.10.3",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-autobuild",
            "direct": false,
            "version": "2025.8.25",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-autodoc2",
            "direct": false,
            "version": "0.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-copybutton",
            "direct": false,
            "version": "0.5.2",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-design",
            "direct": false,
            "version": "0.6.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-design",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-exec-code",
            "direct": false,
            "version": "0.14",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-exec-code",
            "direct": false,
            "version": "0.18",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-togglebutton",
            "direct": false,
            "version": "0.3.2",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-togglebutton",
            "direct": false,
            "version": "0.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-applehelp",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-devhelp",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-htmlhelp",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-jsmath",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-qthelp",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-serializinghtml",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sqlparse",
            "direct": false,
            "version": "0.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sqlparse",
            "direct": false,
            "version": "0.5.2",
            "ecosystem": "pypi"
          },
          {
            "name": "sqlparse",
            "direct": false,
            "version": "0.5.5",
            "ecosystem": "pypi"
          },
          {
            "name": "starlette",
            "direct": false,
            "version": "0.41.3",
            "ecosystem": "pypi"
          },
          {
            "name": "starlette",
            "direct": false,
            "version": "0.52.1",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli",
            "direct": false,
            "version": "2.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli-w",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli-w",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomlkit",
            "direct": false,
            "version": "0.13.2",
            "ecosystem": "pypi"
          },
          {
            "name": "type-lens",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "type-lens",
            "direct": false,
            "version": "0.2.6",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.12.2",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tzdata",
            "direct": false,
            "version": "2024.2",
            "ecosystem": "pypi"
          },
          {
            "name": "tzdata",
            "direct": false,
            "version": "2025.3",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "uv-build",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "uvicorn",
            "direct": false,
            "version": "0.32.1",
            "ecosystem": "pypi"
          },
          {
            "name": "uvicorn",
            "direct": false,
            "version": "0.42.0",
            "ecosystem": "pypi"
          },
          {
            "name": "watchfiles",
            "direct": false,
            "version": "0.24.0",
            "ecosystem": "pypi"
          },
          {
            "name": "watchfiles",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "wcmatch",
            "direct": false,
            "version": "10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "wcwidth",
            "direct": false,
            "version": "0.2.13",
            "ecosystem": "pypi"
          },
          {
            "name": "websockets",
            "direct": false,
            "version": "14.1",
            "ecosystem": "pypi"
          },
          {
            "name": "websockets",
            "direct": false,
            "version": "16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "wheel",
            "direct": false,
            "version": "0.45.1",
            "ecosystem": "pypi"
          },
          {
            "name": "wheel",
            "direct": false,
            "version": "0.46.3",
            "ecosystem": "pypi"
          },
          {
            "name": "wrapt",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "zope-event",
            "direct": false,
            "version": "5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "zope-interface",
            "direct": false,
            "version": "7.1.1",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 174,
        "direct_count": 10,
        "indirect_count": 164
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 1,
        "merged_prs": 9,
        "open_issues": 11,
        "closed_ratio": 0.814,
        "closed_issues": 48,
        "closed_unmerged_prs": 6
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "Tobi-De",
          "commits": 379,
          "avatar_url": "https://avatars.githubusercontent.com/u/40334729?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "publish.yml",
        "test.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": true
    },
    "security_signals": {
      "lockfiles": [
        "uv.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": null,
            "reason": "no pull request found",
            "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": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 3 contributing companies or organizations -- score normalized to 10",
            "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": 0,
            "reason": "no 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": "17 commit(s) and 6 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": "no SAST tool detected",
            "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": "79 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "461b12d8bed851cc936b6ae50e2e40ff9571fce0",
        "ran_at": "2026-07-27T15:10:50Z",
        "aggregate_score": 3.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-06-25T16:11:12Z",
      "oldest_open_prs": [
        {
          "number": 72,
          "created_at": "2026-06-26T06:02:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-01-18T14:29:59Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 46,
          "created_at": "2025-12-24T11:55:16Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 51,
          "created_at": "2025-12-25T14:30:24Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 59,
          "created_at": "2026-01-26T08:58:03Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 63,
          "created_at": "2026-01-30T07:03:58Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 64,
          "created_at": "2026-02-03T08:49:06Z",
          "last_comment_at": "2026-02-14T06:30:16Z",
          "last_comment_author": "Tobi-De"
        },
        {
          "number": 67,
          "created_at": "2026-02-03T23:37:24Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 69,
          "created_at": "2026-06-09T15:41:52Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 71,
          "created_at": "2026-06-14T13:00:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 73,
          "created_at": "2026-06-30T09:10:12Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 74,
          "created_at": "2026-06-30T09:27:30Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 75,
          "created_at": "2026-07-11T13:10:39Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/Tobi-De/fujin",
    "host": "github.com",
    "name": "fujin",
    "owner": "Tobi-De"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": "The weighted overall 62 is calibrated to 69 on the published index scale (record calibration 2026-08-02).",
      "notes": [
        {
          "code": "overall_calibration",
          "params": {
            "raw": 62,
            "calibrated": 69,
            "calibration": "2026-08-02"
          }
        }
      ],
      "value": 69,
      "inputs": {
        "security": 47,
        "vitality": 71,
        "community": 33,
        "governance": 57,
        "calibration": "2026-08-02",
        "engineering": 95,
        "ai_readiness": 73,
        "weighted_overall_raw": 62
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 71,
        "weight": 0.21,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "commits_last_year": 226,
              "human_commit_share": 1,
              "days_since_last_push": 31,
              "active_weeks_last_year": 17
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 31 days ago",
                "points": 18,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 31
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "17/52 weeks with commits",
                "points": 11.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 17
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "226 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 226
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "17 commit(s) and 6 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": 51,
              "latest_release_tag": "v0.27.1",
              "releases_from_tags": false,
              "days_since_latest_release": 31,
              "mean_days_between_releases": 10.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "51 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 51
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 31 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 31
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~10.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 10.7
                    }
                  }
                ],
                "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": "exceptional",
            "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": 38,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 38 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 38
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 33,
        "weight": 0.17,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 19,
            "inputs": {
              "forks": 0,
              "stars": 15,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "15 stars",
                "points": 18.6,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 15
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "readme_badges": null,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "readme_badge_services": [],
              "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 (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": "moderate",
        "name": "Sustainability & Governance",
        "value": 57,
        "weight": 0.23,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 3 contributing companies or organizations -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "newcomer_pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "merged_prs": 9,
              "open_issues": 11,
              "closed_issues": 48,
              "prs_merged_7d": null,
              "prs_decided_7d": null,
              "prs_merged_30d": null,
              "prs_decided_30d": null,
              "issue_closed_ratio": 0.814,
              "closed_unmerged_prs": 6,
              "first_time_authors_30d": null,
              "first_time_prs_merged_30d": null,
              "first_time_prs_decided_30d": null
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "81% of issues closed",
                "points": 34.2,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 81
                    }
                  }
                ],
                "max_points": 42
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "9/15 decided PRs merged",
                "points": 18,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 9,
                      "decided": 15
                    }
                  }
                ],
                "max_points": 30
              },
              {
                "key": "newcomer_pr_acceptance",
                "name": "Newcomer PR acceptance",
                "detail": "no first-time contributor's PR decided in 30d",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_newcomer_prs",
                    "params": {
                      "days": 30
                    }
                  }
                ],
                "max_points": 13
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 64,
            "inputs": {
              "followers": 167,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "Tobi-De",
              "public_repos": 151,
              "account_age_days": 2962
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "167 followers of Tobi-De",
                "points": 16,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 167,
                      "login": "Tobi-De"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "151 public repos, account ~8 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 151
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 8
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "exceptional",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "fujin-cli"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 31
            },
            "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 31 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 31
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "61 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 61
                    }
                  }
                ],
                "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": "exceptional",
        "name": "Engineering Quality",
        "value": 95,
        "weight": 0.19,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "excellent",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 92,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": true
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": null,
                "points": 16,
                "status": "met",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 9.6,
                "status": "met",
                "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "exceptional",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "topics": [
                "deployment",
                "django",
                "fastapi",
                "litestar",
                "python-p"
              ],
              "has_wiki": true,
              "homepage": "https://fujin.oluwatobi.dev/en/latest/",
              "has_readme": true,
              "has_docs_dir": true,
              "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": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://fujin.oluwatobi.dev/en/latest/",
                "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": "5 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "weak",
        "name": "Security",
        "value": 47,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 34,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 3.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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 3 contributing companies or organizations -- score normalized to 10",
                "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": "no update tool detected",
                "points": 0,
                "status": "missed",
                "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": "17 commit(s) and 6 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": "no SAST tool detected",
                "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": "79 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "exceptional",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the pypi:fujin-cli@0.27.1 runtime dependency closure — what installing the published package pulls in — 11 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:fujin-cli@0.27.1",
                  "assessed": 11
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 11,
              "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": "exceptional",
            "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": 11,
              "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": "exceptional",
            "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"
              ],
              "commit_weight_rule": {
                "min_commits": 50,
                "min_commit_share": 0.1
              },
              "review_only_matches": 0,
              "below_threshold_exposures": [],
              "assessed_self_published_locations": 3
            },
            "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": "good",
        "name": "AI Readiness",
        "value": 73,
        "weight": 0.04,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "good",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.5,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 15112
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.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": "50 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 26.7,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 50,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "excellent",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [
                "justfile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed",
                "plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed",
                "plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed"
              ],
              "agent_commit_share": 0.15,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "justfile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "justfile"
                    }
                  }
                ],
                "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": null,
                "points": 11,
                "status": "met",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed"
                    }
                  }
                ],
                "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": "15 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 15,
                      "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": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 30523,
              "source_files_sampled": 65,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "plugins/fujin-secrets-1password/src/fujin_secrets_1password/py.typed, plugins/fujin-secrets-bitwarden/src/fujin_secrets_bitwarden/py.typed, plugins/fujin-secrets-doppler/src/fujin_secrets_doppler/py.typed",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/65 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 65,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "weak",
            "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? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
      }
    ],
    "classification": {
      "labels": [
        "library"
      ],
      "scores": {
        "library": 6
      },
      "primary": "library",
      "evidence": [
        {
          "tier": "distribution",
          "label": "library",
          "source": "registry:pypi",
          "weight": 6
        }
      ],
      "artifacts": [],
      "confidence": "medium",
      "host_extension": false,
      "runs_as_process": false,
      "consumed_by_code": true
    },
    "metrics_version": "2.3.1"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T15:11:07.124030Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/t/Tobi-De/fujin.svg",
  "full_name": "Tobi-De/fujin",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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