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

EvanBacon / serve-sim

The `npx serve` of Apple Simulators.

TypeScript · Objective-CApache-2.0★ 2 563 зірки⑂ 132 форкиз квіт. 2026 р.Переглянути на GitHub ↗

EvanBacon/serve-sim має індекс здоров’я 57 зі 100, що відповідає смузі «Помірний». Найвищий показник — Community & Adoption (72/100), найнижчий — Vitality (38/100). Останнє оновлення було 5 днів тому. Більшість нещодавньої роботи виконує один учасник.

57
загалом / 100
Помірний

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

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

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

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

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

Власність

Evan BaconОсобистий обліковий запис
6 181 підписник343 публічні репозиторіїз лист. 2014 р.

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

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

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

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

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

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

38У зоні ризику · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 5 дн. тому
9/36Ритм комітів — 13/52 тижнів із комітами
18/18Обсяг комітів — 158 комітів за останній рік
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Використані вхідні дані
commits_last_year158
human_commit_share0,86
days_since_last_push5
active_weeks_last_year13
Як обчислюється оцінка
0/27Випускає релізи — релізів не опубліковано
0/36Свіжість релізів — релізів немає
0/27Ритм релізів — релізів немає
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count0
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

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

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

72Добрий · 18% загального індексу
Як обчислюється оцінка
55.3/60Зірки — 2 563 зірок
17.6/25Форки — 132 форків
5.3/15Спостерігачі — 10 спостерігачів
Використані вхідні дані
forks132
stars2 563
watchers10
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (Apache-2.0)
0/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
has_contributingні
has_issue_templateні
has_code_of_conductні
has_pull_request_templateні
Як обчислюється оцінка
74.1/80Щомісячні завантаження — 359 392 завантажень/місяць у npm
0/20Залежні пакети в реєстрі — ця екосистема цього не повідомляє
Використані вхідні дані
packagesserve-sim
dependents
ecosystemsnpm
total_downloads
monthly_downloads359 392
Виключено з оцінювання (немає даних або не застосовно): Залежні пакети в реєстрі. Залишкові ваги перенормовано.

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

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

65Помірний · 24% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
5.7/22.5Розподіл комітів — головний контриб’ютор — автор 75% комітів
13.5/13.5Широта контриб’юторів — 23 контриб’юторів
10/10OpenSSF Scorecard: Contributors — project has 6 contributing companies or organizations
Використані вхідні дані
bus_factor1
contributors_sampled23
top_contributor_share0,746
Як обчислюється оцінка
21.4/46.8Вирішення issue — закрито 46% issue
33.7/38.3Прийняття PR — злито 82/93 вирішених PR
4.5/15OpenSSF Scorecard: Code-Review — Found 11/30 approved changesets -- score normalized to 3
Використані вхідні дані
merged_prs82
open_issues13
closed_issues11
issue_closed_ratio0,458
closed_unmerged_prs11
Як обчислюється оцінка
10/30Підтримка власника — особистий (користувацький) обліковий запис
0/20Верифікований домен — не застосовно до користувацьких облікових записів
25/25Охоплення власника — 6 181 підписників у EvanBacon
25/25Послужний список — 343 публічних репозиторіїв, вік облікового запису ~11 р.
Використані вхідні дані
followers6 181
owner_typeUser
is_verified
owner_loginEvanBacon
public_repos343
account_age_days4 272
Виключено з оцінювання (немає даних або не застосовно): Верифікований домен. Залишкові ваги перенормовано.

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

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 1 пакет(ів) у npm
35/35Свіжість публікацій — остання публікація 5 дн. тому
20/20Історія версій — 81 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packagesserve-sim
ecosystemsnpm
any_deprecatedні
min_days_since_publish5

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

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

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

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

50Помірний
Як обчислюється оцінка
30/30README
0/25Каталог документації
0/15Сайт документації / домашня сторінка
10/10Опис репозиторію
10/10Теми — 3 тем
0/10Wiki
Використані вхідні дані
topicsagent, headless, ios
has_wikiні
homepage
has_readmeтак
has_docs_dirні
has_descriptionтак

Безпека

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

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

Стан безпеки

44У зоні ризику
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — немає даних
2/2.5CI-Tests — 23 out of 26 merged PRs checked by a CI test -- score normalized to 8
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
2.2/7.5Code-Review — Found 11/30 approved changesets -- score normalized to 3
2.5/2.5Contributors — project has 6 contributing companies or organizations
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
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — немає даних
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate4,4
Виключено з оцінювання (немає даних або не застосовно): branch_protection, signed_releases. Залишкові ваги перенормовано.
Як обчислюється оцінка
35/35Прямі залежності без відомих сповіщень — жодна пряма залежність не має відомих сповіщень
0/25Непрямі залежності без відомих сповіщень — транзитивний набір не відокремлюється від залежностей розробки й тестування в цьому обсязі
0/40Немає задавнених сповіщень — жодне сповіщення не має дати публікації
Використані вхідні дані
sourceosv
advisories0
affected_packages0
assessed_packages2
unassessed_packages20
affected_by_severitynone
direct_affected_packages0
Виключено з оцінювання (немає даних або не застосовно): Непрямі залежності без відомих сповіщень, Немає задавнених сповіщень. Залишкові ваги перенормовано. Звірено 2 резолвлених залежностей із OSV. 20 не вдалося оцінити — немає резолвленої версії, непідтримувана екосистема або поза межами звітованого переліку пакетів. Цей репозиторій не публікує пакета, який резолвить індекс, тож натомість оцінено граф залежностей репозиторію. Цей граф змішує закріплені версії для розробки й тестування зі справді постачаними залежностями, тож оцінюються лише задекларовані runtime-залежності; транзитивні знахідки подаються як контекст і в оцінку не входять. Досяжність не аналізується.

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

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

68Помірний · 0% загального індексу
Як обчислюється оцінка
45/45Інструкції для агентів — AGENTS.md, CLAUDE.md
0/15Машиночитана документація (llms.txt)
40/40Читабельна історія комітів — намір зазначено у 74 з 86 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share0,86
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes3 433
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
0/11Конфігурація лінтера / форматера
11/11Статична перевірка типів — tsconfig.json
0/10Відтворюване середовище
10/10Підтверджена практика роботи з агентами — 33 з останніх 100 комітів створено агентом або з його зазначенням
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Використані вхідні дані
has_nixні
has_testsтак
lockfiles
has_dockerfileні
typed_languageтак
bootstrap_files
has_devcontainerні
has_linter_configні
typecheck_configstsconfig.json
agent_commit_share0,33
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
45/45Типізований код — TypeScript (статично типізована)
54.1/55Керовані розміри файлів — 3/193 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languageTypeScript
largest_source_bytes80 589
source_files_sampled193
oversized_source_files3

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

2 563зірок GitHub
23контриб'юторів
158комітів за останні 12 місяців
5днів від останнього пушу
0релізів
1бас-фактор
13відкритих issue
npmпакетних екосистем

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

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • deps.dev does not index npm:serve-sim@0.1.45; advisories assessed against the repository dependency graph instead

Докладніше

Історія зірок і форків 0 ★ / 132 ⇿
0Зірки
132Форки

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

0255075100125150131102026-042026-062026-07
OpenSSF Scorecard 4.4 / 10
4.4сукупно

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

10Binary-Artifactsno binaries found in the repo
н/дBranch-Protectioninternal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
8CI-Tests23 out of 26 merged PRs checked by a CI test -- score normalized to 8
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
3Code-ReviewFound 11/30 approved changesets -- score normalized to 3
10Contributorsproject has 6 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
н/дSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Прямі залежності 3
РеєстрПакетОбмеження версіїМаніфест
npminspect-webkit^0.0.5packages/serve-sim/package.json
npmsonner^2.0.7packages/serve-sim/package.json
npmws^8.21.0packages/serve-sim/package.json
Усі залежності 22

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

