Public record
Software health reportschema 0.27.0 · metrics 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 stars⑂ 132 forkssince Apr 2026View on GitHub ↗

EvanBacon/serve-sim holds a health index of 57 out of 100, placing it in the Moderate band. It scores highest on Community & Adoption (72/100) and lowest on Vitality (38/100). It was last updated 5 days ago. A single contributor accounts for most of its recent work.

57
overall / 100
Moderate

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

57
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

Evan BaconPersonal account
6,181 followers343 public repossince Nov 2014

This repository is owned by a personal account. A single-owner project carries more continuity risk than an organization-backed one.

Package ecosystems

RegistryPackageVersionDownloads / moVersionsLast publish
npmserve-sim0.1.45359,392815 days ago

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

38At risk · 22% of overall
How it's scored
36/36Push recency — last push 5 days ago
9/36Commit cadence — 13/52 weeks with commits
18/18Commit volume — 158 commits in the last year
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Inputs used
commits_last_year158
human_commit_share0.86
days_since_last_push5
active_weeks_last_year13
How it's scored
0/27Ships releases — no releases published
0/36Release recency — no releases
0/27Release cadence — no releases
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count0
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

72Good · 18% of overall
How it's scored
55.3/60Stars — 2,563 stars
17.6/25Forks — 132 forks
5.3/15Watchers — 10 watchers
Inputs used
forks132
stars2,563
watchers10
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (Apache-2.0)
0/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
How it's scored
74.1/80Monthly downloads — 359,392 downloads/month across npm
0/20Registry dependents — not reported by this ecosystem
Inputs used
packagesserve-sim
dependents
ecosystemsnpm
total_downloads
monthly_downloads359,392
Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

65Moderate · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
5.7/22.5Commit distribution — top contributor authored 75% of commits
13.5/13.5Contributor breadth — 23 contributors
10/10OpenSSF Scorecard: Contributors — project has 6 contributing companies or organizations
Inputs used
bus_factor1
contributors_sampled23
top_contributor_share0.746
How it's scored
21.4/46.8Issue resolution — 46% of issues closed
33.7/38.3PR acceptance — 82/93 decided PRs merged
4.5/15OpenSSF Scorecard: Code-Review — Found 11/30 approved changesets -- score normalized to 3
Inputs used
merged_prs82
open_issues13
closed_issues11
issue_closed_ratio0.458
closed_unmerged_prs11
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
25/25Owner reach — 6,181 followers of EvanBacon
25/25Track record — 343 public repos, account ~11 yr old
Inputs used
followers6,181
owner_typeUser
is_verified
owner_loginEvanBacon
public_repos343
account_age_days4,272
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.
How it's scored
25/25Published & resolvable — 1 package(s) on npm
35/35Publish recency — latest publish 5 days ago
20/20Version history — 81 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagesserve-sim
ecosystemsnpm
any_deprecatedno
min_days_since_publish5

Engineering Quality

Are baseline engineering and documentation practices in place?

58Moderate · 20% of overall
How it's scored
24/24CI workflows — 5 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
16/20OpenSSF Scorecard: CI-Tests — 23 out of 26 merged PRs checked by a CI test -- score normalized to 8
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentation

50Moderate
How it's scored
30/30README
0/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
10/10Topics — 3 topics
0/10Wiki
Inputs used
topicsagent, headless, ios
has_wikino
homepage
has_readmeyes
has_docs_dirno
has_descriptionyes

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

55Moderate · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — no data
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.5License — 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 — no data
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate4.4
Excluded from scoring (no data or not applicable): branch_protection, signed_releases. Remaining weights renormalized.
How it's scored
35/35Direct dependencies free of known advisories — no direct dependency carries a known advisory
0/25Indirect dependencies free of known advisories — transitive set not separable from development and test dependencies in this scope
0/40No advisories left outstanding — no advisory carries a publication date
Inputs used
sourceosv
advisories0
affected_packages0
assessed_packages2
unassessed_packages20
affected_by_severitynone
direct_affected_packages0
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.

AI Readiness

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.

68Moderate · 0% of overall
How it's scored
45/45Agent instructions — AGENTS.md, CLAUDE.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 74 of 86 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.86
agent_instruction_filesAGENTS.md, CLAUDE.md
agent_instruction_max_bytes3,433
How it's scored
0/18One-command bootstrap
22/22Automated tests
0/11Lint / format config
11/11Static type checking — tsconfig.json
0/10Reproducible environment
10/10Demonstrated agent practice — 33 of the last 100 commits agent-authored or agent-credited
0/8Automated maintenance — no automated dependency updates observed
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfiles
has_dockerfileno
typed_languageyes
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configstsconfig.json
agent_commit_share0.33
toolchain_manifests
dependency_bot_commit_share0
How it's scored
45/45Type-checkable code — TypeScript (statically typed)
54.1/55Manageable file sizes — 3/193 source files over 60KB
Inputs used
primary_languageTypeScript
largest_source_bytes80,589
source_files_sampled193
oversized_source_files3

Key facts

2,563GitHub stars
23contributors
158commits, last 12 months
5days since last push
0releases
1bus factor
13open issues
npmpackage ecosystems

Data collection 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

More detail

Star and fork history 0 ★ / 132 ⇿
0Stars
132Forks

When each star and fork was added, collected from GitHub and bucketed by day. Cumulative growth sits directly above the daily additions it is made of, so the two read against each other: steady organic accretion looks nothing like an abrupt, short-lived burst. Where that difference is measurable, it is reported as growth authenticity.

0255075100125150131102026-042026-062026-07
OpenSSF Scorecard 4.4 / 10
4.4aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).Scorecard v5.5.0 · 2026-07-23 14:10 UTC

10Binary-Artifactsno binaries found in the repo
n/aBranch-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
n/aSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Direct dependencies 3
RegistryPackageVersion constraintManifest
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
All dependencies 22

Full resolved dependency set from the GitHub dependency graph: 3 direct and 19 indirect (transitive) packages. The transitive closure is complete when the repository commits a lockfile.

RegistryPackageVersionRelation
npminspect-webkit^0.0.5direct
npmsonner^2.0.7direct
npmws^8.21.0direct
npm@types/bunlatestindirect
npm@types/debug^4.1.13indirect
npm@types/node^25.6.2indirect
npm@types/react^19.0.0indirect
npm@types/react-dom^19.0.0indirect
npm@types/ws^8.18.1indirect
npmbun-plugin-tailwind^0.1.2indirect
npmcommander^14.0.1indirect
npmdebug^4.4.3indirect
npmknip^6.12.2indirect
npmlucide-react^1.20.0indirect
npmnode-swift1.5.1indirect
npmoxlint^1.63.0indirect
npmpreact^10.29.1indirect
npmreact^19.0.0indirect
npmreact-dom^19.0.0indirect
npmtailwindcss^4.1.7indirect
npmtypescript^5.7.0indirect
npmtypescript^6.0.3indirect
Dependency advisories 0

This repository publishes no package the index resolves, so its own dependency graph was assessed — 2 packages, which also include development and test pins that never ship: 0 carry known advisories, of which 0 are direct. 20 could not be assessed — no resolved version, an unsupported ecosystem, or beyond the reported package list.

No known advisories affect the assessed dependencies.

An advisory means the version recorded in the dependency graph falls inside an advisory’s affected range. Reachability is not analysed, and the graph includes development and test pins — a finding may concern tooling rather than shipped software.

Raw JSON report machine-readable
{
  "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"
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statisticsnpm.