Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-27 11:15 UTC

BoPeng / ai-marketplace-monitor

Monitor facebook marketplace with AI

HTMLAGPL-3.0★ 280 stars⑂ 71 forkssince Jan 2025View on GitHub ↗

BoPeng/ai-marketplace-monitor holds a health index of 73 out of 100, placing it in the Good band. It scores highest on Engineering Quality (90/100) and lowest on Sustainability & Governance (58/100). It was last updated 2 days ago. A single contributor accounts for most of its recent work.

73
overall / 100
Good

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.

73
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

BoPersonal account
61 followers22 public repossince Nov 2014Baylor College of Medicine

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 publishTags
PyPIai-marketplace-monitor0.10.2-2210 days agoai-marketplace-monitor

Metrics by category

Vitality

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

82Good · 22% of overall
How it's scored
36/36Push recency — last push 2 days ago
7.6/36Commit cadence — 11/52 weeks with commits
16.6/18Commit volume — 69 commits in the last year
10/10OpenSSF Scorecard: Maintained — 29 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year69
human_commit_share0.69
days_since_last_push2
active_weeks_last_year11

Release discipline

100Excellent
How it's scored
27/27Ships releases — 4 releases published
36/36Release recency — latest release 10 days ago
27/27Release cadence — a release every ~37.7 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count4
latest_release_tagv0.10.2
releases_from_tagsno
days_since_latest_release10
mean_days_between_releases37.7
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?

75Good · 18% of overall
How it's scored
39.7/60Stars — 280 stars
15.4/25Forks — 71 forks
5.3/15Watchers — 10 watchers
Inputs used
forks71
stars280
watchers10
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

Community health

92Excellent
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (AGPL-3.0)
18/18CONTRIBUTING guide
13.5/13.5Code of conduct
0/7.2Issue template
6.3/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingyes
has_issue_templateno
has_code_of_conductyes
has_pull_request_templateyes

Sustainability & Governance

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

58Moderate · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
3.6/22.5Commit distribution — top contributor authored 84% of commits
9.5/13.5Contributor breadth — 7 contributors
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Inputs used
bus_factor1
contributors_sampled7
top_contributor_share0.841
How it's scored
40.2/46.8Issue resolution — 86% of issues closed
22.1/38.3PR acceptance — 154/267 decided PRs merged
4.5/15OpenSSF Scorecard: Code-Review — Found 3/8 approved changesets -- score normalized to 3
Inputs used
merged_prs154
open_issues11
closed_issues67
issue_closed_ratio0.859
closed_unmerged_prs113
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
12.9/25Owner reach — 61 followers of BoPeng
21.9/25Track record — 22 public repos, account ~11 yr old
Inputs used
followers61
owner_typeUser
is_verified
owner_loginBoPeng
public_repos22
account_age_days4,265
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.
How it's scored
25/25Published & resolvable — 1 package(s) on pypi
35/35Publish recency — latest publish 10 days ago
20/20Version history — 22 published versions
20/20Not deprecated — active, not deprecated or yanked
Inputs used
packagesai-marketplace-monitor
ecosystemspypi
any_deprecatedno
min_days_since_publish10

Engineering Quality

Are baseline engineering and documentation practices in place?

90Excellent · 20% of overall
How it's scored
24/24CI workflows — 6 workflow(s)
24/24Tests present
16/16Linter config
9.6/9.6Pre-commit hooks
0/6.4.editorconfig
16/20OpenSSF Scorecard: CI-Tests — 19 out of 22 merged PRs checked by a CI test -- score normalized to 8
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configyes
has_precommit_configyes

Documentation

90Excellent
How it's scored
30/30README
25/25Documentation directory
15/15Documentation / homepage site — https://ai-marketplace-monitor.readthedocs.io/en/latest/
10/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepagehttps://ai-marketplace-monitor.readthedocs.io/en/latest/
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

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

62Moderate · 16% of overall
How it's scored
6.8/7.5Binary-Artifacts — binaries present in source code
3/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2/2.5CI-Tests — 19 out of 22 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 3/8 approved changesets -- score normalized to 3
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 29 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
4.5/5SAST — SAST tool detected but not run on all commits
2/5Security-Policy — security policy file detected
0/7.5Signed-Releases — no data
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 79 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate5.5
Excluded from scoring (no data or not applicable): signed_releases. Remaining weights renormalized.
How it's scored
26.6/35Direct dependencies free of known advisories — 1 affected: diskcache 5.6.3 (moderate)
25/25Indirect dependencies free of known advisories — no indirect dependency carries a known advisory
37.2/40No advisories left outstanding — 1 advisory-carrying package(s) unaddressed past 90 days; oldest published 165 days ago
Inputs used
sourceosv
advisories2
affected_packages1
assessed_packages95
unassessed_packages0
affected_by_severitymoderate 1
direct_affected_packages1
Matched the pypi:ai-marketplace-monitor@0.10.2 runtime dependency closure — what installing the published package pulls in — 95 packages. 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
0/45Agent instructions — no CLAUDE.md / AGENTS.md / editor rules
0/15Machine-readable docs (llms.txt)
32.5/40Legible commit history — 42 of 69 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.609
agent_instruction_files
agent_instruction_max_bytes
How it's scored
18/18One-command bootstrap — noxfile.py
22/22Automated tests
11/11Lint / format config
11/11Static type checking — src/ai_marketplace_monitor/py.typed
10/10Reproducible environment — Dockerfile, lockfile
10/10Demonstrated agent practice — 12 of the last 100 commits agent-authored or agent-credited
8/8Automated maintenance — 31 of the last 100 commits are automated dependency updates
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfilesuv.lock
has_dockerfileyes
typed_languageno
bootstrap_filesnoxfile.py
has_devcontainerno
has_linter_configyes
typecheck_configssrc/ai_marketplace_monitor/py.typed
agent_commit_share0.12
toolchain_manifests
dependency_bot_commit_share0.31
How it's scored
27/45Type-checkable code — HTML with type-check config (src/ai_marketplace_monitor/py.typed)
53.8/55Manageable file sizes — 1/45 source files over 60KB
Inputs used
primary_languageHTML
largest_source_bytes67,138
source_files_sampled45
oversized_source_files1

Key facts

280GitHub stars
7contributors
69commits, last 12 months
2days since last push
4releases
1bus factor
11open issues
PyPIpackage ecosystems

Data collection warnings

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

More detail

Star and fork history 0 ★ / 71 ⇿
0Stars
71Forks
4Releases

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.

01325385063757132025-022025-112026-07
Major 0Minor 1Patch 3

Each point covers 2 days.

OpenSSF Scorecard 5.5 / 10
5.5aggregate

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-27 11:15 UTC

9Binary-Artifactsbinaries present in source code
4Branch-Protectionbranch protection is not maximal on development and all release branches
8CI-Tests19 out of 22 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 3/8 approved changesets -- score normalized to 3
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained29 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
9SASTSAST tool detected but not run on all commits
4Security-Policysecurity policy file detected
n/aSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities79 existing vulnerabilities detected
Direct dependencies 26
RegistryPackageVersion constraintManifest
PyPItyper>=0.15.1,<0.28.0pyproject.toml
PyPIplaywright>=1.41.0pyproject.toml
PyPIrich>=13.7.0pyproject.toml
PyPIpushbullet.py>=0.12.0pyproject.toml
PyPIdiskcache>=5.6.3pyproject.toml
PyPIwatchdog>=4.0.0pyproject.toml
PyPIopenai>=1.24.0pyproject.toml
PyPIanthropic>=0.39.0pyproject.toml
PyPIparsedatetime>=2.5pyproject.toml
PyPIhumanize>=4.0.0pyproject.toml
PyPIschedule>=1.2.2pyproject.toml
PyPIinflect>=7.0.0pyproject.toml
PyPIpillow>=10.0.0pyproject.toml
PyPIjinja2>=3.0.0pyproject.toml
PyPIpyparsing>=3.1.0pyproject.toml
PyPIrequests>=2.30.0pyproject.toml
PyPICurrencyConverter>=0.18.0pyproject.toml
PyPItomli==2.2.1pyproject.toml
PyPIsafety>=3.5.2pyproject.toml
PyPIpip-audit>=2.9.0pyproject.toml
PyPIpython-telegram-bot>=22.3pyproject.toml
PyPIfastapi>=0.110pyproject.toml
PyPIuvicorn>=0.27pyproject.toml
PyPIitsdangerous>=2.1pyproject.toml
PyPIbcrypt>=4.0pyproject.toml
PyPIpython-multipart>=0.0.9pyproject.toml
All dependencies 184

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

