公开记录
软件健康报告模式 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年4月在 GitHub 上查看 ↗

EvanBacon/serve-sim 的健康指数为 100 分中的 57 分,处于「中等」区间。 其得分最高的类别是Community & Adoption(72/100),最低的是Vitality(38/100)。 最近一次更新在 5 天前。 近期的大部分工作由 1 位贡献者完成。

57
总分 / 100
中等

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 49(有风险)的上限。AI 就绪度不计入总体分。

57
优秀85-100堪称典范;基本满足所有检验标准
良好70-84健康;仅有轻微不足
中等50-69可接受,但存在明显不足;建议进行审查
存在风险30-49存在重大薄弱环节;采用时应保持审慎
危急1-29问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。

所有权

Evan Bacon个人账户
6,181 关注者343 个公开仓库始于 2014年11月

该仓库由个人账户拥有。相较于组织支持的项目,单一所有者项目的延续性风险更高。

软件包生态系统

注册表软件包版本月下载量版本数最近发布
npmserve-sim0.1.45359,392815 天前

按类别列示的指标

活力

项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?

38存在风险 · 占总体的 22%
评分方式
36/36推送新近度 — 最近一次推送于 5 天前
9/36提交节奏 — 52 周中有 13 周有提交
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

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(Apache-2.0)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template
评分方式
74.1/80月度下载量 — npm 合计每月 359,392 次下载
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议题解决 — 46% 的议题已关闭
33.7/38.3PR 接受 — 已裁定的 PR 中 82/93 已合并
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所有者影响力 — EvanBacon 有 6,181 位关注者
25/25既往记录 — 343 个公开仓库,账户约 11 年
所用输入
followers6,181
owner_typeUser
is_verified
owner_loginEvanBacon
public_repos343
account_age_days4,272
已排除计分(无数据或不适用):已验证域名。 其余权重已重新归一化。
评分方式
25/25已发布且可解析 — npm 上有 1 个软件包
35/35发布时效 — 最近一次发布于 5 天前
20/20版本历史 — 81 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagesserve-sim
ecosystemsnpm
any_deprecated
min_days_since_publish5

工程质量

基础的工程与文档实践是否到位?

58中等 · 占总体的 20%

工程实践

64中等
评分方式
24/24CI 工作流 — 5 个工作流
24/24存在测试
0/16Linter 配置
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 项无法评估——没有已解析的版本、生态系统不受支持,或超出所报告的软件包清单。 该仓库未发布任何索引可解析的软件包,因此改为评估仓库依赖图。该图将开发与测试版本固定同交付的依赖混在一起,因此仅对声明的运行时依赖计分;传递性发现仅作为背景信息列出,不计入评分。 未对可达性进行分析。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?这是一枚独立的实验性徽章——权重为 0.0,因此单独呈现,不影响总体健康评分。

68中等 · 占总体的 0%
评分方式
45/45代理指令 — AGENTS.md, CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 86 次人类提交中有 74 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.86
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes3,433
评分方式
0/18一条命令的引导启动
22/22自动化测试
0/11Lint / 格式化配置
11/11静态类型检查 — tsconfig.json
0/10可复现环境
10/10已体现的代理实践 — 最近 100 次提交中有 33 次由代理编写或署名代理
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可控的文件大小 — 采样的 193 个源文件中有 3 个超过 60KB
所用输入
primary_languageTypeScript
largest_source_bytes80,589
source_files_sampled193
oversized_source_files3

关键数据

2,563GitHub 星标
23贡献者
158最近 12 个月提交数
5距最近推送天数
0发布版本数
1巴士系数(bus factor)
13开放议题
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

更多细节

Star 与 Fork 历史 0 ★ / 132 ⇿
0Star
132Fork

每颗 star 和每个 fork 的添加时间,来自 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 个间接(传递)软件包。仓库提交锁文件时,传递闭包才是完整的。

注册表软件包版本关系
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.