РеєстрПакетВерсіяЗв'язок
npminspect-webkit^0.0.5пряма
npmsonner^2.0.7пряма
npmws^8.21.0пряма
npm@types/bunlatestнепряма
npm@types/debug^4.1.13непряма
npm@types/node^25.6.2непряма
npm@types/react^19.0.0непряма
npm@types/react-dom^19.0.0непряма
npm@types/ws^8.18.1непряма
npmbun-plugin-tailwind^0.1.2непряма
npmcommander^14.0.1непряма
npmdebug^4.4.3непряма
npmknip^6.12.2непряма
npmlucide-react^1.20.0непряма
npmnode-swift1.5.1непряма
npmoxlint^1.63.0непряма
npmpreact^10.29.1непряма
npmreact^19.0.0непряма
npmreact-dom^19.0.0непряма
npmtailwindcss^4.1.7непряма
npmtypescript^5.7.0непряма
npmtypescript^6.0.3непряма
Сповіщення про залежності 0

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

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

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

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [
        "agent",
        "headless",
        "ios"
      ],
      "is_fork": false,
      "size_kb": 8239,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "C": 3603,
        "CSS": 3497,
        "Shell": 6715,
        "Swift": 107117,
        "JavaScript": 76274,
        "TypeScript": 1002167,
        "Objective-C": 164464
      },
      "pushed_at": "2026-07-17T19:29:51Z",
      "created_at": "2026-04-29T20:23:12Z",
      "owner_type": "User",
      "updated_at": "2026-07-23T13:46:37Z",
      "description": "The `npx serve` of Apple Simulators.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript",
        "Objective-C"
      ]
    },
    "owner": {
      "blog": "http://evanbacon.dev/",
      "name": "Evan Bacon",
      "type": "User",
      "login": "EvanBacon",
      "company": null,
      "location": "San Francisco",
      "followers": 6181,
      "avatar_url": "https://avatars.githubusercontent.com/u/9664363?v=4",
      "created_at": "2014-11-10T22:01:21Z",
      "is_verified": null,
      "public_repos": 343,
      "account_age_days": 4272
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [],
      "recent_commits": [
        {
          "oid": "14ad57ff922551bf7be81e907ddfcfa6191e64f2",
          "body": "Improve reliability around simulator helper teardown and type-command e2e assertions. The camera helper now unlinks shared memory before stopping capture sources so a teardown crash can’t leave stale shm names behind. HID debug logging now flushes stdout per line to make redirected logs immediately \n[…]\nauses: shm probe now fails fast on non-zero helper exit with stderr context, and type-command e2e now polls for expected key log lines (with detailed error output) instead of relying on a fixed sleep.",
          "is_bot": false,
          "headline": "Harden helper shutdown and HID log timing",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-07-17T19:29:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7f109fb027fc2aacda53c02a11cbebb7937964c5",
          "body": "Resolving bun-version 'latest' in oven-sh/setup-bun hits GitHub's\ngit/refs/tags API, which returns 503 during GitHub incidents and\nfails the workflow before it starts (e.g. the latest 'Publish stable\nto npm' run). Pinning an exact version downloads straight from the\nrelease URL and skips that API call.\n\n\nClaude-Session: https://claude.ai/code/session_01Tu1ttHMJoJhj5DytTiUzVj\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: pin bun version via .bun-version file (#133)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-07-16T23:35:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8e0cdd9d46b0202cb99c9ee03d8649bd991815ac",
          "body": "* feat: add preview startup state flags\n\n* feat: add simulator theme launch option\n\n* fix: honor preview launch state\n\n* fix: keep initial fit render-pure",
          "is_bot": false,
          "headline": "feat: add preview launch configuration (#129)",
          "author_name": "Guillaume Sabran",
          "author_login": "gsabran",
          "committed_at": "2026-07-16T20:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8206925f3e6747236714d781ef2b6244c7a36f5",
          "body": "* fix(serve-sim): send plain R to reload RN/Expo bundle\n\nExpo Go and the dev-client register the reload key command as a plain\n\"R\" (not Cmd+R), so sending the Cmd modifier prevented the reload from\nfiring. Send just the R key instead.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.\n[…]\nre React Native too, not just Expo Go/dev-client.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): send plain R to reload RN/Expo bundle (#126)",
          "author_name": "Krystof Woldrich",
          "author_login": "krystofwoldrich",
          "committed_at": "2026-07-14T16:09:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1ae0787aa159c9e8d37dda4fd3251d4a9ee4321d",
          "body": "* Avoid subprocess polling for camera status\n\n* Tighten camera helper status implementation",
          "is_bot": false,
          "headline": "Avoid subprocess polling for camera status (#131)",
          "author_name": "Stanisław Chmiela",
          "author_login": "sjchmiela",
          "committed_at": "2026-07-14T16:06:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af681b8c3b0453f31dcb8e98a3389f23b7cfc6b0",
          "body": "* Add simulator event log\n\n* Tighten event log behavior\n\n* Clean up event log noise\n\n* Simplify drag event labels\n\n* Polish tap and key event labels\n\n* Humanize event log CLI output\n\n* Show simulator names in event log CLI\n\n* Use semantic drag event action\n\n* Add msg field to event log entries\n\n* Use normalized coordinates in event log CLI\n\n* Address event log review feedback\n\n* Keep drag log updates server-side\n\n* Avoid raw exec details in event log",
          "is_bot": false,
          "headline": "feat: add event log (#124)",
          "author_name": "Szymon Dziedzic",
          "author_login": "szdziedzic",
          "committed_at": "2026-07-08T16:41:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd545ed70d369683a0367ee82de9bd98ce697417",
          "body": null,
          "is_bot": false,
          "headline": "Maybe fix size feedback loop (#119)",
          "author_name": "Kabir Oberai",
          "author_login": "kabiroberai",
          "committed_at": "2026-07-01T07:01:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a757690411b3da11aa5ddc1ad770ad0cd8b6d698",
          "body": null,
          "is_bot": false,
          "headline": "Performance improvements (#117)",
          "author_name": "Kabir Oberai",
          "author_login": "kabiroberai",
          "committed_at": "2026-07-01T06:56:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e419a8776ba2c9515be8a40d98fea8bcd560af5",
          "body": "Shutting a simulator down from the UI close button SIGTERMed the server's own pid. In in-process mode inProcessServeSimState records process.pid, so the stale-helper reaper on the next grid poll signalled itself, and index.ts converts SIGTERM into process.exit.\n\nSplit the reap decision into classify\n[…]\ntead of killed, while genuine separate helper processes are still SIGTERMed. The shutdown handler now closes the in-process session up front, and the --list/--detach path guards against self-kill too.",
          "is_bot": false,
          "headline": "fix(serve-sim): stop close button from killing the whole server (#122)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-30T17:25:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f94d57c3f05031d93538660fc0d232179b1d8a50",
          "body": null,
          "is_bot": false,
          "headline": "ci: serialize serve-sim e2e tests",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-26T01:05:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e7014f6925914da72de3b7d3bece4b97b6c4d4c",
          "body": null,
          "is_bot": false,
          "headline": "test: close shm probe mmap handles",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-26T00:52:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95722163419c3e143d79ee6a4e8038d02f161c33",
          "body": null,
          "is_bot": false,
          "headline": "Update publish-stable.yml",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-26T00:32:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1cfe9900d654fc05acbaa0b68d7d7a259d9d8fb9",
          "body": "The publish-beta job runs the sim-backed e2e suite but, unlike the\nsim-test.yml PR check, had no retry. A transient simulator wedge (stuck\nfinger from a malformed-HID frame, mid-stream native crash) cascades\nConnectionRefused / \"server not alive\" failures into later tests and\nfailed the whole publis\n[…]\n5 and #116.\n\nMirror sim-test.yml: reboot the shared simulator and retry the suite\nonce. A transient wedge clears; a real regression reproduces.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add sim reboot-and-retry to publish workflow tests (#118)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-25T18:24:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1cd3cb78ed018966b4569ff5b87077e9982dcdac",
          "body": null,
          "is_bot": false,
          "headline": "Fix swiftbuild native build (#116)",
          "author_name": "Kabir Oberai",
          "author_login": "kabiroberai",
          "committed_at": "2026-06-25T16:11:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a70b1bca675f7e1620a85af4b36fcc95b61b60a",
          "body": "…(#115)\n\n* Add MJPEG frame parser and integrate into hook\n\nIntroduce a new incremental MJPEG parser (createMjpegFrameParser) with an amortised growable buffer and in-place compaction to avoid O(bytes²) reallocations and GC churn. The parser reads multipart headers (Content-Length) and falls back to \n[…]\netry. Bump the job timeout 15→25m to leave\nheadroom for the second attempt.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add MJPEG frame parser and optimize Avcc buffer with grid pagination …",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-23T20:57:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d46a621c8c68b17aab3f28249ef4d1cbe2f9109f",
          "body": null,
          "is_bot": false,
          "headline": "Fix publish workflows after client package removal (#114)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-23T00:56:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5c5e73e76f2e5adcdcec3e4edd76a0b5c33e9f04",
          "body": "* refactor: fold serve-sim-client UI components into serve-sim package\n\nMove the simulator UI components, avcc-codec, and types that were only\nused internally by serve-sim out of the separate serve-sim-client package\nand into serve-sim/src/client/. Delete the serve-sim-client package entirely.\n\n- Mo\n[…]\nore: update lockfile after removing serve-sim-client\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>\n\n* Update bun.lock\n\n---------\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "refactor: fold serve-sim-client UI components into serve-sim (#112)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-22T23:36:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0a94b923946abe28e5660891f7498dce6ea71d41",
          "body": "The README advertises `/plugin marketplace add EvanBacon/serve-sim`, but the\nrepo ships no `.claude-plugin/marketplace.json`, so that command currently\nfails. This adds a self-referential marketplace and plugin manifest that\nexposes the existing `skills/serve-sim` Agent Skill, making the advertised\n\n[…]\nlidated with `claude plugin validate --strict`; `marketplace add` plus\n`install serve-sim@serve-sim` succeed and `plugin details` shows the skill.\n\nCo-authored-by: CypherPoet <CypherPoet@tutanota.com>",
          "is_bot": false,
          "headline": "feat: add Claude Code plugin marketplace manifest (#84)",
          "author_name": "CypherPoet",
          "author_login": "CypherPoet",
          "committed_at": "2026-06-22T23:33:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9851f45f2adf00231177bc88fe1e3c827281e6a0",
          "body": null,
          "is_bot": false,
          "headline": "Tweak native build a bit (#111)",
          "author_name": "Kabir Oberai",
          "author_login": "kabiroberai",
          "committed_at": "2026-06-22T23:29:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab5dd5af19b938f6bb553c51f6c1af9d7e394a25",
          "body": "…rver (#110)\n\n* fix: guard in-process HID calls so malformed input can't crash the server\n\nSince the napi migration (#108) HID injection runs in-process. The N-API\nbinding throws synchronously when a JS value can't be coerced to its native\nparameter type (e.g. a touch frame whose `type` is missing →\n[…]\ned server with that env set\n(it propagates to the re-exec'd `serve` child).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: guard in-process HID calls so malformed input can't crash the se…",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-22T07:33:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a55ce8e16ea4148251a282d0a4fb08daeddc513c",
          "body": "The serve-sim e2e tests load the in-process N-API addon\n(dist/native/serve-sim-native.node). After the napi migration there is no\ncommitted helper binary, so the publish workflows must build the addon before\nrunning the tests — otherwise the native-dependent tests (AVCC, accessibility,\ntype, idle-fr\n[…]\nblish-stable.yml. The\nexisting post-version-bump `bun run build` in the publish step is kept so the\npublished bundle embeds the bumped version.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "CI: build serve-sim native addon before publish e2e tests (#109)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-22T05:35:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6fb5867145c463f78a652a492e75f979a3692f98",
          "body": "* Add in-process N-API addon MVP (serve-sim-native.node)\n\nProves the toolchain for folding the spawned serve-sim-bin helper into a\nsingle in-process native addon. Sources/SimNative builds a fat arm64+x86_64\n.node via swiftc+lipo (clang++ for the Objective-C++ N-API glue), using\nnode-api-headers only\n[…]\nthe product dir varies by toolchain (native SwiftPM vs Xcode build system).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: Migrate to napi (#108)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-22T05:20:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "55bb294260095ae7bc6287fa0934f2b527d75f52",
          "body": "* Polish serve-sim UI chrome and toasts\n\n* fix(serve-sim): restore translucent resize badge backdrop\n\nThe shared --color-panel-bg became opaque, so the resize badge's\nbackdrop-blur rendered behind a solid fill and the frosted-glass look\nwas lost. Add a translucent variant of the shared panel color and use\nit for the badge so the blur shows through again.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "[codex] Polish serve-sim UI chrome and toasts (#106)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-21T23:44:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ff86df5e32d8f334074525c5e7fdbcb5f5ff763c",
          "body": "* test(serve-sim): de-flake shm-shutdown and location-permission sim tests\n\nTwo integration tests race eventually-consistent system state on loaded CI\nrunners and have been intermittently failing sim-test/publish across PRs:\n\n- shm-probe \"shutdown unmaps shm\": the helper shm_unlink()s during shutdow\n[…]\nut\". Match the beforeAll's generous budget\nso teardown can't gate sim-test.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "De-flake shm-shutdown and location-permission sim tests (#107)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-21T23:44:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b8f1c47be3168439931d00a05caf281c84b73ede",
          "body": "* added cmd+k shortcut to toggle the on-screen software keyboard, matching the ios simulator (instant, via the same hid button it uses; doesn't touch hardware-keyboard state)\n\n* add instant cmd+k software keyboard toggle for the simulator",
          "is_bot": false,
          "headline": "Adds software keyboard toggle support (CMD + K) (#104)",
          "author_name": "traf",
          "author_login": "traf",
          "committed_at": "2026-06-21T22:39:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d93d45ea6b1d47bd323df5b91d9484a80f73634b",
          "body": "Route the helper stream/control + WebKit DevTools sockets through the preview\nserver's same-origin proxy so remote viewers only need one port, and add\nserver-side stream codec control.\n\n- `--codec <auto|h264|mjpeg>` pins the preview stream codec (forces MJPEG on\n  hosts that can't encode H.264, e.g.\n[…]\nps/wss;\n  closes the internal server if the front server fails to bind.\n- Node LTS-only support documented; engines bumped to >=20.\n\nCo-authored-by: Kabir Oberai <kabiroberai@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Support single-port proxying with codec control (#91)",
          "author_name": "Kabir Oberai",
          "author_login": "kabiroberai",
          "committed_at": "2026-06-21T18:02:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9c38ca1d389b4e9d6f829d29b58c49e8e8292fce",
          "body": "* fix(serve-sim): add stream codec control with auto-downgrade on decoder error\n\n* refactor(serve-sim): reuse SettingRow/SettingSelect in stream tool\n\n* docs(serve-sim): document StreamSettingsTool component",
          "is_bot": false,
          "headline": "Add stream codec control with auto-downgrade on decoder error (#101)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-20T06:46:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd41254c8d9d512bea9a818ca4b7c143b38bf199",
          "body": "…#100)\n\n* Add DeviceKit chrome and HID hardware buttons\n\nIntroduce full DeviceKit chrome support and arbitrary HID button injection.\n\n- Add a DeviceKit chrome React component (device-chrome-frame.tsx) used by both the placeholder and live stream, rendering bezel, screen cutout, and interactive hardw\n[…]\n watch cap z-order into the chrome descriptor (data-driven onTop)\n- Key the crown wheel listener on presence not identity to avoid per-frame churn\n- Drop dead screenClipRadius branch and unused import",
          "is_bot": false,
          "headline": "Add DeviceKit chrome frame with hardware buttons around live stream (…",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-20T05:39:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ddef1039fad5dc28f3087a162337359804b5c2bf",
          "body": "* add ios 27 home events\n\n* wip\n\n* Emulate scroll as cursor-anchored touch drags\n\nAdd cursor anchor to scroll events and switch to touch-drag emulation for scrolling. The ScrollEventPayload now optionally carries normalized x/y anchor, the client and SimulatorView send the anchor (rotated into raw d\n[…]\ndrag approach was chosen. Update main to pass anchors to HID injection.\n\n* refactor(serve-sim): dedup scroll drag begin into a helper\n\n* fix(serve-sim): serialize all HID sends through one input queue",
          "is_bot": false,
          "headline": "iOS 27 home gesture and cursor-anchored scroll input (#99)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-20T00:18:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "94ce87acf9d8843651094c4e5b0bc42630ab16ce",
          "body": "* Add generated watch PNGs in tmp/pdfs\n\nAdd four generated PNG assets under tmp/pdfs: watch-se3-40.png and three watch2-pieces images (WatchTL-130.png, WatchTL-poppler.png, WatchTL.png). These appear to be derived image outputs (thumbnails/pieces) from PDF processing and are placed in the temporary/\n[…]\nnds and skip a\nplaceholder case when its asset isn't present on the runner.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add rich asset support for placeholders (#97)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-19T06:01:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fcccef64eb86b60904bf88f38d639dc8ad1b753b",
          "body": null,
          "is_bot": false,
          "headline": "fix(serve-sim): gate simulator settings panel to ios simulators (#96)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-18T01:02:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3c0fb89457420f59c8cb3fc6ec6172084e9f1e5d",
          "body": "Remove the simctl logs SSE endpoint and associated client/server plumbing (dev.ts, middleware, client, types, tests, and docs).\n\nUpdate StreamFormat.swift",
          "is_bot": false,
          "headline": "Remove simctl log SSE; optimize MJPEG & AVCC (#95)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-18T00:46:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23c4b1105cf3ea9610c8434366b8837753ad55c2",
          "body": "* rework devices to be a unified side bar\n\n* Prefer MJPEG for UI-started devices\n\nTrack devices started from the UI (uiStarted) and avoid the H.264/AVCC path for those devices so streams fall back to MJPEG immediately when helpers may not serve /stream.avcc. Re-subscribe the stream SSE when the sele\n[…]\nrabber and a gradient hairline, moving transitions into classes. Delete the corresponding unit test that validated the resisted grabber motion.\n\n* fix(serve-sim): memoize deltaFor in useResizableWidth",
          "is_bot": false,
          "headline": "serve-sim: unified devices sidebar & UI refactor (#94)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-17T23:58:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb16f5cb25360a72b2f1d1edb9ab25e8677fcd42",
          "body": "* fix(serve-sim): support Xcode 27 (SimulatorKit relocation)\n\nXcode 27 moved SimulatorKit.framework from Contents/Developer/Library/\nPrivateFrameworks to Contents/SharedFrameworks, breaking the @rpath load\nof the helper binary.\n\nCoreSimulator/SimulatorKit are only used via the Objective-C runtime, s\n[…]\naunch\nfailure, return the fallback Developer dir.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: support Xcode 27 (SimulatorKit relocation) (#90)",
          "author_name": "Krystof Woldrich",
          "author_login": "krystofwoldrich",
          "committed_at": "2026-06-15T18:31:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "20fe0987591a8dad8f56d016096b87e24b9f8bc7",
          "body": null,
          "is_bot": false,
          "headline": "clean up screenshot thumbnail dragging (#88)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-12T19:31:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc18ce20a848e6d63d30d83242191f3a2624dd9d",
          "body": "Native <select> option popups are drawn by the host browser and ignore\nthe page color scheme in embedded webviews (Codex, VS Code), rendering\na broken white list over the dark panel. Replace the settings and trail\nselects with a custom listbox in the device-picker dropdown style,\nportaled to <body> since the tools panel scrolls and sections clip\noverflow. Also declare color-scheme: dark for remaining UA chrome.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): replace native select popups with in-page dropdown",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-12T01:19:44Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5cd81d648c79c422a630d53cc23b51e5b7134ff6",
          "body": null,
          "is_bot": false,
          "headline": "Use custom select to fix styling in codex",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-12T01:14:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee573a6881629f898a086a54c2e1eb50fc3ad4ba",
          "body": "The middleware injects a minimal {basePath, execToken} __SIM_PREVIEW__ when\nno helper is attached so the empty state can authenticate /exec. The client\ntreated any truthy config as a full stream config, mounting SimulatorView\nwith url undefined: the page fetched /undefined/stream.avcc and, whenever\n\n[…]\nr goes away instead of deleting the global, and guard\nuseAvccStream against an empty url so it can never fetch a relative\nundefined/stream.avcc.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): don't treat the device-less preview config as a stream",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-12T00:34:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f0c65f71a5e657969fee9d94325c1e270a1fcd7d",
          "body": "killPortHolder used `lsof -ti tcp:<port>`, which lists every process with\nany socket on the port — including *clients*. A browser tab still streaming\nfrom a previous helper holds client sockets to the helper port, so every\nfresh serve-sim startup SIGKILLed the browser's network process. The new\nprev\n[…]\nts.ts, scope the lsof query\nto -sTCP:LISTEN, and add a regression test that a connected client's pid\nis never returned alongside the listener's.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): only kill port listeners, not connected clients",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-12T00:22:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3fa15cc2e1b8ce9c706aebe05e1aedc9956712c8",
          "body": "Bun's bundler inlines a bare CommonJS __dirname as a string constant —\nthe build machine's source directory — so published bundles searched\n/Users/runner/work/... for the sim-ax-settings helper and failed with\n\"binary not found\" on every other machine, even though the binary\nshipped in the tarball. \n[…]\nndex.ts already does for the camera artifacts, and add a bundle\nportability test asserting no build-machine path is baked into the\ndist bundles.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): resolve sim-ax-settings path at runtime, not build time",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-11T23:19:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0ebc0b1ec442732aec688ff1fe614595ee16a489",
          "body": "…tos (#87)\n\n* add version flag\n\n* add screenshots and update icons\n\n* update toast\n\n* update state\n\n* Update SimulatorToolbar.tsx\n\n* Support host-path drops to add media to Photos\n\nAdd a custom drag flavor (DROP_HOST_PATH_TYPE) and addHostMediaToPhotos helper so screenshots/media that already live o\n[…]\nre command\n- AxTreeStatus is a polite live region with a decorative spinner\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add screenshot button with save popup, Finder reveal, and drag-to-Pho…",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-11T23:04:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a069c68a1f5428f30cb0a33d3c7009737d9031eb",
          "body": "* Add simulator-wide UI settings CLI and UI panel\n\nIntroduce an in-simulator CLI and frontend tooling for managing simulator-wide UI options.\n\nAdds sim-ax-settings (Objective‑C) and a build.sh to produce a fat simulator binary that reads/writes private Accessibility/MediaAccessibility/UIKit preferen\n[…]\nsimulator planes;\nSERVE_SIM_UI_E2E=1 forces the suite on for capable runners.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add simulator-wide settings sidebar with WebSocket control channel (#86)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-11T21:06:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7327ab3d189795b8137eba78be20412c0d87344b",
          "body": "Reverts the universal arm64+x86_64 build introduced in #80. x86_64\nsupport did not work, so the helper ships as arm64-only again and the\nlimitation is documented in the README.",
          "is_bot": false,
          "headline": "revert(serve-sim): drop intel mac universal binary support (#85)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-09T19:32:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cd1a816b33a160e69d426ae9d433024121c4da4f",
          "body": null,
          "is_bot": false,
          "headline": "Update publish-stable.yml",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-08T00:22:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0d98f69f3ec932ea10903fd7c8b32647949606d",
          "body": null,
          "is_bot": false,
          "headline": "test: relax lipo binary assertion timeout",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T05:25:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "71f5d246917fd0eb7dee2aae3df1ff2cce27c9a5",
          "body": null,
          "is_bot": false,
          "headline": "ci: publish beta for client changes",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T05:16:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "69e2bb04ebf1f2d58c5cf81da3781070f38fcfd8",
          "body": null,
          "is_bot": false,
          "headline": "Update SimulatorView.tsx",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T04:38:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0cb1a2faf23cf59538f5de41db26d6b10b0970c",
          "body": null,
          "is_bot": false,
          "headline": "drop fill animation",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T04:31:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d8509bbe4281e084b744f4535a093ac210ee9eb",
          "body": "* Share camera frames via IOSurface ring\n\n* Fix IOSurface probe test types\n\n* Apply IOSurface review fixes",
          "is_bot": false,
          "headline": "Share camera frames via IOSurface ring (#81)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T04:09:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "842cf6065603b9b9b344b4a8f543af842d88a72d",
          "body": "* Add AVCC (H.264) streaming support\n\nIntroduce AVCC (length-prefixed H.264) streaming and client-side decode via WebCodecs with MJPEG fallback. Client changes: add avcc-codec parser, useAvccStream hook, tests, and wire in a codec prop to SimulatorStream/SimulatorView to render an AVCC stream into a\n[…]\n the encoder warms.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n\n* Apply AVCC review feedback\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add AVCC (H.264) streaming support (#78)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T04:04:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9ad340a6e9c1d528ce38880183223adccbd3ef77",
          "body": null,
          "is_bot": false,
          "headline": "ci: publish beta by default",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-06-05T03:36:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "911fef3a2e0f22fb97fef9ee5071b117e1fc6abb",
          "body": "* added support for intel macs\n\n* Fix typecheck: import test globals from bun:test\n\nThe new serve-sim-bin test used describe/test/expect without importing\nthem, breaking the typecheck CI job (TS2593/TS2304). Match the rest of\nthe suite by importing from \"bun:test\".\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Evan Bacon <baconbrix@gmail.com>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add support for Intel Macs (#80)",
          "author_name": "Tristan",
          "author_login": "longtimeno-c",
          "committed_at": "2026-06-05T02:38:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9149ec816bc0e1e0fc979bc6dd8367329e001f13",
          "body": "* Improve simulated camera connection compatibility\n\n* Refresh attached output inputs on reconfiguration",
          "is_bot": false,
          "headline": "[codex] Improve simulated camera connection compatibility (#77)",
          "author_name": "Marc Rousavy",
          "author_login": "mrousavy",
          "committed_at": "2026-06-01T19:10:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b3f718cc28c87867c5fd5825c222871e1e33e62",
          "body": "…03) (#72)\n\nThe accessibility-endpoint test intermittently fails on GitHub macOS runners\nbecause the booted simulator's AX framework never warms up — the helper stays\nalive and the /ax endpoint returns 503 for the entire readiness budget. That's\nan environment condition, not a regression in the tree\n[…]\nak\non a non-503/non-200 response) is still a hard failure, and a real 200 response\nstill asserts the bounded-tree shape as before.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Soft-pass AX e2e test when sim AX framework never warms (persistent 5…",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-21T21:10:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6d1d8eb02d6277c3cb6bdba0f4e00da23176dd0c",
          "body": "* Fix viewDidAppear: swizzle clobbering all view controllers\n\nUIImagePickerController no longer overrides viewDidAppear: on iOS 26, so\nclass_getInstanceMethod returned the inherited UIViewController Method and\nmethod_exchangeImplementations swapped the IMP on the shared superclass.\nEvery view contro\n[…]\ns) so cold-start latency stops flaking the suite.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix viewDidAppear: swizzle clobbering all view controllers (#71)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-21T20:48:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "15df8a20dce67965a1ce482032c32ebeb487dba0",
          "body": null,
          "is_bot": false,
          "headline": "adjust swipe edge (#70)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-21T16:54:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "43db8bd95de728553c96cd9c8228f01d28a6d113",
          "body": "long description has made codex & claude code not finding the skill despite it was installed",
          "is_bot": false,
          "headline": "fix: shorten serve-sim skill description (#69)",
          "author_name": "Guy Tepper",
          "author_login": "guytepper",
          "committed_at": "2026-05-21T16:29:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "df53c2ab3c0d0ca7d0fcc5419a687395c5ca24ec",
          "body": "The helper binds on `*:<port>`, but the CLI hardcodes `127.0.0.1` in the\n`url`/`streamUrl`/`wsUrl` it writes to the state file. Those URLs are\ninjected into the preview HTML as `window.__SIM_PREVIEW__`, so a remote\nbrowser dereferences `127.0.0.1` as itself and the stream never loads.\n\nRewrite the h\n[…]\nLAN viewers can reach it directly, and\ntunnels can expose the helper port under the same hostname.\n\nLoopback callers (localhost / 127.0.0.1 / ::1) get the state untouched\nto preserve current behavior.",
          "is_bot": false,
          "headline": "Rewrite helper host to request hostname for remote viewers (#64)",
          "author_name": "Robert Herber",
          "author_login": "robertherber",
          "committed_at": "2026-05-19T15:56:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "138d70b0b490fa12fe8fc0d264b2531f9c98d1a5",
          "body": "- AX streamer cache was append-only; added prune()/dispose() and call it\n  from /ax so entries for booted-then-removed simulators are released.\n- /logs and /appstate SSE handlers accumulated stdout into an uncapped\n  line buffer; capped at 1 MB and added child error / stdio destroy on\n  client disconnect so a malformed log line or abnormal child exit can't\n  retain memory.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix memory leaks in AX streamer cache and SSE log endpoints (#66)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-19T15:54:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0c737860339044b90aad86a781479fb1ecf9e65d",
          "body": null,
          "is_bot": false,
          "headline": "Add watchOS digital crown scrolling support (#52)",
          "author_name": "Łukasz Kuczborski",
          "author_login": "lkuczborski",
          "committed_at": "2026-05-19T15:53:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0e474580551243a2a301c70885efaae74b07512",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-17T23:15:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79572ffc19621e8d9438828ead3d41afff9ceb8c",
          "body": "* feat(serve-sim): support UIImagePickerController camera injection\n\nThe AVFoundation swizzles handle AVCaptureSession-based camera flows, but\nUIImagePickerController with sourceType=.camera bypassed them and showed\nthe gray \"no signal\" placeholder on iOS 26 simulator. Hook the picker's\nown view lif\n[…]\nmatching what most \"no real editing\" apps expect.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Support UIImagePickerController camera injection (#63)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-17T23:08:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3912c01460af23956d166499d49603e848690d4c",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-17T21:43:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce007ece911c08e6ae6252541d4c78e8585edfdb",
          "body": "Update packages/serve-sim package.json to use inspect-webkit ^0.0.5 and bump the serve-sim package version to 0.1.32. bun.lock was updated to reflect the dependency and lockfile changes.",
          "is_bot": false,
          "headline": "Bump inspect-webkit and serve-sim version",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-17T21:38:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "38fd4462557aa18271cafa69b44691c9a846408c",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-15T21:40:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9155c1aba57ae728ae1312673e96d5c18a7483d0",
          "body": "* refactor(serve-sim): rewrite CLI argument parsing with commander\n\nReplace the hand-rolled switch-based argument parsing with commander.\nThe seven simple subcommands (gesture, tap, button, type, rotate,\nca-debug, memory-warning) now take structured arguments; camera and\npermissions keep their own d\n[…]\nes reset across every permission while the sim\nis still cold, and the AX helper's framework warm-up overran the 30s window.\nBump the permissions hook/test budget to 90s and the AX ready budget to 60s.",
          "is_bot": false,
          "headline": "Rewrite serve-sim CLI argument parsing with commander (#59)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-15T21:35:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b89829b06b01a5c4dcc80ee4b5adf80e0c9d2fb1",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-14T19:20:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ae2e8de821a2d7da00cf8059b6518887b5e1703",
          "body": "A slow /ax response that exceeds the per-request budget aborts the fetch,\nand the AbortError propagated uncaught instead of being treated as \"helper\nstill warming up\". Swallow AbortError and keep polling to the deadline.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): keep polling AX endpoint when a request times out",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-14T19:12:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d95363af0e84bf2bf017ec38ab62e1918ec1ba0d",
          "body": "The afterAll hook runs `serve-sim --kill`, which takes ~5.5s on CI and\nexceeded Bun's default 5s hook timeout, failing the publish job.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(serve-sim): give idle-floor afterAll hook a 30s timeout",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-14T18:55:34Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d42dee4af82dbaf0445b5b6c8f6528fc3cbe39e2",
          "body": "* add permissions commands\n\n* fix(serve-sim): use simctl privacy for location permissions\n\niOS keys locationd's clients.plist entries as `i<bundleId>:` — the\ntrailing colon is part of the key, so neither plutil (dot paths) nor\nPlistBuddy (colon paths) can address it, and a hand-written plain\nbundle-\n[…]\nve every hook and test in the suite a 30s budget.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(serve-sim): add permissions subcommand (#58)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-14T18:38:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1755f049488b7a1df4c7a5549a45292fbb6eed7a",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-14T18:13:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "452b0ed917baa101e4c0ccfe270b858df8c5b24c",
          "body": "* feat(skills): add serve-sim agent skill\n\nAdds an Agent Skill under skills/serve-sim/ that teaches AI coding\nagents (Claude Code, Cursor, Codex CLI, Gemini CLI, GitHub Copilot —\nany host implementing the open Agent Skills standard) how to drive a\nrunning Apple Simulator through the serve-sim CLI.\n\n\n[…]\nn README.\n\nNote: README.md at the repo root is a symlink to this file\n(packages/serve-sim/README.md); the relative links are written to\nresolve from the repo root, where the README is normally viewed.",
          "is_bot": false,
          "headline": "feat(skills): add serve-sim agent skill (#57)",
          "author_name": "Manuel Lopez",
          "author_login": "malopezr7",
          "committed_at": "2026-05-14T18:02:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "af9a268ccc7314654c4109940c48fdf085c0127f",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'main' of github.com:EvanBacon/serve-sim",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-14T17:24:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8b028faebe997637c71f08d50bf32e5c9991bc74",
          "body": null,
          "is_bot": false,
          "headline": "Update README.md",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-14T17:24:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7ad32fd6f559943df1769487f37a3260f523dda3",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-14T17:19:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ab9da6c914263b6d9b2f725f0bb5f8029568b21",
          "body": "* feat(serve-sim): add `type` subcommand\n\nMirrors AXe's `type`: maps US-keyboard text → HID usages and streams\nthem through the existing 0x06 WS_MSG_KEY opcode. Supports positional\ntext, --stdin, and --file inputs.\n\nIncludes a fast unit/in-process e2e (fake Bun WS server) and a real\nnative e2e that \n[…]\ndiscovery+create if none of the known names boot.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(serve-sim): add `type` subcommand (#55)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-14T17:12:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "84322fdf34f6c5a6d067d6d74dad884012fe9ebe",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-13T00:24:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "503e5d64c8046d75b2447fd719df1744d1971143",
          "body": null,
          "is_bot": false,
          "headline": "Update client.tsx",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-13T00:19:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd6c5b64506810e443f5e694f444f7e7040deafe",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'main' of github.com:EvanBacon/serve-sim",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-13T00:16:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7f3881c1ed41c8e738fa282e71a2ba7cfd8513cf",
          "body": "Refactor AppPermissionsTool layout and button styling: make the container a vertical flex with gaps, update the toggle button classes and add an explicit type=\"button\" (prevents implicit form submission), tweak label spacing and structure for consistent alignment. Also change LocationEmulationTool default state to start collapsed (open set to false) so the tool is closed by default on load.",
          "is_bot": false,
          "headline": "Adjust permissions UI and collapse location tool",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-13T00:16:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "489b6ad25ce76f2a520f4c885851ba541ff22941",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-13T00:08:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f85262404d22d3f32bfb1204e3e05755d970035a",
          "body": null,
          "is_bot": false,
          "headline": "Update index.ts",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-12T23:59:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6d0a87839fe9efe2714eb0d3c2b8a0fdea75e7dd",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-12T22:35:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "82eed293576af07dcd6c4fdfe51de239b8a56b52",
          "body": "* fix: harden simulator camera injection\n\n* fix: address camera injection review feedback\n\n* fix: tighten camera-tool state machine and full-stop teardown\n\n- Derive primary action (Play / Inject ${bundleId} / Stop) from a pure\n  `selectCameraPrimaryKind` helper so reload-mid-injection keeps Stop\n  e\n[…]\nSplit pending state into primary/aux so mirror/switch ops no longer\n  blink the Stop button.\n\nTests: +12 new pure-function cases (primary kind matrix, webcam parser,\npreview config). 80 pass / 0 fail.",
          "is_bot": false,
          "headline": "Harden simulator camera injection (#49)",
          "author_name": "Joao Paulo Costa Marra",
          "author_login": "JoaoPauloCMarra",
          "committed_at": "2026-05-12T22:28:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e536531a4c16a656d77cfa5054f558f9e2967a3a",
          "body": "Closes #9\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add Apache-2.0 LICENSE file (#51)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-12T18:57:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fa93596c75b6410643da7b7a18da297af13ba0fe",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-12T18:50:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26eb878142243931e880596d5567145e0de139fa",
          "body": "The `simMiddleware` /exec route ran arbitrary shell commands with no auth,\nno CSRF protection, and no Content-Type check. The bundled preview server\ncalled `server.listen(port)` without a host argument, so it bound to all\ninterfaces — making the unauthenticated RCE reachable from the LAN and\nfrom an\n[…]\nn't match Host.\n- Constant-time token compare; 4 MiB body cap.\n- Regression tests covering each rejection path and the happy path.\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: authenticate /exec and bind preview to loopback (#20) (#50)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-12T18:43:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7d4b8c84b1fa40f37c8d43be3a77df3877895050",
          "body": null,
          "is_bot": false,
          "headline": "docs: correct `.claude/launch.json` port config in README (#48)",
          "author_name": "Agustín Millán Jiménez",
          "author_login": "amillez",
          "committed_at": "2026-05-12T18:20:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4babbf1a0f47715a022667c3e1e95f0eeabec998",
          "body": null,
          "is_bot": false,
          "headline": "Update client.tsx",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-12T18:09:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6b972936471ccd9a972511e69855f7fc5cf83a1d",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-11T23:05:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8943780b3f4600e86eb22ef34bd9632613b7d6de",
          "body": "* Update ax-toolbar-button.tsx\n\n* Update toolbar icons and button text color\n\nReplace several inline SVG icons and standardize styles: swap the old filled RotateIcon for a stroke-based, 24x24 rotate icon; replace the inline chevron SVG in the permissions tool with the shared Chevron component; and c\n[…]\nent contrast. Modified files: packages/serve-sim-client/src/simulator/SimulatorToolbar.tsx, packages/serve-sim/src/client/client.tsx, packages/serve-sim/src/client/components/app-permissions-tool.tsx.",
          "is_bot": false,
          "headline": "fix: polish icons (#47)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-11T22:58:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d39348d581c7f2bf919b7e39f7ae4047bd98fd4b",
          "body": null,
          "is_bot": false,
          "headline": "Update accessibility-endpoint.test.ts",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-11T21:49:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a07f8844ea8511c70985108ada194229d5ef4024",
          "body": "* Add SimCameraInjector dylib & camera CLI\n\nIntroduce a simulator camera injector: an Objective-C dylib (SimCameraInjector.m) that is DYLD-inserted into simulator apps to fake AVCapture devices and stream a static image/gradient as camera frames. Add a build.sh to produce a fat dylib for the iOS sim\n[…]\nurce type to CamSourceKind so it accepts \"video\".\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add basic camera support (#46)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-11T21:34:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "49f68a6965a63ed9a2620538e059b5282c3e6e25",
          "body": "Drag the simulator frame by a curved-arc corner handle to scale it,\nwith iOS-style direct manipulation:\n\n  - Rubber-band resistance past min/max bounds\n  - Velocity-sampled release with a critically-near-damped spring tween\n  - Magnetic detent at the device's natural 1x width\n  - Sub-pixel widths ro\n[…]\nnge:hidden.\n\nAdds a shared geometry helper in serve-sim-client:\n  simulatorResizeCornerArc({ type, config, containerWidth, containerHeight })\nwhich returns the SVG arc path for the active device type.",
          "is_bot": false,
          "headline": "feat: polished simulator resize with curved arc corner handle (#45)",
          "author_name": "Joao Paulo Costa Marra",
          "author_login": "JoaoPauloCMarra",
          "committed_at": "2026-05-11T18:06:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb705eec118d1ffd592fdd51a98ee5e1694d28f2",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-10T22:47:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d9a7a462ff522bb42a0f9b05f2119b50b0ac1f92",
          "body": "…lity classes (#43)\n\n* Use PostCSS Tailwind pipeline in build script\n\n* Rename tailwind.css to global.css; update deps\n\nRename the client stylesheet (packages/serve-sim/src/client/tailwind.css → global.css) and update the build script to read the new path. Adjust the stylesheet @source reference acc\n[…]\nBuffer-as-ArrayBuffer through unknown in WS tests\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Integrate Tailwind into serve-sim build and refactor Panel to use uti…",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-10T22:41:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d4184628110122c70e828d0293b2613d84faef32",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-10T19:47:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d4d6649478d313edc82d832794e37d2bc09d2266",
          "body": "Drag/drop install toasts now indicate that work is happening:\n- determinate progress bar + percentage while the .ipa/media bytes are\n  streamed to /tmp in 256KB chunks\n- indeterminate animated bar during the simctl install/addmedia step,\n  which has no progress signal\n\nThe toast is also no longer text-selectable in non-error states; errors\nkeep selection enabled so the message can be copied.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Show install progress in drop toast and disable selection (#42)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-10T19:40:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "96d0c203b9086a3fcc62eb81b726058a54f82db5",
          "body": "Add `/foreground` route to SimStreamHelper that returns `{bundleId, pid}`\nfor the visible app via a cheap AX point-query (no tree walk), and use it\nto seed `/appstate` SSE clients. SpringBoard's foreground log feed is\nedge-triggered, so a fresh subscriber would otherwise see nothing until\nthe user r\n[…]\nst`, which works for simulator app processes\nsince their host-side path lives under the runtime container.\n\nReplaces the prior `/ax` + `simctl listapps` seed in middleware.ts with\nthe dedicated probe.",
          "is_bot": false,
          "headline": "serve-sim ax: bootstrap /appstate with frontmost-app probe (#41)",
          "author_name": "Evan Bacon",
          "author_login": "EvanBacon",
          "committed_at": "2026-05-10T19:33:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f10d11df30afdf2b6722495da3babdf56eb2a472",
          "body": null,
          "is_bot": true,
          "headline": "chore: bump serve-sim version [skip ci]",
          "author_name": "github-actions[bot]",
          "author_login": "github-actions[bot]",
          "committed_at": "2026-05-09T19:28:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 0,
      "commits_last_year": 158,
      "latest_release_at": null,
      "latest_release_tag": null,
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 13,
      "days_since_latest_release": null,
      "mean_days_between_releases": null
    },
    "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": "serve-sim",
          "exists": true,
          "license": "Apache-2.0",
          "keywords": [],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/serve-sim",
          "is_deprecated": false,
          "latest_version": "0.1.45",
          "repository_url": "https://github.com/EvanBacon/serve-sim",
          "versions_count": 81,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 359392,
          "first_published_at": "2026-04-17T18:33:15.804000Z",
          "latest_published_at": "2026-07-18T06:08:04.043000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        }
      ]
    },
    "popularity": {
      "forks": 132,
      "stars": 2563,
      "watchers": 10,
      "fork_history": {
        "days": [
          {
            "date": "2026-04-29",
            "count": 4
          },
          {
            "date": "2026-04-30",
            "count": 8
          },
          {
            "date": "2026-05-01",
            "count": 10
          },
          {
            "date": "2026-05-02",
            "count": 6
          },
          {
            "date": "2026-05-03",
            "count": 1
          },
          {
            "date": "2026-05-04",
            "count": 3
          },
          {
            "date": "2026-05-05",
            "count": 2
          },
          {
            "date": "2026-05-06",
            "count": 2
          },
          {
            "date": "2026-05-07",
            "count": 2
          },
          {
            "date": "2026-05-08",
            "count": 3
          },
          {
            "date": "2026-05-09",
            "count": 1
          },
          {
            "date": "2026-05-10",
            "count": 2
          },
          {
            "date": "2026-05-11",
            "count": 1
          },
          {
            "date": "2026-05-12",
            "count": 2
          },
          {
            "date": "2026-05-13",
            "count": 3
          },
          {
            "date": "2026-05-14",
            "count": 2
          },
          {
            "date": "2026-05-16",
            "count": 1
          },
          {
            "date": "2026-05-18",
            "count": 2
          },
          {
            "date": "2026-05-19",
            "count": 1
          },
          {
            "date": "2026-05-20",
            "count": 1
          },
          {
            "date": "2026-05-21",
            "count": 1
          },
          {
            "date": "2026-05-22",
            "count": 2
          },
          {
            "date": "2026-05-23",
            "count": 1
          },
          {
            "date": "2026-05-24",
            "count": 1
          },
          {
            "date": "2026-05-26",
            "count": 1
          },
          {
            "date": "2026-05-28",
            "count": 1
          },
          {
            "date": "2026-05-29",
            "count": 1
          },
          {
            "date": "2026-06-04",
            "count": 2
          },
          {
            "date": "2026-06-05",
            "count": 2
          },
          {
            "date": "2026-06-06",
            "count": 1
          },
          {
            "date": "2026-06-07",
            "count": 1
          },
          {
            "date": "2026-06-08",
            "count": 3
          },
          {
            "date": "2026-06-12",
            "count": 3
          },
          {
            "date": "2026-06-14",
            "count": 2
          },
          {
            "date": "2026-06-16",
            "count": 4
          },
          {
            "date": "2026-06-17",
            "count": 2
          },
          {
            "date": "2026-06-18",
            "count": 1
          },
          {
            "date": "2026-06-19",
            "count": 1
          },
          {
            "date": "2026-06-20",
            "count": 2
          },
          {
            "date": "2026-06-21",
            "count": 8
          },
          {
            "date": "2026-06-22",
            "count": 6
          },
          {
            "date": "2026-06-23",
            "count": 1
          },
          {
            "date": "2026-06-24",
            "count": 2
          },
          {
            "date": "2026-06-26",
            "count": 1
          },
          {
            "date": "2026-06-27",
            "count": 1
          },
          {
            "date": "2026-06-29",
            "count": 4
          },
          {
            "date": "2026-07-01",
            "count": 1
          },
          {
            "date": "2026-07-02",
            "count": 1
          },
          {
            "date": "2026-07-07",
            "count": 1
          },
          {
            "date": "2026-07-10",
            "count": 4
          },
          {
            "date": "2026-07-11",
            "count": 4
          },
          {
            "date": "2026-07-13",
            "count": 2
          },
          {
            "date": "2026-07-14",
            "count": 1
          },
          {
            "date": "2026-07-16",
            "count": 2
          },
          {
            "date": "2026-07-17",
            "count": 3
          }
        ],
        "complete": true,
        "collected": 131,
        "total_forks": 132
      },
      "star_history": null,
      "open_issues_and_prs": 31
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 80589,
      "source_files_sampled": 193,
      "oversized_source_files": 3,
      "agent_instruction_files": [
        "AGENTS.md",
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 3433
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 2,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 20,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "inspect-webkit",
          "manifest": "packages/serve-sim/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.0.5"
        },
        {
          "name": "sonner",
          "manifest": "packages/serve-sim/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.0.7"
        },
        {
          "name": "ws",
          "manifest": "packages/serve-sim/package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.21.0"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "inspect-webkit",
            "direct": true,
            "version": "^0.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "sonner",
            "direct": true,
            "version": "^2.0.7",
            "ecosystem": "npm"
          },
          {
            "name": "ws",
            "direct": true,
            "version": "^8.21.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/bun",
            "direct": false,
            "version": "latest",
            "ecosystem": "npm"
          },
          {
            "name": "@types/debug",
            "direct": false,
            "version": "^4.1.13",
            "ecosystem": "npm"
          },
          {
            "name": "@types/node",
            "direct": false,
            "version": "^25.6.2",
            "ecosystem": "npm"
          },
          {
            "name": "@types/react",
            "direct": false,
            "version": "^19.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/react-dom",
            "direct": false,
            "version": "^19.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/ws",
            "direct": false,
            "version": "^8.18.1",
            "ecosystem": "npm"
          },
          {
            "name": "bun-plugin-tailwind",
            "direct": false,
            "version": "^0.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "commander",
            "direct": false,
            "version": "^14.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "debug",
            "direct": false,
            "version": "^4.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "knip",
            "direct": false,
            "version": "^6.12.2",
            "ecosystem": "npm"
          },
          {
            "name": "lucide-react",
            "direct": false,
            "version": "^1.20.0",
            "ecosystem": "npm"
          },
          {
            "name": "node-swift",
            "direct": false,
            "version": "1.5.1",
            "ecosystem": "npm"
          },
          {
            "name": "oxlint",
            "direct": false,
            "version": "^1.63.0",
            "ecosystem": "npm"
          },
          {
            "name": "preact",
            "direct": false,
            "version": "^10.29.1",
            "ecosystem": "npm"
          },
          {
            "name": "react",
            "direct": false,
            "version": "^19.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "react-dom",
            "direct": false,
            "version": "^19.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "tailwindcss",
            "direct": false,
            "version": "^4.1.7",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^5.7.0",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "^6.0.3",
            "ecosystem": "npm"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 22,
        "direct_count": 3,
        "indirect_count": 19
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 18,
        "merged_prs": 82,
        "open_issues": 13,
        "closed_ratio": 0.458,
        "closed_issues": 11,
        "closed_unmerged_prs": 11
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "EvanBacon",
          "commits": 94,
          "avatar_url": "https://avatars.githubusercontent.com/u/9664363?v=4"
        },
        {
          "type": "User",
          "login": "kabiroberai",
          "commits": 5,
          "avatar_url": "https://avatars.githubusercontent.com/u/12706786?v=4"
        },
        {
          "type": "User",
          "login": "JoaoPauloCMarra",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/976151?v=4"
        },
        {
          "type": "User",
          "login": "krystofwoldrich",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/31292499?v=4"
        },
        {
          "type": "User",
          "login": "rounak-openai",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/181146116?v=4"
        },
        {
          "type": "User",
          "login": "jiunshinn",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/58166091?v=4"
        },
        {
          "type": "User",
          "login": "watadarkstar",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/3059371?v=4"
        },
        {
          "type": "User",
          "login": "amillez",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/74896585?v=4"
        },
        {
          "type": "User",
          "login": "bheemreddy-samsara",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/233852901?v=4"
        },
        {
          "type": "User",
          "login": "CypherPoet",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/46851636?v=4"
        }
      ],
      "contributors_sampled": 23,
      "top_contributor_share": 0.746
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "lint.yml",
        "publish-stable.yml",
        "publish.yml",
        "sim-test.yml",
        "typecheck.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "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": null,
            "reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 8,
            "reason": "23 out of 26 merged PRs checked by a CI test -- score normalized to 8",
            "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": 3,
            "reason": "Found 11/30 approved changesets -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 6 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 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": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "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": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "14ad57ff922551bf7be81e907ddfcfa6191e64f2",
        "ran_at": "2026-07-23T14:10:11Z",
        "aggregate_score": 4.4,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-18T06:08:21Z",
      "oldest_open_prs": [
        {
          "number": 13,
          "created_at": "2026-05-01T06:30:47Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 27,
          "created_at": "2026-05-05T22:58:24Z",
          "last_comment_at": "2026-05-05T23:09:06Z",
          "last_comment_author": "malopezr7"
        },
        {
          "number": 32,
          "created_at": "2026-05-07T20:30:04Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 53,
          "created_at": "2026-05-13T00:40:36Z",
          "last_comment_at": "2026-05-13T00:40:47Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 54,
          "created_at": "2026-05-13T16:56:38Z",
          "last_comment_at": "2026-05-13T21:22:17Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 61,
          "created_at": "2026-05-16T14:10:07Z",
          "last_comment_at": "2026-05-19T16:01:34Z",
          "last_comment_author": "JoaoPauloCMarra"
        },
        {
          "number": 83,
          "created_at": "2026-06-06T14:15:38Z",
          "last_comment_at": "2026-06-06T14:15:50Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 89,
          "created_at": "2026-06-14T19:32:06Z",
          "last_comment_at": "2026-06-14T23:51:22Z",
          "last_comment_author": "brahimhamichan"
        },
        {
          "number": 93,
          "created_at": "2026-06-17T19:54:47Z",
          "last_comment_at": "2026-06-17T19:54:57Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 98,
          "created_at": "2026-06-18T21:16:28Z",
          "last_comment_at": "2026-06-18T21:16:38Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 105,
          "created_at": "2026-06-21T21:41:41Z",
          "last_comment_at": "2026-06-21T21:41:54Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 120,
          "created_at": "2026-06-29T06:59:11Z",
          "last_comment_at": "2026-07-10T12:53:13Z",
          "last_comment_author": "jeroenbaas"
        },
        {
          "number": 121,
          "created_at": "2026-06-29T17:05:37Z",
          "last_comment_at": "2026-06-29T17:05:45Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 125,
          "created_at": "2026-07-02T15:57:14Z",
          "last_comment_at": "2026-07-02T15:57:44Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 127,
          "created_at": "2026-07-10T09:15:56Z",
          "last_comment_at": "2026-07-10T09:16:36Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 132,
          "created_at": "2026-07-16T18:46:08Z",
          "last_comment_at": "2026-07-17T16:58:11Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 134,
          "created_at": "2026-07-17T02:13:09Z",
          "last_comment_at": "2026-07-17T02:13:19Z",
          "last_comment_author": "coderabbitai"
        },
        {
          "number": 135,
          "created_at": "2026-07-21T04:11:38Z",
          "last_comment_at": "2026-07-21T18:48:27Z",
          "last_comment_author": "alex-vance"
        }
      ],
      "last_merged_pr_at": "2026-07-16T23:35:45Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 21,
          "created_at": "2026-05-03T14:29:35Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 39,
          "created_at": "2026-05-09T07:04:12Z",
          "last_comment_at": "2026-06-07T16:53:02Z",
          "last_comment_author": "amzzzzzzz"
        },
        {
          "number": 56,
          "created_at": "2026-05-13T21:18:10Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 62,
          "created_at": "2026-05-16T22:33:40Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 67,
          "created_at": "2026-05-19T16:18:25Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 75,
          "created_at": "2026-05-26T04:03:16Z",
          "last_comment_at": "2026-06-08T19:17:58Z",
          "last_comment_author": "jiunshinn"
        },
        {
          "number": 79,
          "created_at": "2026-06-04T20:10:13Z",
          "last_comment_at": "2026-06-07T16:53:11Z",
          "last_comment_author": "amzzzzzzz"
        },
        {
          "number": 82,
          "created_at": "2026-06-05T17:23:20Z",
          "last_comment_at": "2026-06-05T17:30:53Z",
          "last_comment_author": "weipengzou"
        },
        {
          "number": 92,
          "created_at": "2026-06-17T19:53:28Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 102,
          "created_at": "2026-06-20T06:37:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 103,
          "created_at": "2026-06-20T07:24:48Z",
          "last_comment_at": "2026-07-10T12:53:08Z",
          "last_comment_author": "jeroenbaas"
        },
        {
          "number": 123,
          "created_at": "2026-07-01T15:00:39Z",
          "last_comment_at": "2026-07-02T21:26:55Z",
          "last_comment_author": "garymc-MO"
        },
        {
          "number": 128,
          "created_at": "2026-07-10T12:53:19Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/EvanBacon/serve-sim",
    "host": "github.com",
    "name": "serve-sim",
    "owner": "EvanBacon"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 57,
      "inputs": {
        "security": 55,
        "vitality": 38,
        "community": 72,
        "governance": 65,
        "engineering": 58
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "at_risk",
        "name": "Vitality",
        "value": 38,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 63,
            "inputs": {
              "commits_last_year": 158,
              "human_commit_share": 0.86,
              "days_since_last_push": 5,
              "active_weeks_last_year": 13
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "13/52 weeks with commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 13
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "158 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 158
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "critical",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "releases_count": 0
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "no releases published",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases_published",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "no releases",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_releases",
                    "params": {}
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "good",
        "name": "Community & Adoption",
        "value": 72,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "good",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "forks": 132,
              "stars": 2563,
              "watchers": 10,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "2,563 stars",
                "points": 55.3,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 2563
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "132 forks",
                "points": 17.6,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 132
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "10 watchers",
                "points": 5.3,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "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
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "excellent",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 93,
            "inputs": {
              "packages": [
                "serve-sim"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 359392
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "359,392 downloads/month across npm",
                "points": 74.1,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 359392,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 65,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 38,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 23,
              "top_contributor_share": 0.746
            },
            "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 75% of commits",
                "points": 5.7,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 75
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "23 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 23
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 6 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "merged_prs": 82,
              "open_issues": 13,
              "closed_issues": 11,
              "issue_closed_ratio": 0.458,
              "closed_unmerged_prs": 11
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "46% of issues closed",
                "points": 21.4,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 46
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "82/93 decided PRs merged",
                "points": 33.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 82,
                      "decided": 93
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 11/30 approved changesets -- score normalized to 3",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "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": 75,
            "inputs": {
              "followers": 6181,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "EvanBacon",
              "public_repos": 343,
              "account_age_days": 4272
            },
            "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": "6,181 followers of EvanBacon",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 6181,
                      "login": "EvanBacon"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "343 public repos, account ~11 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 343
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 11
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "serve-sim"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 5
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 5 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "81 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 81
                    }
                  }
                ],
                "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": "moderate",
        "name": "Engineering Quality",
        "value": 58,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 64,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "23 out of 26 merged PRs checked by a CI test -- score normalized to 8",
                "points": 16,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [
                "agent",
                "headless",
                "ios"
              ],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": "3 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 55,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 44,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 4.4
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "23 out of 26 merged PRs checked by a CI test -- score normalized to 8",
                "points": 2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 11/30 approved changesets -- score normalized to 3",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 6 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "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": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 2 resolved dependencies against OSV; 20 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories",
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 2
                }
              },
              {
                "code": "advisories_unassessed",
                "params": {
                  "count": 20
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 2,
              "unassessed_packages": 20,
              "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": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 2,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 10
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 68,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.86,
              "agent_instruction_files": [
                "AGENTS.md",
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 3433
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md, CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md, 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": "74 of 86 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 74,
                      "sampled": 86
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 43,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0.33,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "33 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 33,
                      "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": 99,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 80589,
              "source_files_sampled": 193,
              "oversized_source_files": 3
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "3/193 source files over 60KB",
                "points": 54.1,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 193,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "deps.dev does not index npm:serve-sim@0.1.45; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-23T14:10:39.659415Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/e/EvanBacon/serve-sim.svg",
  "full_name": "EvanBacon/serve-sim",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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

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

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