RegistryPackageVersionRelation
PyPIanthropic0.94.0direct
PyPIbcrypt5.0.0direct
PyPIcurrencyconverter0.18.9direct
PyPIdiskcache5.6.3direct
PyPIfastapi0.135.3direct
PyPIhumanize4.12.3direct
PyPIinflect7.5.0direct
PyPIitsdangerous2.2.0direct
PyPIjinja23.1.6direct
PyPIopenai1.98.0direct
PyPIparsedatetime2.6direct
PyPIpillow11.3.0direct
PyPIpip-audit2.9.0direct
PyPIplaywright1.54.0direct
PyPIpushbullet-py0.12.0direct
PyPIpyparsing3.2.3direct
PyPIpython-multipart0.0.26direct
PyPIpython-telegram-bot22.3direct
PyPIrequests2.32.4direct
PyPIrich14.1.0direct
PyPIsafety3.6.0direct
PyPIschedule1.2.2direct
PyPItomli2.2.1direct
PyPItyper0.16.0direct
PyPIuvicorn0.44.0direct
PyPIwatchdog6.0.0direct
PyPIaccessible-pygments0.0.5indirect
PyPIai-marketplace-monitor0.10.0indirect
PyPIalabaster1.0.0indirect
PyPIannotated-doc0.0.4indirect
PyPIannotated-types0.7.0indirect
PyPIanyio4.9.0indirect
PyPIauthlib1.6.1indirect
PyPIbabel2.17.0indirect
PyPIbackports-asyncio-runner1.2.0indirect
PyPIbackports-datetime-fromisoformat2.0.3indirect
PyPIbackports-tarfile1.2.0indirect
PyPIbeautifulsoup44.13.4indirect
PyPIblack25.1.0indirect
PyPIboolean-py5.0indirect
PyPIbuild1.3.0indirect
PyPIbump2version1.0.1indirect
PyPIcachecontrol0.14.3indirect
PyPIcertifi2025.7.14indirect
PyPIcffi1.17.1indirect
PyPIcfgv3.4.0indirect
PyPIcharset-normalizer3.4.2indirect
PyPIclick8.2.1indirect
PyPIcolorama0.4.6indirect
PyPIcoverage7.10.1indirect
PyPIcryptography45.0.5indirect
PyPIcyclonedx-python-lib9.1.0indirect
PyPIdefusedxml0.7.1indirect
PyPIdistlib0.4.0indirect
PyPIdistro1.9.0indirect
PyPIdocstring-parser0.17.0indirect
PyPIdocutils0.21.2indirect
PyPIdparse0.6.4indirect
PyPIevdev1.9.2indirect
PyPIexceptiongroup1.3.0indirect
PyPIfilelock3.16.1indirect
PyPIfuroindirect
PyPIfuro2025.7.19indirect
PyPIgreenlet3.2.3indirect
PyPIh110.16.0indirect
PyPIhttpcore1.0.9indirect
PyPIhttptools0.7.1indirect
PyPIhttpx0.28.1indirect
PyPIid1.5.0indirect
PyPIidentify2.6.12indirect
PyPIidna3.10indirect
PyPIimagesize1.4.1indirect
PyPIimportlib-metadata8.7.0indirect
PyPIiniconfig2.1.0indirect
PyPIinvoke2.2.0indirect
PyPIisort6.0.1indirect
PyPIjaraco-classes3.4.0indirect
PyPIjaraco-context6.0.1indirect
PyPIjaraco-functools4.2.1indirect
PyPIjeepney0.9.0indirect
PyPIjiter0.10.0indirect
PyPIjoblib1.5.1indirect
PyPIkeyring25.6.0indirect
PyPIlicense-expression30.4.4indirect
PyPIlinkify-it-pyindirect
PyPIlinkify-it-py2.0.3indirect
PyPImarkdown-it-py3.0.0indirect
PyPImarkupsafe3.0.2indirect
PyPImarshmallow4.0.0indirect
PyPImdit-py-plugins0.4.2indirect
PyPImdurl0.1.2indirect
PyPImore-itertools10.7.0indirect
PyPImsgpack1.1.1indirect
PyPImypy1.17.1indirect
PyPImypy-extensions1.1.0indirect
PyPImyst-parserindirect
PyPImyst-parser4.0.1indirect
PyPInh30.3.0indirect
PyPInltk3.9.1indirect
PyPInodeenv1.9.1indirect
PyPIpackageurl-python0.17.2indirect
PyPIpackaging25.0indirect
PyPIpathspec0.12.1indirect
PyPIpip25.2indirect
PyPIpip-api0.0.34indirect
PyPIpip-requirements-parser32.0.1indirect
PyPIplatformdirs4.3.8indirect
PyPIpluggy1.6.0indirect
PyPIpre-commit4.2.0indirect
PyPIpsutil6.1.1indirect
PyPIpy-serializable2.1.0indirect
PyPIpycparser2.22indirect
PyPIpydantic2.9.2indirect
PyPIpydantic-core2.23.4indirect
PyPIpyee13.0.0indirect
PyPIpygments2.19.2indirect
PyPIpynput1.8.1indirect
PyPIpyobjc-core11.1indirect
PyPIpyobjc-framework-applicationservices11.1indirect
PyPIpyobjc-framework-cocoa11.1indirect
PyPIpyobjc-framework-coretext11.1indirect
PyPIpyobjc-framework-quartz11.1indirect
PyPIpyproject-hooks1.2.0indirect
PyPIpytest8.4.1indirect
PyPIpytest-asyncio1.1.0indirect
PyPIpytest-base-url2.1.0indirect
PyPIpytest-cov6.2.1indirect
PyPIpytest-playwright0.7.0indirect
PyPIpython-dotenv1.2.2indirect
PyPIpython-magic0.4.27indirect
PyPIpython-slugify8.0.4indirect
PyPIpython-xlib0.33indirect
PyPIpywin32-ctypes0.2.3indirect
PyPIpyyaml6.0.2indirect
PyPIreadme-renderer44.0indirect
PyPIregex2025.7.34indirect
PyPIrequests-toolbelt1.0.0indirect
PyPIrfc39862.0.0indirect
PyPIroman-numerals-py3.1.0indirect
PyPIruamel-yaml0.18.14indirect
PyPIruamel-yaml-clib0.2.12indirect
PyPIruff0.12.7indirect
PyPIsafety-schemas0.0.14indirect
PyPIsecretstorage3.3.3indirect
PyPIsetuptools80.9.0indirect
PyPIshellingham1.5.4indirect
PyPIsix1.17.0indirect
PyPIsniffio1.3.1indirect
PyPIsnowballstemmer3.0.1indirect
PyPIsortedcontainers2.4.0indirect
PyPIsoupsieve2.7indirect
PyPIsphinxindirect
PyPIsphinx8.1.3indirect
PyPIsphinx8.2.3indirect
PyPIsphinx-basic-ng1.0.0b2indirect
PyPIsphinx-copybuttonindirect
PyPIsphinx-copybutton0.5.2indirect
PyPIsphinxcontrib-applehelp2.0.0indirect
PyPIsphinxcontrib-devhelp2.0.0indirect
PyPIsphinxcontrib-htmlhelp2.1.0indirect
PyPIsphinxcontrib-jsmath1.0.1indirect
PyPIsphinxcontrib-qthelp2.0.0indirect
PyPIsphinxcontrib-serializinghtml2.0.0indirect
PyPIsphinxext-opengraphindirect
PyPIsphinxext-opengraph0.12.0indirect
PyPIstarlette1.0.0indirect
PyPItenacity9.1.2indirect
PyPItext-unidecode1.3indirect
PyPItoml0.10.2indirect
PyPItomlkit0.13.3indirect
PyPItqdm4.67.1indirect
PyPItwine6.1.0indirect
PyPItypeguard4.4.4indirect
PyPItyping-extensions4.14.1indirect
PyPItyping-inspection0.4.2indirect
PyPIuc-micro-py1.0.3indirect
PyPIurllib32.5.0indirect
PyPIuvloop0.22.1indirect
PyPIvirtualenv20.32.0indirect
PyPIwatchfiles1.1.1indirect
PyPIwebsocket-client1.8.0indirect
PyPIwebsockets16.0indirect
PyPIxdoctest1.2.0indirect
PyPIzipp3.23.0indirect
Dependency advisories 1

Installing pypi:ai-marketplace-monitor@0.10.2 pulls in 95 packages, direct and transitive: 1 carry known advisories, of which 1 are direct dependencies.

PackageVersionRelationSeverityAdvisoriesFixed in
diskcache5.6.3directmoderate2

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": [],
      "is_fork": false,
      "size_kb": 5037,
      "has_wiki": true,
      "homepage": "https://ai-marketplace-monitor.readthedocs.io/en/latest/",
      "languages": {
        "CSS": 17265,
        "HTML": 13691514,
        "Jinja": 9136,
        "Python": 393616,
        "Dockerfile": 2542,
        "JavaScript": 67138
      },
      "pushed_at": "2026-07-24T15:53:31Z",
      "created_at": "2025-01-20T15:42:42Z",
      "owner_type": "User",
      "updated_at": "2026-07-27T04:06:26Z",
      "description": "Monitor facebook marketplace with AI",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "AGPL-3.0",
      "default_branch": "main",
      "license_spdx_raw": "AGPL-3.0",
      "primary_language": "HTML",
      "significant_languages": [
        "HTML"
      ]
    },
    "owner": {
      "blog": "http://bioworkflows.com",
      "name": "Bo",
      "type": "User",
      "login": "BoPeng",
      "company": "Baylor College of Medicine",
      "location": "Houston, TX, USA",
      "followers": 61,
      "avatar_url": "https://avatars.githubusercontent.com/u/9889312?v=4",
      "created_at": "2014-11-21T20:13:47Z",
      "is_verified": null,
      "public_repos": 22,
      "account_age_days": 4265
    },
    "license": {
      "state": "standard",
      "spdx_id": "AGPL-3.0",
      "raw_spdx": "AGPL-3.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.10.2",
          "kind": "patch",
          "published_at": "2026-07-17T05:27:37Z"
        },
        {
          "tag": "v0.10.1",
          "kind": "patch",
          "published_at": "2026-04-12T18:25:20Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-04-12T14:28:35Z"
        },
        {
          "tag": "v0.9.12",
          "kind": "patch",
          "published_at": "2026-03-26T05:32:53Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "16394b3e2a8c232f6d78a942fb85237f4e193a85",
          "body": "chore: release 0.10.2",
          "is_bot": false,
          "headline": "Merge pull request #342 from BoPeng/release/0.10.2",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T05:23:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2edddac6f121b0267d93a7b5c0ca2cb7b5a6d2f7",
          "body": "Roll the [Unreleased] entries (sort_by #323, Web UI Export CSV #334) into\nthe [0.10.2] section and date it. 0.10.2 was bumped in pyproject earlier\nbut never tagged/published (PyPI latest was 0.10.1), so this becomes the\nnext release covering everything since 0.10.1.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: finalize CHANGELOG for 0.10.2 release",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T05:19:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2380e01ebb4dbd784843052786bf2646f7f7a971",
          "body": "* docs: design spec for Web UI found-items CSV export (#334)\n\nBrainstormed design for an \"Export CSV\" button that downloads the\nmatched/notified listings (link, price, rating, etc.) by reading and\njoining the existing diskcache. No scraping, no new storage.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@\n[…]\nmula-injection sanitization and two-pass exclusion of\nun-notified listings.\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: Web UI Export CSV of found items (#334) (#341)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T05:12:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7687f0802ce1e181b693d6d33a6fa7c55d54241d",
          "body": "* feat: add sort_by option for Facebook search results (#323)\n\nAdd a `sort_by` option that maps to Facebook Marketplace's `sortBy`\nquery parameter, letting users order results by newest first, price,\nor distance instead of the default \"suggested\" ranking. This enables\nmonitoring of newly listed item\n[…]\nan expected-type map;\nadd the new sort_by option (str | None) so it passes.\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: add sort_by option for Facebook search results (#323) (#340)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:57:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3d78cc80950f9c969cf18dd6f08a10d7a8bc5451",
          "body": "Update sphinx requirement from >=8.1.3 to >=9.1.0 in /docs",
          "is_bot": false,
          "headline": "Merge pull request #317 from BoPeng/dependabot/pip/docs/sphinx-gte-9.1.0",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9054be568b81c6b713c8b85d13baefc80f1ed9dc",
          "body": "…ngraph-gte-0.13.0\n\nUpdate sphinxext-opengraph requirement from >=0.9.0 to >=0.13.0 in /docs",
          "is_bot": false,
          "headline": "Merge pull request #319 from BoPeng/dependabot/pip/docs/sphinxext-ope…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b757988c632dcca77ae15d5c9a1aa7fe8be8ea8",
          "body": "…build-push-action-7\n\nBump docker/build-push-action from 6 to 7",
          "is_bot": false,
          "headline": "Merge pull request #327 from BoPeng/dependabot/github_actions/docker/…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb72cc11f44551ce7af7ba93f4fad38a48581eac",
          "body": "…metadata-action-6\n\nBump docker/metadata-action from 5 to 6",
          "is_bot": false,
          "headline": "Merge pull request #328 from BoPeng/dependabot/github_actions/docker/…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f05ffbb71dc7d767e977e355c34511285c346bb",
          "body": "…setup-qemu-action-4\n\nBump docker/setup-qemu-action from 3 to 4",
          "is_bot": false,
          "headline": "Merge pull request #329 from BoPeng/dependabot/github_actions/docker/…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4437a755f9fd965c5f4510de95731eb7b7882cba",
          "body": "…/checkout-6\n\nBump actions/checkout from 4 to 6",
          "is_bot": false,
          "headline": "Merge pull request #330 from BoPeng/dependabot/github_actions/actions…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ca9d43f9a26a23d4b50988f37dedd776e68cea9a",
          "body": "…setup-buildx-action-4\n\nBump docker/setup-buildx-action from 3 to 4",
          "is_bot": false,
          "headline": "Merge pull request #331 from BoPeng/dependabot/github_actions/docker/…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-07-17T01:20:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b01be82acfee622b5130a99c45e64719a83dfbf2",
          "body": "…#336)\n\nFacebook removed the <button name=\"login\"> element from their login page.\nThe login form now uses <div> elements for the \"Log in\" button, which means\nwaiting for button[name=\"login\"] always times out.\n\nFix: after typing credentials, press Enter to submit the form instead.\nThe form has id=\"login_form\" and handles submit events correctly via keyboard.\n\nCo-authored-by: josharmour <1240306+josharmour@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Fix Facebook login: use Enter key instead of broken button selector (…",
          "author_name": "josharmour",
          "author_login": "josharmour",
          "committed_at": "2026-07-17T01:20:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4502b6274a8e3444beebd10583c1f5600fafa80f",
          "body": "Updates the requirements on [myst-parser](https://github.com/executablebooks/MyST-Parser) to permit the latest version.\n- [Release notes](https://github.com/executablebooks/MyST-Parser/releases)\n- [Changelog](https://github.com/executablebooks/MyST-Parser/blob/master/CHANGELOG.md)\n- [Commits](https:\n[…]\nendency-version: 5.1.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update myst-parser requirement from >=3.0.0 to >=5.1.0 in /docs (#332)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-17T01:18:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6d79f2c44a44320fce1c397d44f481018a8df75b",
          "body": "…startup with FastAPI >= 0.139 (#337)\n\nFacebook changed the Marketplace listing page to render the Details\nsection (condition, description, location) in nested span/div structures\ninstead of ul/li lists, causing all existing page parsers to fail with\n'Failed to get item details' for every listing (#\n[…]\nl=None, as\nnewer FastAPI versions refuse to build a response model from the\nDict | JSONResponse return annotation and the web UI fails to start.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add FacebookFlexItemPage for new span/div listing layout; fix web UI …",
          "author_name": "Cameron",
          "author_login": "BlackIsBlack",
          "committed_at": "2026-07-17T01:17:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "18060590496ce4bb0572598a4dace56cdb6b757b",
          "body": "Add a GeminiBackend that uses Google's OpenAI-compatible endpoint\n(https://generativelanguage.googleapis.com/v1beta/openai/) with\ngemini-2.5-flash as the default model, registered as [ai.gemini] /\nprovider = 'Gemini'. Document the new provider in the READMEs.\n\nCo-authored-by: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add Google Gemini AI backend (#338)",
          "author_name": "Cameron",
          "author_login": "BlackIsBlack",
          "committed_at": "2026-07-17T01:17:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "11b26d55641f534d4560ee4d0e865b5c59624acc",
          "body": "…339)\n\nUpdates the requirements on [typer](https://github.com/fastapi/typer) to permit the latest version.\n- [Release notes](https://github.com/fastapi/typer/releases)\n- [Changelog](https://github.com/fastapi/typer/blob/master/docs/release-notes.md)\n- [Commits](https://github.com/fastapi/typer/compa\n[…]\nndency-version: 0.27.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update typer requirement from <0.26.0,>=0.15.1 to >=0.15.1,<0.28.0 (#…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-17T01:16:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c4f9da45c1a366c7807e1b5cde89a39cd90f2404",
          "body": "Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.\n- [Release notes](https://github.com/docker/setup-buildx-action/releases)\n- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)\n\n---\nupdated-dependencies:\n- dependency-name: docker/setup-buildx-action\n  dependency-version: '4'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump docker/setup-buildx-action from 3 to 4",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T01:26:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba63175d51a39e57f036a8655482c9f2d2ebd467",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/v4...v6)\n\n---\nupdated-dependenc\n[…]\n:\n- dependency-name: actions/checkout\n  dependency-version: '6'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump actions/checkout from 4 to 6",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T01:26:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "908b459d8a70fd26c5028e1e802bba495fcdad52",
          "body": "Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.\n- [Release notes](https://github.com/docker/setup-qemu-action/releases)\n- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)\n\n---\nupdated-dependencies:\n- dependency-name: docker/setup-qemu-action\n  dependency-version: '4'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump docker/setup-qemu-action from 3 to 4",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T01:25:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2bb7ab67f9a9c14585ac950b5198c890687dc60d",
          "body": "Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.\n- [Release notes](https://github.com/docker/metadata-action/releases)\n- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)\n\n---\nupdated-dependencies:\n- dependency-name: docker/metadata-action\n  dependency-version: '6'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump docker/metadata-action from 5 to 6",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T01:25:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d00e8b25e82950b9674eed419ce30e784c9a389",
          "body": "Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.\n- [Release notes](https://github.com/docker/build-push-action/releases)\n- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)\n\n---\nupdated-dependencies:\n- dependency-name: docker/build-push-action\n  dependency-version: '7'\n  dependency-type: direct:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Bump docker/build-push-action from 6 to 7",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-19T01:25:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "69b214d4578fbe08a3827013f4c5e3cd00c2b0c0",
          "body": null,
          "is_bot": false,
          "headline": "Add Docker image with embedded noVNC browser view (#310) (#325)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-05-16T13:21:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "24c17aee1e74590503ceda029983abc03a77f6aa",
          "body": "Updates the requirements on [sphinxext-opengraph](https://github.com/sphinx-doc/sphinxext-opengraph) to permit the latest version.\n- [Release notes](https://github.com/sphinx-doc/sphinxext-opengraph/releases)\n- [Commits](https://github.com/sphinx-doc/sphinxext-opengraph/compare/v0.9.0...v0.13.0)\n\n---\nupdated-dependencies:\n- dependency-name: sphinxext-opengraph\n  dependency-version: 0.13.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Update sphinxext-opengraph requirement from >=0.9.0 to >=0.13.0 in /docs",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:36:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "746e995c3f089fc66e8a8b2cb70ab2e0baf2f235",
          "body": "Updates the requirements on [sphinx](https://github.com/sphinx-doc/sphinx) to permit the latest version.\n- [Release notes](https://github.com/sphinx-doc/sphinx/releases)\n- [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES.rst)\n- [Commits](https://github.com/sphinx-doc/sphinx/compare/v8.1.3...v9.1.0)\n\n---\nupdated-dependencies:\n- dependency-name: sphinx\n  dependency-version: 9.1.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "Update sphinx requirement from >=8.1.3 to >=9.1.0 in /docs",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:36:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c6225a4015d270c8765fc4154fd4a80681b0ecf1",
          "body": "…322)\n\nUpdates the requirements on [typer](https://github.com/fastapi/typer) to permit the latest version.\n- [Release notes](https://github.com/fastapi/typer/releases)\n- [Changelog](https://github.com/fastapi/typer/blob/master/docs/release-notes.md)\n- [Commits](https://github.com/fastapi/typer/compa\n[…]\nndency-version: 0.25.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update typer requirement from <0.25.0,>=0.15.1 to >=0.15.1,<0.26.0 (#…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:32:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "250249a87e9d957a7e3632979af81c16d921ef40",
          "body": "Updates the requirements on [linkify-it-py](https://github.com/tsutsu3/linkify-it-py) to permit the latest version.\n- [Release notes](https://github.com/tsutsu3/linkify-it-py/releases)\n- [Changelog](https://github.com/tsutsu3/linkify-it-py/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/tsuts\n[…]\nendency-version: 2.1.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update linkify-it-py requirement from >=2.0.0 to >=2.1.0 in /docs (#318)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:32:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b110ca5b7da8c4d666dbc43717bb9dbe4cfc7357",
          "body": "Updates the requirements on [furo](https://github.com/pradyunsg/furo) to permit the latest version.\n- [Release notes](https://github.com/pradyunsg/furo/releases)\n- [Changelog](https://github.com/pradyunsg/furo/blob/main/docs/changelog.md)\n- [Commits](https://github.com/pradyunsg/furo/compare/2024.01\n[…]\ncy-version: 2025.12.19\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update furo requirement from >=2024.1.29 to >=2025.12.19 in /docs (#316)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:32:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ed5b6b88bc5188d25708cc3b3b07920d8c4736a2",
          "body": "Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.\n- [Release notes](https://github.com/actions/upload-artifact/releases)\n- [Commits](https://github.com/actions/upload-artifact/compare/v7.0.0...v7.0.1)\n\n---\nupdated-dependencies:\n- dependency-name: action\n[…]\nirect:production\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump actions/upload-artifact from 7.0.0 to 7.0.1 (#313)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:32:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2cc92c0eb6aa69a54bc004ed4755103790592c25",
          "body": "Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.8 to 8.1.1.\n- [Release notes](https://github.com/peter-evans/create-pull-request/releases)\n- [Commits](https://github.com/peter-evans/create-pull-request/compare/v7.0.8...v8.1.1)\n\n---\nupdated-depende\n[…]\nirect:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump peter-evans/create-pull-request from 7.0.8 to 8.1.1 (#312)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-16T06:32:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f0316d30f9ee8c7cc16db2f538f29332f5d76b55",
          "body": null,
          "is_bot": false,
          "headline": "Fix WebUI startup failure on older FastAPI versions (#315)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-14T01:47:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5487b229d069f2956db57b232b8c3940e15cff00",
          "body": null,
          "is_bot": false,
          "headline": "Fix stale runtime version reporting (#314)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-14T01:27:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "999542a43f15977714cc8d71a6f888bc08524046",
          "body": "Closes #302",
          "is_bot": false,
          "headline": "Add Python 3.10+ requirement note to Quick Start section (#311)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-13T14:18:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "03036665dba1a989c8af52f07b8d25b56a01c021",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix broken WEBUI.md link in README (case mismatch)",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T18:40:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4c593ff4d530b4439a4e538c01f7d7c491944e6a",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 0.10.1",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T18:25:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f1be81df46d968c648669d542f840c9bef518fb6",
          "body": null,
          "is_bot": false,
          "headline": "Add embedded web UI for config editing and live monitoring (#305)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T18:23:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58a753de89fb3b7d2bc42ec3344ede193da21cf0",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 0.10.0",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T14:24:40Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "fcf94083d88f226e0bd4bdae71af993eee1c14d7",
          "body": "… (#308)",
          "is_bot": false,
          "headline": "Support FACEBOOK_USERNAME and FACEBOOK_PASSWORD environment variables…",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T14:22:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "527e04e807cb37c466eb848fe80781083133f434",
          "body": "Replace token-based authentication with OpenID Connect trusted\npublisher. This eliminates the need for PYPI_TOKEN and TEST_PYPI_TOKEN\nsecrets — the id-token: write permission handles auth via OIDC.\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Switch release workflow to PyPI trusted publisher (OIDC) (#307)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T14:14:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "9a9930b340b5d22b06ff80808ad41e8a95600e1e",
          "body": null,
          "is_bot": false,
          "headline": "Add Anthropic/Claude as AI backend provider (#306)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T14:05:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9f4b51862c61e652bf954dadc37f58ba41ae63cd",
          "body": "* feat: add configurable rate limiting framework for notifications\n\nImplement comprehensive rate limiting infrastructure for all notification\ntypes, resolving GitHub issue #235. This adds a flexible, opt-in rate\nlimiting system that prevents API violations while maintaining backward\ncompatibility.\n\n\n[…]\n it).\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Adam Wallis <adam@byte.fit>\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add configurable rate limiting framework for notifications (#301)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-04-12T03:35:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1a6593f2d42f0100cfd9782ad65817c35e223f12",
          "body": "Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Bump version to 0.9.12",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2026-03-26T05:30:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "499b47605c2d769cf27f639c913611eb23ef3027",
          "body": "* Fix 30s timeout delay in get_seller for anonymous mode (#289)\n\nAdd explicit 3s timeout to seller link text_content() call to avoid\nPlaywright's default 30s timeout when seller data is not present\n(e.g. when browsing Facebook Marketplace without logging in).\n\nCo-Authored-By: Claude Opus 4.6 (1M con\n[…]\nxists when\ntriggered by a release creation event.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix 30s timeout delay in get_seller for anonymous mode (#300)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-03-26T05:30:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5f324a2af87a41f822aa940a1284b98a3def0c82",
          "body": null,
          "is_bot": false,
          "headline": "skip security test (#299)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2026-03-23T23:22:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5c4a79e96bbf938a5807cb3755c52256fc38ec77",
          "body": "Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.1 to 7.0.0.\n- [Release notes](https://github.com/actions/upload-artifact/releases)\n- [Commits](https://github.com/actions/upload-artifact/compare/v4.6.1...v7.0.0)\n\n---\nupdated-dependencies:\n- dependency-name: action\n[…]\nirect:production\n  update-type: version-update:semver-major\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump actions/upload-artifact from 4.6.1 to 7.0.0 (#293)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-23T23:04:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2395769b6b4aefd8a139dbe2abf522921cbbe7f6",
          "body": "Updates the requirements on [ruff](https://github.com/astral-sh/ruff) to permit the latest version.\n- [Release notes](https://github.com/astral-sh/ruff/releases)\n- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/astral-sh/ruff/compare/0.9.2...0.15\n[…]\ndency-version: 0.15.7\n  dependency-type: direct:development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update ruff requirement from <0.14.0,>=0.9.2 to >=0.9.2,<0.16.0 (#294)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-23T23:04:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "37f7a953e0360940faa33c204ee6607b16a43b6f",
          "body": "…295)\n\nUpdates the requirements on [typer](https://github.com/fastapi/typer) to permit the latest version.\n- [Release notes](https://github.com/fastapi/typer/releases)\n- [Changelog](https://github.com/fastapi/typer/blob/master/docs/release-notes.md)\n- [Commits](https://github.com/fastapi/typer/compa\n[…]\nuction\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>\nCo-authored-by: Bo <BoPeng@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update typer requirement from <0.18.0,>=0.15.1 to >=0.15.1,<0.25.0 (#…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-23T23:02:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "69344016f1008193023798e5df35981285cf9908",
          "body": "Updates the requirements on [black](https://github.com/psf/black) to permit the latest version.\n- [Release notes](https://github.com/psf/black/releases)\n- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)\n- [Commits](https://github.com/psf/black/compare/24.10.0...26.3.1)\n\n---\nupdated-de\n[…]\ndency-version: 26.3.1\n  dependency-type: direct:development\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update black requirement from <26.0,>=24.10 to >=24.10,<27.0 (#297)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-03-23T23:02:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b0cb9287847552f623a05e0f1cbf3ea4e8969eb5",
          "body": null,
          "is_bot": false,
          "headline": "Specify units on ollama timeout config (#298)",
          "author_name": "Jonathan Owens",
          "author_login": "intjonathan",
          "committed_at": "2026-03-23T22:53:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "020af90fd4df095f644bd653d01ac058d6e385fb",
          "body": null,
          "is_bot": false,
          "headline": "Vehicle description fixes (#290)",
          "author_name": "Jonathan Owens",
          "author_login": "intjonathan",
          "committed_at": "2026-03-21T05:20:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cc84084c0adb75e3ad96906f303688922e420082",
          "body": null,
          "is_bot": false,
          "headline": "Fix minor docs inaccuracies (#288)",
          "author_name": "Jonathan Owens",
          "author_login": "intjonathan",
          "committed_at": "2026-03-21T01:58:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "236a2c719a3c11ef4eb9fad534f6892dea27e266",
          "body": null,
          "is_bot": false,
          "headline": "Allow different browsers",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-11-04T05:16:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e3959a275c2b6d0827f851732f68906f1eac85c9",
          "body": null,
          "is_bot": false,
          "headline": "release ai-marketplace-monitor 0.9.10",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-09-18T04:31:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9669af623c44e71046e069bd04d949eefa60bfb3",
          "body": null,
          "is_bot": false,
          "headline": "check search_city (#264)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2025-09-18T03:54:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "374ac926c84e798dd814b9ba663b8153edca8e7b",
          "body": "Updates the requirements on [ruff](https://github.com/astral-sh/ruff) to permit the latest version.\n- [Release notes](https://github.com/astral-sh/ruff/releases)\n- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/astral-sh/ruff/compare/0.9.2...0.13\n[…]\nndency-version: 0.13.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update ruff requirement from <0.13.0,>=0.9.2 to >=0.9.2,<0.14.0 (#261)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-09-17T13:59:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e878314414af74d6853fb6c25b1445548b21f9dd",
          "body": "…262)\n\nUpdates the requirements on [typer](https://github.com/fastapi/typer) to permit the latest version.\n- [Release notes](https://github.com/fastapi/typer/releases)\n- [Changelog](https://github.com/fastapi/typer/blob/master/docs/release-notes.md)\n- [Commits](https://github.com/fastapi/typer/compa\n[…]\nuction\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>\nCo-authored-by: Bo <BoPeng@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Update typer requirement from <0.17.0,>=0.15.1 to >=0.15.1,<0.18.0 (#…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-09-17T13:59:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9bb9d0b9443ba7be84b0d2ad68f376170fe5c6e4",
          "body": "* Make keyboard monitoring optional (#259)\n\n* release version 0.9.9",
          "is_bot": false,
          "headline": "Make keyboard monitoring optional (#259) (#260)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2025-09-17T13:58:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5cd86e70684baa5cb058aef22fa878ab28cc8f99",
          "body": null,
          "is_bot": false,
          "headline": "automate release process",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-08-10T02:23:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "732bb69db04fc4c3d53d71e6f31a597c86fb0d75",
          "body": null,
          "is_bot": false,
          "headline": "release version 0.9.8",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-08-10T01:45:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47a101305908a4ac6e7c8b6a9f96fac1442e0b60",
          "body": null,
          "is_bot": false,
          "headline": "Update documentation for translation",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-08-10T01:39:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "000e3f403cc4419871237213b3a2ff888724393c",
          "body": null,
          "is_bot": false,
          "headline": "release version 0.9.7",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-08-10T01:28:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb8763226f2ce768ffe201a971d86edfff00259f",
          "body": "* Fix premature keyword filtering in Facebook marketplace scraping\n\nAddresses a critical bug where listings were incorrectly rejected during\nkeyword filtering before their descriptions had been extracted from\nFacebook's detail pages.\n\n## Problem\n\nThe dual-check workflow was failing:\n1. First check_l\n[…]\nedback\n\n- Remove redundant description_available=True parameter (uses default)\n- Move self.logger check to outer if condition to avoid nested checks\n\nThese changes improve code clarity and efficiency.",
          "is_bot": false,
          "headline": "Fix premature keyword filtering in Facebook marketplace scraping (#248)",
          "author_name": "adawalli",
          "author_login": "adawalli",
          "committed_at": "2025-08-10T01:28:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ce75502160d43da21292e9d290dfd0739a5bce4f",
          "body": null,
          "is_bot": false,
          "headline": "fix a link",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-08-08T16:13:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6b691d310f823989b0ee492ba936be7dfaf79260",
          "body": "* update installation instruction\n\n* reneame configuration guide to configuration reference\n\n* update docs",
          "is_bot": false,
          "headline": "Update to docs (#246)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2025-08-08T16:04:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c2be169fc903ee2e51959022c076a3441f087e4",
          "body": "* move docs to readthedocs",
          "is_bot": false,
          "headline": "Read the docs (#245)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2025-08-08T15:34:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07642d8fdbaa85fcc2aca162e96b9c98908791b6",
          "body": null,
          "is_bot": false,
          "headline": "Install instructions for linux (#233)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2025-08-08T14:25:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2295bcc69681fec1094ad9af49c322240afbbcc8",
          "body": "* feat: add comprehensive Telegram notification support\n\nAdd complete Telegram bot integration for AI Marketplace Monitor notifications:\n\n- Implement TelegramNotificationConfig with bot token and chat ID authentication\n- Add MarkdownV2 message formatting with proper escaping for Telegram\n- Implement\n[…]\n logic to\na single line while maintaining identical functionality.\n\n- Use textwrap.wrap() with break_long_words=False\n- Maintains word boundary splitting behavior\n- All existing tests continue to pass",
          "is_bot": false,
          "headline": "feat: add comprehensive Telegram notification support (#231)",
          "author_name": "adawalli",
          "author_login": "adawalli",
          "committed_at": "2025-08-05T00:40:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "941d11c1a570f9f28261096938d0ed173bf5088c",
          "body": "Addresses GitHub issue #240 by adding proper application identification\nwhen using OpenRouter API. This ensures the application appears as\n\"AI Marketplace Monitor\" in OpenRouter's dashboard instead of \"Unknown\"\nand provides a direct link to the GitHub repository.\n\n- Added X-Title header with application name\n- Added HTTP-Referer header with repository URL\n- Follows OpenRouter's recommended identification practices",
          "is_bot": false,
          "headline": "Add OpenRouter user agent identification headers (#241)",
          "author_name": "adawalli",
          "author_login": "adawalli",
          "committed_at": "2025-08-04T01:59:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c8a7d0453daec09ba27682d5628084372a534dbf",
          "body": "Add proper newline spacing before \"AI:\" messages in all notification formats:\n- Plain text: Add \\n before \"AI:\"\n- Markdown: Add \\n before \"**AI**:\"\n- HTML: Add <br> before \"<b>AI</b>:\"\n- Email text: Add \\n before \"AI:\"\n\nThis improves readability by separating AI comments from listing details\nwith appropriate whitespace in all notification channels.",
          "is_bot": false,
          "headline": "Fix newline spacing around AI messages in notifications (#236)",
          "author_name": "adawalli",
          "author_login": "adawalli",
          "committed_at": "2025-08-03T20:11:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ebe1602bc6dffaf832cc8c5f73bc618e541fc87",
          "body": "…n (#229)\n\n- Add monitor_config: dict to key_types dictionary in test_config function\n- Resolves KeyError: 'monitor_config' that was causing 9 test failures\n- All CLI config tests now pass (65 passed, 1 skipped)",
          "is_bot": false,
          "headline": "Fix CLI test failures by adding missing monitor_config type validatio…",
          "author_name": "adawalli",
          "author_login": "adawalli",
          "committed_at": "2025-08-01T02:40:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3c5a4fb427776bdaaf1be596bf60e5eb69922985",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'uv'",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-27T01:44:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5510ca459bc2675fbc8b2f01b7b67c3052ec8927",
          "body": null,
          "is_bot": false,
          "headline": "rotating vpn #157",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-27T01:42:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "978e40e0bbadc15434d8e9ce57bf88a838cdcf40",
          "body": null,
          "is_bot": false,
          "headline": "Release of version 0.9.6",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-27T01:40:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6b6408b02b2ff40b2f829ce294d0dc35b9f64460",
          "body": "* Switch from poetry to uv\n* Suppress an info message (close #204)\n* Fix end of line for markdown files",
          "is_bot": false,
          "headline": "Switch from poetry to uv (#203)",
          "author_name": "Bo",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T04:40:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a153d3fa6278e657ba8665d59f0b424af86331b",
          "body": null,
          "is_bot": false,
          "headline": "revert rotating vpn patch",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T04:26:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "92892ce6c4f9fd3a2ec01e8a1bcb6e3178aa2353",
          "body": null,
          "is_bot": false,
          "headline": "fix tests",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T03:51:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44c415b90aaf2822747a0a36db1e2358c5eb9302",
          "body": null,
          "is_bot": false,
          "headline": "fix tests",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T03:37:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "76721ea45952ad5c76e10b2451cc7d73db38fda6",
          "body": null,
          "is_bot": false,
          "headline": "Fix tests",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T03:26:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0360daa1d423299f81331020ef2bb22bafd92faa",
          "body": null,
          "is_bot": false,
          "headline": "fix mypy",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T03:19:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d90a47ff035d58d22f811ac273c3a8ed30674921",
          "body": null,
          "is_bot": false,
          "headline": "Fix end of line for markdown files",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T03:09:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dc1597990eed0a5e76d9bd486f533b8e817ae721",
          "body": null,
          "is_bot": false,
          "headline": "Suppress an info message (close #204)",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T03:00:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5e27eeaa41454835627d72b30cc1a544646919d8",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'main' into uv",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T02:57:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66228b39529cd46946ecfa8afd00ea1052af38d8",
          "body": null,
          "is_bot": false,
          "headline": "rotating vpn #157",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T02:56:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "80eb8bb86ece0bffd64a36dae2637765427ea153",
          "body": null,
          "is_bot": false,
          "headline": "Fix across-region search",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T02:53:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bc6970fbf57cfa1693c1cd7be8a1c5931e83623d",
          "body": null,
          "is_bot": false,
          "headline": "add sv translation",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-26T02:05:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8103fa4ab2ee63af48c90144a6185907b9f49a00",
          "body": "Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.9.1 to 7.9.2.\n- [Release notes](https://github.com/nedbat/coveragepy/releases)\n- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)\n- [Commits](https://github.com/nedbat/coveragepy/compare/7.9.1...7.9.2)\n\n---\nupdate\n[…]\n-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>\nCo-authored-by: Bo <BoPeng@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump coverage from 7.9.1 to 7.9.2 (#205)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-07-10T05:27:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "253ff97a4560fb9277c2a3b569dc58aece2f872f",
          "body": "Bumps [openai](https://github.com/openai/openai-python) from 1.91.0 to 1.93.3.\n- [Release notes](https://github.com/openai/openai-python/releases)\n- [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/openai/openai-python/compare/v1.91.0...v1.93\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump openai from 1.91.0 to 1.93.3 (#208)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-07-10T05:27:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1c8dda28ff575e822eb27cac44763073c90f0dbc",
          "body": "Bumps [safety](https://github.com/pyupio/safety) from 3.5.2 to 3.6.0.\n- [Release notes](https://github.com/pyupio/safety/releases)\n- [Changelog](https://github.com/pyupio/safety/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/pyupio/safety/compare/3.5.2...3.6.0)\n\n---\nupdated-dependencies:\n- d\n[…]\nrect:development\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump safety from 3.5.2 to 3.6.0 (#209)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-07-10T05:26:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "69f4eaa0fdf8d11ff40904bd83d2c7ae82b6f640",
          "body": null,
          "is_bot": false,
          "headline": "add README for migration",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-06T04:29:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "08d8071c586cb5f53aa587173191a0bf0d5b62eb",
          "body": null,
          "is_bot": false,
          "headline": "remove more poetry stuf",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-06T04:11:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5a7fde85b76915b0cfff78390173a6e371961d78",
          "body": null,
          "is_bot": false,
          "headline": "More changes",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-06T03:40:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fde09092afb50295d3d3bfccec5888cdbafd64f1",
          "body": null,
          "is_bot": false,
          "headline": "Switch from poetry to uv",
          "author_name": "Bo Peng",
          "author_login": "BoPeng",
          "committed_at": "2025-07-06T03:31:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dcc3a97be51c0641df55a7fab3a53144809f24a9",
          "body": "Co-authored-by: Bo <BoPeng@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix removal of cookie prompt (#201)",
          "author_name": "Brad",
          "author_login": "Bradzie",
          "committed_at": "2025-07-05T20:20:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e4662be88ad347b7ec4358d4fd6dfac012bba177",
          "body": "Bumps [playwright](https://github.com/microsoft/playwright-python) from 1.52.0 to 1.53.0.\n- [Release notes](https://github.com/microsoft/playwright-python/releases)\n- [Commits](https://github.com/microsoft/playwright-python/compare/v1.52.0...v1.53.0)\n\n---\nupdated-dependencies:\n- dependency-name: pla\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump playwright from 1.52.0 to 1.53.0 (#194)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-07-04T23:49:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c5013c1f1f59aa3802d92ac9d1af0529cf7a5c52",
          "body": "Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 6.1.1 to 6.2.1.\n- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)\n- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v6.1.1...v6.2.1)\n\n---\nupdated-dependencies:\n- dependency-name: pytest-cov\n \n[…]\nrect:development\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump pytest-cov from 6.1.1 to 6.2.1 (#192)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-26T02:48:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba7fad4da2620c78cdfdc75a7872de20e846e5c7",
          "body": "Bumps [mypy](https://github.com/python/mypy) from 1.15.0 to 1.16.1.\n- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/python/mypy/compare/v1.15.0...v1.16.1)\n\n---\nupdated-dependencies:\n- dependency-name: mypy\n  dependency-version: 1.16.1\n  dependenc\n[…]\nrect:development\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump mypy from 1.15.0 to 1.16.1 (#188)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-26T02:47:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e16d6059a6ed75ef3a2603bbe74b99aa4155adba",
          "body": "Bumps [safety](https://github.com/pyupio/safety) from 3.3.1 to 3.5.2.\n- [Release notes](https://github.com/pyupio/safety/releases)\n- [Changelog](https://github.com/pyupio/safety/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/pyupio/safety/compare/3.3.1...3.5.2)\n\n---\nupdated-dependencies:\n- d\n[…]\nrect:development\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump safety from 3.3.1 to 3.5.2 (#190)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-26T02:47:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1304800a5e9112a616effc3a8a56276ac2a0435f",
          "body": "Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.8.2 to 7.9.1.\n- [Release notes](https://github.com/nedbat/coveragepy/releases)\n- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)\n- [Commits](https://github.com/nedbat/coveragepy/compare/7.8.2...7.9.1)\n\n---\nupdate\n[…]\nrect:development\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump coverage from 7.8.2 to 7.9.1 (#191)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-26T02:47:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0c6f22fd9c0f156f95a90c7eb832fa10667f2ce8",
          "body": "Bumps [openai](https://github.com/openai/openai-python) from 1.88.0 to 1.91.0.\n- [Release notes](https://github.com/openai/openai-python/releases)\n- [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/openai/openai-python/compare/v1.88.0...v1.91\n[…]\nirect:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump openai from 1.88.0 to 1.91.0 (#193)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-26T02:47:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd51ccf4242459a28246c6830c94e2ab266302ff",
          "body": "Bumps [currencyconverter](https://github.com/alexprengere/currencyconverter) from 0.18.6 to 0.18.7.\n- [Commits](https://github.com/alexprengere/currencyconverter/compare/v0.18.6...v0.18.7)\n\n---\nupdated-dependencies:\n- dependency-name: currencyconverter\n  dependency-version: 0.18.7\n  dependency-type:\n[…]\nirect:production\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump currencyconverter from 0.18.6 to 0.18.7 (#179)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-22T21:35:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "76155905f87bdc00ab28aff61fbdf7208e98e210",
          "body": "Bumps [requests](https://github.com/psf/requests) from 2.32.3 to 2.32.4.\n- [Release notes](https://github.com/psf/requests/releases)\n- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)\n- [Commits](https://github.com/psf/requests/compare/v2.32.3...v2.32.4)\n\n---\nupdated-dependencies:\n-\n[…]\nirect:production\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "Bump requests from 2.32.3 to 2.32.4 (#180)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2025-06-22T21:35:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 4,
      "commits_last_year": 69,
      "latest_release_at": "2026-07-17T05:27:37Z",
      "latest_release_tag": "v0.10.2",
      "releases_from_tags": false,
      "days_since_last_push": 2,
      "active_weeks_last_year": 11,
      "days_since_latest_release": 10,
      "mean_days_between_releases": 37.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 100,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "ai-marketplace-monitor",
          "exists": true,
          "license": null,
          "keywords": [
            "ai-marketplace-monitor",
            "Development Status :: 2 - Pre-Alpha",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: GNU Affero General Public License v3",
            "Natural Language :: English",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/ai-marketplace-monitor/",
          "is_deprecated": false,
          "latest_version": "0.10.2",
          "repository_url": "https://github.com/BoPeng/ai-marketplace-monitor",
          "versions_count": 22,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2025-01-21T00:35:07.840175Z",
          "latest_published_at": "2026-07-17T05:28:05.086000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 10
        }
      ]
    },
    "popularity": {
      "forks": 71,
      "stars": 280,
      "watchers": 10,
      "fork_history": {
        "days": [
          {
            "date": "2025-02-25",
            "count": 1
          },
          {
            "date": "2025-03-02",
            "count": 1
          },
          {
            "date": "2025-03-05",
            "count": 1
          },
          {
            "date": "2025-03-20",
            "count": 1
          },
          {
            "date": "2025-05-14",
            "count": 1
          },
          {
            "date": "2025-05-21",
            "count": 1
          },
          {
            "date": "2025-05-24",
            "count": 1
          },
          {
            "date": "2025-06-02",
            "count": 1
          },
          {
            "date": "2025-06-14",
            "count": 1
          },
          {
            "date": "2025-07-04",
            "count": 1
          },
          {
            "date": "2025-07-25",
            "count": 1
          },
          {
            "date": "2025-09-07",
            "count": 1
          },
          {
            "date": "2025-09-09",
            "count": 1
          },
          {
            "date": "2025-09-19",
            "count": 1
          },
          {
            "date": "2025-09-22",
            "count": 1
          },
          {
            "date": "2025-09-24",
            "count": 1
          },
          {
            "date": "2025-10-14",
            "count": 1
          },
          {
            "date": "2025-10-28",
            "count": 1
          },
          {
            "date": "2025-11-20",
            "count": 2
          },
          {
            "date": "2025-12-16",
            "count": 1
          },
          {
            "date": "2025-12-23",
            "count": 2
          },
          {
            "date": "2025-12-26",
            "count": 1
          },
          {
            "date": "2025-12-27",
            "count": 1
          },
          {
            "date": "2026-01-04",
            "count": 1
          },
          {
            "date": "2026-01-06",
            "count": 1
          },
          {
            "date": "2026-01-07",
            "count": 1
          },
          {
            "date": "2026-01-09",
            "count": 1
          },
          {
            "date": "2026-02-17",
            "count": 1
          },
          {
            "date": "2026-02-27",
            "count": 1
          },
          {
            "date": "2026-03-01",
            "count": 1
          },
          {
            "date": "2026-03-07",
            "count": 1
          },
          {
            "date": "2026-03-12",
            "count": 1
          },
          {
            "date": "2026-03-13",
            "count": 1
          },
          {
            "date": "2026-03-15",
            "count": 1
          },
          {
            "date": "2026-03-17",
            "count": 2
          },
          {
            "date": "2026-03-20",
            "count": 1
          },
          {
            "date": "2026-03-30",
            "count": 1
          },
          {
            "date": "2026-04-01",
            "count": 1
          },
          {
            "date": "2026-04-12",
            "count": 1
          },
          {
            "date": "2026-04-17",
            "count": 1
          },
          {
            "date": "2026-04-18",
            "count": 1
          },
          {
            "date": "2026-05-01",
            "count": 1
          },
          {
            "date": "2026-05-02",
            "count": 2
          },
          {
            "date": "2026-05-21",
            "count": 1
          },
          {
            "date": "2026-05-30",
            "count": 1
          },
          {
            "date": "2026-06-03",
            "count": 1
          },
          {
            "date": "2026-06-05",
            "count": 1
          },
          {
            "date": "2026-06-07",
            "count": 1
          },
          {
            "date": "2026-06-15",
            "count": 1
          },
          {
            "date": "2026-06-19",
            "count": 1
          },
          {
            "date": "2026-06-22",
            "count": 1
          },
          {
            "date": "2026-06-27",
            "count": 1
          },
          {
            "date": "2026-06-28",
            "count": 1
          },
          {
            "date": "2026-07-01",
            "count": 1
          },
          {
            "date": "2026-07-02",
            "count": 1
          },
          {
            "date": "2026-07-05",
            "count": 1
          },
          {
            "date": "2026-07-07",
            "count": 1
          },
          {
            "date": "2026-07-08",
            "count": 1
          },
          {
            "date": "2026-07-10",
            "count": 1
          },
          {
            "date": "2026-07-14",
            "count": 2
          },
          {
            "date": "2026-07-15",
            "count": 1
          },
          {
            "date": "2026-07-18",
            "count": 1
          },
          {
            "date": "2026-07-22",
            "count": 2
          },
          {
            "date": "2026-07-24",
            "count": 1
          },
          {
            "date": "2026-07-25",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 71,
        "total_forks": 71
      },
      "star_history": null,
      "open_issues_and_prs": 16
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "noxfile.py"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "src/ai_marketplace_monitor/py.typed"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 67138,
      "source_files_sampled": 45,
      "oversized_source_files": 1,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "docs/requirements.txt",
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [
          {
            "name": "diskcache",
            "direct": true,
            "version": "5.6.3",
            "severity": "moderate",
            "ecosystem": "pypi",
            "cvss_score": null,
            "advisory_ids": [
              "GHSA-w8v5-vhqr-4h9v",
              "PYSEC-2026-2447"
            ],
            "fixed_version": null,
            "advisory_count": 2,
            "oldest_advisory_days": 165
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "moderate": 1
        },
        "advisory_count": 2,
        "affected_count": 1,
        "assessed_count": 95,
        "malicious_count": 0,
        "assessed_package": "pypi:ai-marketplace-monitor@0.10.2",
        "unassessed_count": 0,
        "direct_affected_count": 1
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "typer",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.15.1,<0.28.0"
        },
        {
          "name": "playwright",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.41.0"
        },
        {
          "name": "rich",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=13.7.0"
        },
        {
          "name": "pushbullet.py",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.12.0"
        },
        {
          "name": "diskcache",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=5.6.3"
        },
        {
          "name": "watchdog",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=4.0.0"
        },
        {
          "name": "openai",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.24.0"
        },
        {
          "name": "anthropic",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.39.0"
        },
        {
          "name": "parsedatetime",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.5"
        },
        {
          "name": "humanize",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=4.0.0"
        },
        {
          "name": "schedule",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.2.2"
        },
        {
          "name": "inflect",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=7.0.0"
        },
        {
          "name": "pillow",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=10.0.0"
        },
        {
          "name": "jinja2",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.0.0"
        },
        {
          "name": "pyparsing",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.1.0"
        },
        {
          "name": "requests",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.30.0"
        },
        {
          "name": "CurrencyConverter",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.18.0"
        },
        {
          "name": "tomli",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "==2.2.1"
        },
        {
          "name": "safety",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.5.2"
        },
        {
          "name": "pip-audit",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.9.0"
        },
        {
          "name": "python-telegram-bot",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=22.3"
        },
        {
          "name": "fastapi",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.110"
        },
        {
          "name": "uvicorn",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.27"
        },
        {
          "name": "itsdangerous",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=2.1"
        },
        {
          "name": "bcrypt",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=4.0"
        },
        {
          "name": "python-multipart",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.0.9"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "anthropic",
            "direct": true,
            "version": "0.94.0",
            "ecosystem": "pypi"
          },
          {
            "name": "bcrypt",
            "direct": true,
            "version": "5.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "currencyconverter",
            "direct": true,
            "version": "0.18.9",
            "ecosystem": "pypi"
          },
          {
            "name": "diskcache",
            "direct": true,
            "version": "5.6.3",
            "ecosystem": "pypi"
          },
          {
            "name": "fastapi",
            "direct": true,
            "version": "0.135.3",
            "ecosystem": "pypi"
          },
          {
            "name": "humanize",
            "direct": true,
            "version": "4.12.3",
            "ecosystem": "pypi"
          },
          {
            "name": "inflect",
            "direct": true,
            "version": "7.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "itsdangerous",
            "direct": true,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": true,
            "version": "3.1.6",
            "ecosystem": "pypi"
          },
          {
            "name": "openai",
            "direct": true,
            "version": "1.98.0",
            "ecosystem": "pypi"
          },
          {
            "name": "parsedatetime",
            "direct": true,
            "version": "2.6",
            "ecosystem": "pypi"
          },
          {
            "name": "pillow",
            "direct": true,
            "version": "11.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pip-audit",
            "direct": true,
            "version": "2.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "playwright",
            "direct": true,
            "version": "1.54.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pushbullet-py",
            "direct": true,
            "version": "0.12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyparsing",
            "direct": true,
            "version": "3.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "python-multipart",
            "direct": true,
            "version": "0.0.26",
            "ecosystem": "pypi"
          },
          {
            "name": "python-telegram-bot",
            "direct": true,
            "version": "22.3",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": true,
            "version": "2.32.4",
            "ecosystem": "pypi"
          },
          {
            "name": "rich",
            "direct": true,
            "version": "14.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "safety",
            "direct": true,
            "version": "3.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "schedule",
            "direct": true,
            "version": "1.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli",
            "direct": true,
            "version": "2.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "typer",
            "direct": true,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "uvicorn",
            "direct": true,
            "version": "0.44.0",
            "ecosystem": "pypi"
          },
          {
            "name": "watchdog",
            "direct": true,
            "version": "6.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "accessible-pygments",
            "direct": false,
            "version": "0.0.5",
            "ecosystem": "pypi"
          },
          {
            "name": "ai-marketplace-monitor",
            "direct": false,
            "version": "0.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "alabaster",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "annotated-doc",
            "direct": false,
            "version": "0.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "annotated-types",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "anyio",
            "direct": false,
            "version": "4.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "authlib",
            "direct": false,
            "version": "1.6.1",
            "ecosystem": "pypi"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "backports-asyncio-runner",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "backports-datetime-fromisoformat",
            "direct": false,
            "version": "2.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "backports-tarfile",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "beautifulsoup4",
            "direct": false,
            "version": "4.13.4",
            "ecosystem": "pypi"
          },
          {
            "name": "black",
            "direct": false,
            "version": "25.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "boolean-py",
            "direct": false,
            "version": "5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "build",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "bump2version",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "cachecontrol",
            "direct": false,
            "version": "0.14.3",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2025.7.14",
            "ecosystem": "pypi"
          },
          {
            "name": "cffi",
            "direct": false,
            "version": "1.17.1",
            "ecosystem": "pypi"
          },
          {
            "name": "cfgv",
            "direct": false,
            "version": "3.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "click",
            "direct": false,
            "version": "8.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "coverage",
            "direct": false,
            "version": "7.10.1",
            "ecosystem": "pypi"
          },
          {
            "name": "cryptography",
            "direct": false,
            "version": "45.0.5",
            "ecosystem": "pypi"
          },
          {
            "name": "cyclonedx-python-lib",
            "direct": false,
            "version": "9.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "defusedxml",
            "direct": false,
            "version": "0.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "distlib",
            "direct": false,
            "version": "0.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "distro",
            "direct": false,
            "version": "1.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "docstring-parser",
            "direct": false,
            "version": "0.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "docutils",
            "direct": false,
            "version": "0.21.2",
            "ecosystem": "pypi"
          },
          {
            "name": "dparse",
            "direct": false,
            "version": "0.6.4",
            "ecosystem": "pypi"
          },
          {
            "name": "evdev",
            "direct": false,
            "version": "1.9.2",
            "ecosystem": "pypi"
          },
          {
            "name": "exceptiongroup",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "filelock",
            "direct": false,
            "version": "3.16.1",
            "ecosystem": "pypi"
          },
          {
            "name": "furo",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "furo",
            "direct": false,
            "version": "2025.7.19",
            "ecosystem": "pypi"
          },
          {
            "name": "greenlet",
            "direct": false,
            "version": "3.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "h11",
            "direct": false,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "httpcore",
            "direct": false,
            "version": "1.0.9",
            "ecosystem": "pypi"
          },
          {
            "name": "httptools",
            "direct": false,
            "version": "0.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "httpx",
            "direct": false,
            "version": "0.28.1",
            "ecosystem": "pypi"
          },
          {
            "name": "id",
            "direct": false,
            "version": "1.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "identify",
            "direct": false,
            "version": "2.6.12",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.10",
            "ecosystem": "pypi"
          },
          {
            "name": "imagesize",
            "direct": false,
            "version": "1.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "importlib-metadata",
            "direct": false,
            "version": "8.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "iniconfig",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "invoke",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "isort",
            "direct": false,
            "version": "6.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jaraco-classes",
            "direct": false,
            "version": "3.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jaraco-context",
            "direct": false,
            "version": "6.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jaraco-functools",
            "direct": false,
            "version": "4.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jeepney",
            "direct": false,
            "version": "0.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jiter",
            "direct": false,
            "version": "0.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "joblib",
            "direct": false,
            "version": "1.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "keyring",
            "direct": false,
            "version": "25.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "license-expression",
            "direct": false,
            "version": "30.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "linkify-it-py",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "linkify-it-py",
            "direct": false,
            "version": "2.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown-it-py",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "marshmallow",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mdit-py-plugins",
            "direct": false,
            "version": "0.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mdurl",
            "direct": false,
            "version": "0.1.2",
            "ecosystem": "pypi"
          },
          {
            "name": "more-itertools",
            "direct": false,
            "version": "10.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "msgpack",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy",
            "direct": false,
            "version": "1.17.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy-extensions",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "myst-parser",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "myst-parser",
            "direct": false,
            "version": "4.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "nh3",
            "direct": false,
            "version": "0.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "nltk",
            "direct": false,
            "version": "3.9.1",
            "ecosystem": "pypi"
          },
          {
            "name": "nodeenv",
            "direct": false,
            "version": "1.9.1",
            "ecosystem": "pypi"
          },
          {
            "name": "packageurl-python",
            "direct": false,
            "version": "0.17.2",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "25.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pathspec",
            "direct": false,
            "version": "0.12.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pip",
            "direct": false,
            "version": "25.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pip-api",
            "direct": false,
            "version": "0.0.34",
            "ecosystem": "pypi"
          },
          {
            "name": "pip-requirements-parser",
            "direct": false,
            "version": "32.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "platformdirs",
            "direct": false,
            "version": "4.3.8",
            "ecosystem": "pypi"
          },
          {
            "name": "pluggy",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pre-commit",
            "direct": false,
            "version": "4.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "psutil",
            "direct": false,
            "version": "6.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "py-serializable",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pycparser",
            "direct": false,
            "version": "2.22",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic",
            "direct": false,
            "version": "2.9.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic-core",
            "direct": false,
            "version": "2.23.4",
            "ecosystem": "pypi"
          },
          {
            "name": "pyee",
            "direct": false,
            "version": "13.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.19.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pynput",
            "direct": false,
            "version": "1.8.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-core",
            "direct": false,
            "version": "11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-applicationservices",
            "direct": false,
            "version": "11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-cocoa",
            "direct": false,
            "version": "11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-coretext",
            "direct": false,
            "version": "11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyobjc-framework-quartz",
            "direct": false,
            "version": "11.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pyproject-hooks",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "8.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-asyncio",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-base-url",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-cov",
            "direct": false,
            "version": "6.2.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-playwright",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dotenv",
            "direct": false,
            "version": "1.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "python-magic",
            "direct": false,
            "version": "0.4.27",
            "ecosystem": "pypi"
          },
          {
            "name": "python-slugify",
            "direct": false,
            "version": "8.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "python-xlib",
            "direct": false,
            "version": "0.33",
            "ecosystem": "pypi"
          },
          {
            "name": "pywin32-ctypes",
            "direct": false,
            "version": "0.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "readme-renderer",
            "direct": false,
            "version": "44.0",
            "ecosystem": "pypi"
          },
          {
            "name": "regex",
            "direct": false,
            "version": "2025.7.34",
            "ecosystem": "pypi"
          },
          {
            "name": "requests-toolbelt",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "rfc3986",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "roman-numerals-py",
            "direct": false,
            "version": "3.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ruamel-yaml",
            "direct": false,
            "version": "0.18.14",
            "ecosystem": "pypi"
          },
          {
            "name": "ruamel-yaml-clib",
            "direct": false,
            "version": "0.2.12",
            "ecosystem": "pypi"
          },
          {
            "name": "ruff",
            "direct": false,
            "version": "0.12.7",
            "ecosystem": "pypi"
          },
          {
            "name": "safety-schemas",
            "direct": false,
            "version": "0.0.14",
            "ecosystem": "pypi"
          },
          {
            "name": "secretstorage",
            "direct": false,
            "version": "3.3.3",
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": false,
            "version": "80.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "shellingham",
            "direct": false,
            "version": "1.5.4",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sniffio",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "snowballstemmer",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sortedcontainers",
            "direct": false,
            "version": "2.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "soupsieve",
            "direct": false,
            "version": "2.7",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx",
            "direct": false,
            "version": "8.1.3",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx",
            "direct": false,
            "version": "8.2.3",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-basic-ng",
            "direct": false,
            "version": "1.0.0b2",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-copybutton",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "sphinx-copybutton",
            "direct": false,
            "version": "0.5.2",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-applehelp",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-devhelp",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-htmlhelp",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-jsmath",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-qthelp",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxcontrib-serializinghtml",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxext-opengraph",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "sphinxext-opengraph",
            "direct": false,
            "version": "0.12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "starlette",
            "direct": false,
            "version": "1.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tenacity",
            "direct": false,
            "version": "9.1.2",
            "ecosystem": "pypi"
          },
          {
            "name": "text-unidecode",
            "direct": false,
            "version": "1.3",
            "ecosystem": "pypi"
          },
          {
            "name": "toml",
            "direct": false,
            "version": "0.10.2",
            "ecosystem": "pypi"
          },
          {
            "name": "tomlkit",
            "direct": false,
            "version": "0.13.3",
            "ecosystem": "pypi"
          },
          {
            "name": "tqdm",
            "direct": false,
            "version": "4.67.1",
            "ecosystem": "pypi"
          },
          {
            "name": "twine",
            "direct": false,
            "version": "6.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "typeguard",
            "direct": false,
            "version": "4.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.14.1",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-inspection",
            "direct": false,
            "version": "0.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "uc-micro-py",
            "direct": false,
            "version": "1.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "uvloop",
            "direct": false,
            "version": "0.22.1",
            "ecosystem": "pypi"
          },
          {
            "name": "virtualenv",
            "direct": false,
            "version": "20.32.0",
            "ecosystem": "pypi"
          },
          {
            "name": "watchfiles",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "websocket-client",
            "direct": false,
            "version": "1.8.0",
            "ecosystem": "pypi"
          },
          {
            "name": "websockets",
            "direct": false,
            "version": "16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "xdoctest",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "zipp",
            "direct": false,
            "version": "3.23.0",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 184,
        "direct_count": 26,
        "indirect_count": 158
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 5,
        "merged_prs": 154,
        "open_issues": 11,
        "closed_ratio": 0.859,
        "closed_issues": 67,
        "closed_unmerged_prs": 113
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "BoPeng",
          "commits": 69,
          "avatar_url": "https://avatars.githubusercontent.com/u/9889312?v=4"
        },
        {
          "type": "User",
          "login": "adawalli",
          "commits": 5,
          "avatar_url": "https://avatars.githubusercontent.com/u/14079121?v=4"
        },
        {
          "type": "User",
          "login": "intjonathan",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/518164?v=4"
        },
        {
          "type": "User",
          "login": "BlackIsBlack",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/39253172?v=4"
        },
        {
          "type": "User",
          "login": "Bradzie",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/70105933?v=4"
        },
        {
          "type": "User",
          "login": "josharmour",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/1240306?v=4"
        },
        {
          "type": "User",
          "login": "spawnpoint",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/14818915?v=4"
        }
      ],
      "contributors_sampled": 7,
      "top_contributor_share": 0.841
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "close-stale-issue.yml",
        "codeql-analysis.yml",
        "docker.yml",
        "pre-commit-autoupdate.yml",
        "release.yml",
        "tests.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": true
    },
    "security_signals": {
      "lockfiles": [
        "uv.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 9,
            "reason": "binaries present in source code",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 4,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 8,
            "reason": "19 out of 22 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 3/8 approved changesets -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "29 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 9,
            "reason": "SAST tool detected but not run on all commits",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 4,
            "reason": "security policy file 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": 0,
            "reason": "79 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "16394b3e2a8c232f6d78a942fb85237f4e193a85",
        "ran_at": "2026-07-27T11:15:15Z",
        "aggregate_score": 5.5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": true,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-27T09:55:19Z",
      "oldest_open_prs": [
        {
          "number": 343,
          "created_at": "2026-07-17T15:52:52Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 344,
          "created_at": "2026-07-17T15:53:00Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 347,
          "created_at": "2026-07-20T15:53:33Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 348,
          "created_at": "2026-07-20T15:53:35Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 350,
          "created_at": "2026-07-24T15:53:32Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-17T05:23:51Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 18,
          "created_at": "2025-01-29T13:56:17Z",
          "last_comment_at": "2026-05-25T23:30:55Z",
          "last_comment_author": "Geonode-JP"
        },
        {
          "number": 29,
          "created_at": "2025-02-02T20:19:35Z",
          "last_comment_at": "2025-09-11T15:33:03Z",
          "last_comment_author": "benthamite"
        },
        {
          "number": 157,
          "created_at": "2025-05-19T15:36:45Z",
          "last_comment_at": "2025-05-31T22:31:53Z",
          "last_comment_author": "BoPeng"
        },
        {
          "number": 166,
          "created_at": "2025-05-25T22:52:30Z",
          "last_comment_at": "2026-07-26T20:46:39Z",
          "last_comment_author": "crawlbench"
        },
        {
          "number": 168,
          "created_at": "2025-05-27T21:40:53Z",
          "last_comment_at": "2025-05-29T02:29:41Z",
          "last_comment_author": "BoPeng"
        },
        {
          "number": 187,
          "created_at": "2025-06-23T01:24:00Z",
          "last_comment_at": "2025-08-06T00:22:59Z",
          "last_comment_author": "adawalli"
        },
        {
          "number": 225,
          "created_at": "2025-07-28T00:51:51Z",
          "last_comment_at": "2026-07-26T20:46:38Z",
          "last_comment_author": "crawlbench"
        },
        {
          "number": 234,
          "created_at": "2025-08-03T17:45:18Z",
          "last_comment_at": "2026-07-26T20:46:38Z",
          "last_comment_author": "crawlbench"
        },
        {
          "number": 257,
          "created_at": "2025-09-06T08:28:52Z",
          "last_comment_at": "2025-09-09T02:36:00Z",
          "last_comment_author": "BoPeng"
        },
        {
          "number": 346,
          "created_at": "2026-07-20T07:12:24Z",
          "last_comment_at": "2026-07-26T20:47:39Z",
          "last_comment_author": "crawlbench"
        },
        {
          "number": 349,
          "created_at": "2026-07-21T12:06:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/BoPeng/ai-marketplace-monitor",
    "host": "github.com",
    "name": "ai-marketplace-monitor",
    "owner": "BoPeng"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 73,
      "inputs": {
        "security": 62,
        "vitality": 82,
        "community": 75,
        "governance": 58,
        "engineering": 90
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 82,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "commits_last_year": 69,
              "human_commit_share": 0.69,
              "days_since_last_push": 2,
              "active_weeks_last_year": 11
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "11/52 weeks with commits",
                "points": 7.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "69 commits in the last year",
                "points": 16.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 69
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "29 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "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": 100,
            "inputs": {
              "releases_count": 4,
              "latest_release_tag": "v0.10.2",
              "releases_from_tags": false,
              "days_since_latest_release": 10,
              "mean_days_between_releases": 37.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "4 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 10 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~37.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 37.7
                    }
                  }
                ],
                "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": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 10,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 10 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "good",
        "name": "Community & Adoption",
        "value": 75,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "forks": 71,
              "stars": 280,
              "watchers": 10,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "280 stars",
                "points": 39.7,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 280
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "71 forks",
                "points": 15.4,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 71
                    }
                  }
                ],
                "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": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 92,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (AGPL-3.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "AGPL-3.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "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": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 58,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 25,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 7,
              "top_contributor_share": 0.841
            },
            "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 84% of commits",
                "points": 3.6,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 84
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "7 contributors",
                "points": 9.5,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "merged_prs": 154,
              "open_issues": 11,
              "closed_issues": 67,
              "issue_closed_ratio": 0.859,
              "closed_unmerged_prs": 113
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "86% of issues closed",
                "points": 40.2,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 86
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "154/267 decided PRs merged",
                "points": 22.1,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 154,
                      "decided": 267
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 3/8 approved changesets -- score normalized to 3",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 56,
            "inputs": {
              "followers": 61,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "BoPeng",
              "public_repos": 22,
              "account_age_days": 4265
            },
            "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": "61 followers of BoPeng",
                "points": 12.9,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 61,
                      "login": "BoPeng"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "22 public repos, account ~11 yr old",
                "points": 21.9,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 22
                    }
                  },
                  {
                    "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": [
                "ai-marketplace-monitor"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 10
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 10 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 10
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "22 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 22
                    }
                  }
                ],
                "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": "excellent",
        "name": "Engineering Quality",
        "value": 90,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "excellent",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": true
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "6 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 16,
                "status": "met",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 9.6,
                "status": "met",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "19 out of 22 merged PRs checked by a CI test -- score normalized to 8",
                "points": 16,
                "status": "partial",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://ai-marketplace-monitor.readthedocs.io/en/latest/",
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://ai-marketplace-monitor.readthedocs.io/en/latest/",
                "points": 15,
                "status": "met",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 62,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 55,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 5.5
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "binaries present in source code",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection is not maximal on development and all release branches",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "19 out of 22 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 3/8 approved changesets -- score normalized to 3",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "29 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool detected but not run on all commits",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 2,
                "status": "partial",
                "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": "79 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Matched the pypi:ai-marketplace-monitor@0.10.2 runtime dependency closure — what installing the published package pulls in — 95 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "pypi:ai-marketplace-monitor@0.10.2",
                  "assessed": 95
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 89,
            "inputs": {
              "source": "osv",
              "advisories": 2,
              "affected_packages": 1,
              "assessed_packages": 95,
              "unassessed_packages": 0,
              "affected_by_severity": "moderate 1",
              "direct_affected_packages": 1
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "1 affected: diskcache 5.6.3 (moderate)",
                "points": 26.6,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "diskcache 5.6.3 (moderate)"
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "1 advisory-carrying package(s) unaddressed past 90 days; oldest published 165 days ago",
                "points": 37.2,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_stale",
                    "params": {
                      "days": 90,
                      "count": 1,
                      "oldest": 165
                    }
                  }
                ],
                "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": 95,
              "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": 4
            },
            "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": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 32,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.609,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "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": "42 of 69 human commits state their intent (structured subject or explanatory body)",
                "points": 32.5,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 42,
                      "sampled": 69
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "excellent",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [
                "noxfile.py"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "src/ai_marketplace_monitor/py.typed"
              ],
              "agent_commit_share": 0.12,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.31
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "noxfile.py",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "noxfile.py"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 11,
                "status": "met",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "src/ai_marketplace_monitor/py.typed",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "src/ai_marketplace_monitor/py.typed"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "12 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 12,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "31 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 31,
                      "sampled": 100
                    }
                  }
                ],
                "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": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "primary_language": "HTML",
              "largest_source_bytes": 67138,
              "source_files_sampled": 45,
              "oversized_source_files": 1
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "HTML with type-check config (src/ai_marketplace_monitor/py.typed)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "src/ai_marketplace_monitor/py.typed",
                      "language": "HTML"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "1/45 source files over 60KB",
                "points": 53.8,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 45,
                      "oversized": 1
                    }
                  }
                ],
                "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"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T11:15:35.996153Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/b/BoPeng/ai-marketplace-monitor.svg",
  "full_name": "BoPeng/ai-marketplace-monitor",
  "license_state": "standard",
  "license_spdx": "AGPL-3.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 statisticsPyPI.