Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-24 15:18 UTC

deafdudecomputers / PalworldSaveTools

PalworldSaveTools - A comprehensive toolkit designed to fix, transfer, edit, and manage your Palworld save files with ease.

Python · C · C++MIT★ 597 stars⑂ 58 forkssince Sep 2024View on GitHub ↗

deafdudecomputers/PalworldSaveTools holds a health index of 54 out of 100, placing it in the Moderate band. It scores highest on Vitality (75/100) and lowest on Security (35/100). It was last updated today. A single contributor accounts for most of its recent work.

54
overall / 100
Moderate

Software health index

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

54
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

PylarPersonal account
17 followers7 public repossince Mar 2024

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

Metrics by category

Vitality

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

75Good · 22% of overall
How it's scored
36/36Push recency — last push 0 days ago
1.4/36Commit cadence — 2/52 weeks with commits
18/18Commit volume — 225 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year225
human_commit_share1
days_since_last_push0
active_weeks_last_year2
How it's scored
27/27Ships releases — 100 releases published
36/36Release recency — latest release 1 days ago
27/27Release cadence — a release every ~0.7 days
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Inputs used
releases_count100
latest_release_tagv2.2.1
releases_from_tagsno
days_since_latest_release1
mean_days_between_releases0.7

Community & Adoption

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

57Moderate · 18% of overall
How it's scored
45/60Stars — 597 stars
14.6/25Forks — 58 forks
4.7/15Watchers — 8 watchers
Inputs used
forks58
stars597
watchers8
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
22.5/22.5License — recognized license (MIT)
0/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
0/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno

Sustainability & Governance

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

39At risk · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
1.6/22.5Commit distribution — top contributor authored 93% of commits
6.8/13.5Contributor breadth — 5 contributors
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Inputs used
bus_factor1
contributors_sampled5
top_contributor_share0.93
How it's scored
46.2/46.8Issue resolution — 99% of issues closed
20.3/38.3PR acceptance — 17/32 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Inputs used
merged_prs17
open_issues2
closed_issues188
issue_closed_ratio0.989
closed_unmerged_prs15
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
9/25Owner reach — 17 followers of deafdudecomputers
11.2/25Track record — 7 public repos, account ~2 yr old
Inputs used
followers17
owner_typeUser
is_verified
owner_logindeafdudecomputers
public_repos7
account_age_days851
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.

Engineering Quality

Are baseline engineering and documentation practices in place?

62Moderate · 20% of overall
How it's scored
24/24CI workflows — 8 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — no data
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configno
has_precommit_configno
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.

Documentation

65Moderate
How it's scored
30/30README
0/25Documentation directory
15/15Documentation / homepage site — https://discord.gg/sYcZwcT4cT
10/10Repository description
0/10Topics
10/10Wiki
Inputs used
topics
has_wikiyes
homepagehttps://discord.gg/sYcZwcT4cT
has_readmeyes
has_docs_dirno
has_descriptionyes

Security

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

35At risk · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — no data
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — no data
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
6.8/7.5Vulnerabilities — 1 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate3.5
Excluded from scoring (no data or not applicable): ci_tests, packaging. Remaining weights renormalized.

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.

49At risk · 0% of overall
How it's scored
45/45Agent instructions — AGENTS.md
0/15Machine-readable docs (llms.txt)
35.2/40Legible commit history — 66 of 100 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.66
agent_instruction_filesAGENTS.md
agent_instruction_max_bytes5,514
How it's scored
0/18One-command bootstrap
22/22Automated tests
0/11Lint / format config
0/11Static type checking
0/10Reproducible environment
4/10Demonstrated agent practice — 2 of the last 100 commits agent-authored or agent-credited
0/8Automated maintenance — no automated dependency updates observed
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfiles
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0.02
toolchain_manifests
dependency_bot_commit_share0
How it's scored
0/45Type-checkable code — Python without a type-check config
50.3/55Manageable file sizes — 21/245 source files over 60KB
Inputs used
primary_languagePython
largest_source_bytes315,673
source_files_sampled245
oversized_source_files21

Key facts

597GitHub stars
5contributors
225commits, last 12 months
0days since last push
100releases
1bus factor
2open issues
PyPIpackage ecosystems

Data collection warnings

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • Could not fetch pypi package 'PalworldSaveTools' from its registry
  • Could not fetch pypi package 'palsav-flex' from its registry
  • No resolved dependencies carried a version and a supported ecosystem

More detail

Star and fork history 0 ★ / 58 ⇿
0Stars
58Forks
97Releases

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.

01020304050605852024-092025-082026-07
Major 1Minor 0Patch 96

Each point covers 2 days.

OpenSSF Scorecard 3.5 / 10
3.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-24 15:17 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/aCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10
n/aPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
9Vulnerabilities1 existing vulnerabilities detected
Direct dependencies 17
RegistryPackageVersion constraintManifest
PyPIpyside6-essentialspyproject.toml
PyPIPillowpyproject.toml
PyPIcx-freeze>=8.3.0pyproject.toml
PyPInerdfontpyproject.toml
PyPIpackagingpyproject.toml
PyPIpalsav-flexpyproject.toml
PyPIbrotlipyproject.toml
PyPIcbor2pyproject.toml
PyPImsgpackpyproject.toml
PyPIzstandardpyproject.toml
PyPIorjsonpyproject.toml
PyPIpy7zrpyproject.toml
PyPInuitka>=4.1.2pyproject.toml
PyPIloguru>=0.7.3pyproject.toml
PyPIorjson>=3.11.8src/palsav/pyproject.toml
PyPIpaloozsrc/palsav/pyproject.toml
PyPIsetuptools>=68.0src/palsav/pyproject.toml
All dependencies 16

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

RegistryPackageVersionRelation
PyPIbrotlidirect
PyPIcbor2direct
PyPIcx-freezedirect
PyPIlogurudirect
PyPImsgpackdirect
PyPInerdfontdirect
PyPInuitkadirect
PyPIorjsondirect
PyPIpackagingdirect
PyPIpalsav-flexdirect
PyPIpillowdirect
PyPIpy7zrdirect
PyPIpyside6-essentialsdirect
PyPIsetuptoolsdirect
PyPIzstandarddirect
PyPIpytestindirect
Dependency advisories not assessed

Advisory matching could not run for this report: No resolved dependencies carried a version and a supported ecosystem

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 551495,
      "has_wiki": true,
      "homepage": "https://discord.gg/sYcZwcT4cT",
      "languages": {
        "C": 734173,
        "C++": 659061,
        "HTML": 281064,
        "Python": 3455367,
        "Batchfile": 8600,
        "Inno Setup": 1620
      },
      "pushed_at": "2026-07-24T00:43:20Z",
      "created_at": "2024-09-16T04:15:04Z",
      "owner_type": "User",
      "updated_at": "2026-07-24T13:10:19Z",
      "description": "PalworldSaveTools - A comprehensive toolkit designed to fix, transfer, edit, and manage your Palworld save files with ease.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python",
        "C",
        "C++"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Pylar",
      "type": "User",
      "login": "deafdudecomputers",
      "company": null,
      "location": null,
      "followers": 17,
      "avatar_url": "https://avatars.githubusercontent.com/u/164821928?v=4",
      "created_at": "2024-03-25T01:35:43Z",
      "is_verified": null,
      "public_repos": 7,
      "account_age_days": 851
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v2.2.1",
          "kind": "patch",
          "published_at": "2026-07-23T12:52:25Z"
        },
        {
          "tag": "v2.2.0",
          "kind": "minor",
          "published_at": "2026-07-23T00:00:33Z"
        },
        {
          "tag": "v2.1.9",
          "kind": "patch",
          "published_at": "2026-07-22T01:56:36Z"
        },
        {
          "tag": "v2.1.8",
          "kind": "patch",
          "published_at": "2026-07-21T21:44:02Z"
        },
        {
          "tag": "v2.1.7",
          "kind": "patch",
          "published_at": "2026-07-21T02:55:49Z"
        },
        {
          "tag": "v2.1.6",
          "kind": "patch",
          "published_at": "2026-07-20T02:23:46Z"
        },
        {
          "tag": "v2.1.5",
          "kind": "patch",
          "published_at": "2026-07-19T01:16:43Z"
        },
        {
          "tag": "v2.1.4",
          "kind": "patch",
          "published_at": "2026-07-18T06:48:14Z"
        },
        {
          "tag": "v2.1.2",
          "kind": "patch",
          "published_at": "2026-07-17T07:05:40Z"
        },
        {
          "tag": "v2.1.1",
          "kind": "patch",
          "published_at": "2026-07-16T21:45:13Z"
        },
        {
          "tag": "v2.0.9",
          "kind": "patch",
          "published_at": "2026-07-15T21:53:54Z"
        },
        {
          "tag": "v2.0.8",
          "kind": "patch",
          "published_at": "2026-07-15T03:36:45Z"
        },
        {
          "tag": "v2.0.7",
          "kind": "patch",
          "published_at": "2026-07-14T04:48:50Z"
        },
        {
          "tag": "v2.0.6",
          "kind": "patch",
          "published_at": "2026-07-13T08:13:41Z"
        },
        {
          "tag": "v2.0.5",
          "kind": "patch",
          "published_at": "2026-07-13T04:08:39Z"
        },
        {
          "tag": "v2.0.4",
          "kind": "patch",
          "published_at": "2026-07-12T21:51:43Z"
        },
        {
          "tag": "v2.0.3",
          "kind": "patch",
          "published_at": "2026-07-11T23:10:19Z"
        },
        {
          "tag": "v2.0.2",
          "kind": "patch",
          "published_at": "2026-07-11T22:13:58Z"
        },
        {
          "tag": "v2.0.1",
          "kind": "patch",
          "published_at": "2026-07-11T07:53:17Z"
        },
        {
          "tag": "v2.0.0",
          "kind": "major",
          "published_at": "2026-07-10T03:44:07Z"
        },
        {
          "tag": "v1.1.88",
          "kind": "patch",
          "published_at": "2026-05-14T19:24:03Z"
        },
        {
          "tag": "v1.1.87",
          "kind": "patch",
          "published_at": "2026-05-14T08:43:40Z"
        },
        {
          "tag": "v1.1.86",
          "kind": "patch",
          "published_at": "2026-05-07T04:36:40Z"
        },
        {
          "tag": "v1.1.85",
          "kind": "patch",
          "published_at": "2026-05-06T22:01:54Z"
        },
        {
          "tag": "v1.1.84",
          "kind": "patch",
          "published_at": "2026-05-06T05:24:56Z"
        },
        {
          "tag": "v1.1.83",
          "kind": "patch",
          "published_at": "2026-03-24T00:08:43Z"
        },
        {
          "tag": "v1.1.82",
          "kind": "patch",
          "published_at": "2026-03-22T03:14:47Z"
        },
        {
          "tag": "v1.1.81",
          "kind": "patch",
          "published_at": "2026-03-21T05:17:06Z"
        },
        {
          "tag": "v1.1.80",
          "kind": "patch",
          "published_at": "2026-03-16T05:56:59Z"
        },
        {
          "tag": "v1.1.79",
          "kind": "patch",
          "published_at": "2026-03-12T06:25:57Z"
        },
        {
          "tag": "v1.1.78",
          "kind": "patch",
          "published_at": "2026-03-11T19:57:20Z"
        },
        {
          "tag": "v1.1.77",
          "kind": "patch",
          "published_at": "2026-03-07T06:07:27Z"
        },
        {
          "tag": "v1.1.76",
          "kind": "patch",
          "published_at": "2026-03-04T17:19:31Z"
        },
        {
          "tag": "v1.1.75",
          "kind": "patch",
          "published_at": "2026-03-04T09:40:02Z"
        },
        {
          "tag": "v1.1.73",
          "kind": "patch",
          "published_at": "2026-03-02T06:58:33Z"
        },
        {
          "tag": "v1.1.72",
          "kind": "patch",
          "published_at": "2026-03-01T09:59:48Z"
        },
        {
          "tag": "v1.1.71",
          "kind": "patch",
          "published_at": "2026-02-23T07:11:29Z"
        },
        {
          "tag": "v1.1.70",
          "kind": "patch",
          "published_at": "2026-02-20T09:25:13Z"
        },
        {
          "tag": "v1.1.69",
          "kind": "patch",
          "published_at": "2026-02-18T21:59:39Z"
        },
        {
          "tag": "v1.1.68",
          "kind": "patch",
          "published_at": "2026-02-16T21:07:46Z"
        },
        {
          "tag": "v1.1.67",
          "kind": "patch",
          "published_at": "2026-02-10T09:39:43Z"
        },
        {
          "tag": "v1.1.66",
          "kind": "patch",
          "published_at": "2026-02-04T12:12:13Z"
        },
        {
          "tag": "v1.1.65",
          "kind": "patch",
          "published_at": "2026-02-02T05:56:59Z"
        },
        {
          "tag": "v1.1.64",
          "kind": "patch",
          "published_at": "2026-02-01T04:59:51Z"
        },
        {
          "tag": "v1.1.63",
          "kind": "patch",
          "published_at": "2026-01-30T08:23:29Z"
        },
        {
          "tag": "v1.1.62",
          "kind": "patch",
          "published_at": "2026-01-29T06:36:34Z"
        },
        {
          "tag": "v1.1.61",
          "kind": "patch",
          "published_at": "2026-01-28T04:30:40Z"
        },
        {
          "tag": "v1.1.60",
          "kind": "patch",
          "published_at": "2026-01-27T05:56:12Z"
        },
        {
          "tag": "v1.1.59",
          "kind": "patch",
          "published_at": "2026-01-25T07:57:54Z"
        },
        {
          "tag": "v1.1.58",
          "kind": "patch",
          "published_at": "2026-01-21T06:20:04Z"
        },
        {
          "tag": "v1.1.57",
          "kind": "patch",
          "published_at": "2026-01-20T06:18:51Z"
        },
        {
          "tag": "v1.1.56",
          "kind": "patch",
          "published_at": "2026-01-19T04:51:15Z"
        },
        {
          "tag": "v1.1.55",
          "kind": "patch",
          "published_at": "2026-01-16T23:58:52Z"
        },
        {
          "tag": "v1.1.54",
          "kind": "patch",
          "published_at": "2026-01-14T05:58:17Z"
        },
        {
          "tag": "v1.1.53",
          "kind": "patch",
          "published_at": "2026-01-11T22:29:10Z"
        },
        {
          "tag": "v1.1.52",
          "kind": "patch",
          "published_at": "2026-01-07T20:49:16Z"
        },
        {
          "tag": "v1.1.51",
          "kind": "patch",
          "published_at": "2026-01-06T08:09:40Z"
        },
        {
          "tag": "v1.1.50",
          "kind": "patch",
          "published_at": "2026-01-05T11:13:24Z"
        },
        {
          "tag": "v1.1.49",
          "kind": "patch",
          "published_at": "2026-01-04T03:16:18Z"
        },
        {
          "tag": "v1.1.48",
          "kind": "patch",
          "published_at": "2026-01-03T09:50:16Z"
        },
        {
          "tag": "v1.1.47",
          "kind": "patch",
          "published_at": "2026-01-03T08:13:49Z"
        },
        {
          "tag": "v1.1.46",
          "kind": "patch",
          "published_at": "2026-01-03T03:32:17Z"
        },
        {
          "tag": "v1.1.45",
          "kind": "patch",
          "published_at": "2026-01-02T09:52:26Z"
        },
        {
          "tag": "v1.1.44",
          "kind": "patch",
          "published_at": "2025-12-29T07:43:40Z"
        },
        {
          "tag": "v1.1.43",
          "kind": "patch",
          "published_at": "2025-12-28T06:28:06Z"
        },
        {
          "tag": "v1.1.42",
          "kind": "patch",
          "published_at": "2025-12-27T03:59:00Z"
        },
        {
          "tag": "v1.1.41",
          "kind": "patch",
          "published_at": "2025-12-25T00:30:33Z"
        },
        {
          "tag": "v1.1.40",
          "kind": "patch",
          "published_at": "2025-12-24T01:04:54Z"
        },
        {
          "tag": "v1.1.39",
          "kind": "patch",
          "published_at": "2025-12-23T02:09:02Z"
        },
        {
          "tag": "v1.1.38",
          "kind": "patch",
          "published_at": "2025-12-22T17:52:10Z"
        },
        {
          "tag": "v1.1.37",
          "kind": "patch",
          "published_at": "2025-12-22T04:19:41Z"
        },
        {
          "tag": "v1.1.36",
          "kind": "patch",
          "published_at": "2025-12-19T20:36:13Z"
        },
        {
          "tag": "v1.1.35",
          "kind": "patch",
          "published_at": "2025-12-19T06:15:00Z"
        },
        {
          "tag": "v1.1.34",
          "kind": "patch",
          "published_at": "2025-12-18T02:04:14Z"
        },
        {
          "tag": "v1.1.33",
          "kind": "patch",
          "published_at": "2025-12-17T20:00:39Z"
        },
        {
          "tag": "v1.1.32",
          "kind": "patch",
          "published_at": "2025-12-17T10:02:04Z"
        },
        {
          "tag": "v1.1.31",
          "kind": "patch",
          "published_at": "2025-12-16T05:17:55Z"
        },
        {
          "tag": "v1.1.30",
          "kind": "patch",
          "published_at": "2025-12-13T08:51:25Z"
        },
        {
          "tag": "v1.1.29",
          "kind": "patch",
          "published_at": "2025-12-13T04:52:38Z"
        },
        {
          "tag": "v1.1.28",
          "kind": "patch",
          "published_at": "2025-12-12T20:34:12Z"
        },
        {
          "tag": "v1.1.27",
          "kind": "patch",
          "published_at": "2025-12-12T05:33:42Z"
        },
        {
          "tag": "v1.1.26",
          "kind": "patch",
          "published_at": "2025-12-12T00:49:15Z"
        },
        {
          "tag": "v1.1.25",
          "kind": "patch",
          "published_at": "2025-12-08T02:44:13Z"
        },
        {
          "tag": "v1.1.24",
          "kind": "patch",
          "published_at": "2025-12-06T21:26:33Z"
        },
        {
          "tag": "v1.1.23",
          "kind": "patch",
          "published_at": "2025-12-06T01:36:33Z"
        },
        {
          "tag": "v1.1.22",
          "kind": "patch",
          "published_at": "2025-12-05T06:31:54Z"
        },
        {
          "tag": "v1.1.21",
          "kind": "patch",
          "published_at": "2025-12-05T01:16:36Z"
        },
        {
          "tag": "v1.1.20",
          "kind": "patch",
          "published_at": "2025-12-03T18:47:42Z"
        },
        {
          "tag": "v1.1.19",
          "kind": "patch",
          "published_at": "2025-12-03T09:17:38Z"
        },
        {
          "tag": "v1.1.18",
          "kind": "patch",
          "published_at": "2025-12-02T10:29:54Z"
        },
        {
          "tag": "v1.1.17",
          "kind": "patch",
          "published_at": "2025-12-01T09:18:33Z"
        },
        {
          "tag": "v1.1.16",
          "kind": "patch",
          "published_at": "2025-11-30T06:24:43Z"
        },
        {
          "tag": "v1.1.15",
          "kind": "patch",
          "published_at": "2025-11-29T20:41:18Z"
        },
        {
          "tag": "v1.1.14",
          "kind": "patch",
          "published_at": "2025-11-26T23:25:50Z"
        },
        {
          "tag": "v1.1.13",
          "kind": "patch",
          "published_at": "2025-11-25T03:27:10Z"
        },
        {
          "tag": "v1.1.12",
          "kind": "patch",
          "published_at": "2025-11-17T02:32:51Z"
        },
        {
          "tag": "v1.1.11",
          "kind": "patch",
          "published_at": "2025-11-14T07:16:48Z"
        },
        {
          "tag": "v1.1.10",
          "kind": "patch",
          "published_at": "2025-11-14T02:22:53Z"
        },
        {
          "tag": "v1.1.09",
          "kind": "patch",
          "published_at": "2025-11-12T00:25:12Z"
        },
        {
          "tag": "v1.1.08",
          "kind": "patch",
          "published_at": "2025-11-09T07:38:08Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "cbd98c44923b18d8010d94cc1ca10d1657d55c17",
          "body": "…er steps",
          "is_bot": false,
          "headline": "TOC alignment, swap notes in transfer guides, expand Character Transf…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-24T00:41:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e0d5c57a4ed869be743eec17628992e2fd393a4",
          "body": "…grams",
          "is_bot": false,
          "headline": "Rewrite host swap section: emphasize two-way swap with file-state dia…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-24T00:38:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b01096f1dedec652ca410941d8270772c41429d7",
          "body": null,
          "is_bot": false,
          "headline": "Update translations for simplified host transfer guides",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-24T00:12:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ec816e5eb2aeee3044f84604d7974dd3335a4b6f",
          "body": null,
          "is_bot": false,
          "headline": "Simplify host transfer guides in README",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-24T00:10:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3c636855a8431a9c50c59d6ba5820f1f08f485f4",
          "body": "…ventFilter, per-button style update instead of full rebuild",
          "is_bot": false,
          "headline": "Fix tech tab lag/crash: replace monkey-patched mousePressEvent with e…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T17:14:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c5e42c8adb5f81720adec990307058b11360495a",
          "body": "- Tech _click handler used 'not in' instead of 'in', reversing toggle direction\n- Removed super().mousePressEvent() call on frames scheduled for deferred deletion\n- Base inventory _refresh_container_ui() moved after dialog.exec() to avoid\n  deleteLater() inside nested event loop signal handler (segfault)",
          "is_bot": false,
          "headline": "Fix tech tree inverted toggle and base inventory add-item crash",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T12:28:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ed9a2f889587a5153437fca11686c2fd8de1edf2",
          "body": "Call clear_player() on inventory and pal editor tabs,\n_clear_guild_selection() on base inventory tab, and\nclear_selection() on results widget before refresh_all()\nso prev_uid is None when refresh() runs, preventing\nre-selection of old players/guilds/bases after load.",
          "is_bot": false,
          "headline": "Reset tab picker selections on save load",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T12:22:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1af173d314886c6a7c1592c637e6d9f1d3d09ab8",
          "body": "… reset",
          "is_bot": false,
          "headline": "Update changelog for 2.2.1: custom HP preservation and results widget…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T12:10:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "deadbd1ad79870c43c47a24c41f712a8de686907",
          "body": "results_widget.clear_selection() existed but was never called,\nso the player/guild/base picker labels showed stale data from\nthe previous save after reloading.",
          "is_bot": false,
          "headline": "Reset results widget on save reload",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T12:09:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "793ebbf601ecab49ea81fae2a6fd7568f8c23566",
          "body": "Both import_base_json and _replace_structures_impl were reading\ndefault HP from game data and overwriting the structure's max HP,\ndestroying custom durability set via server config.\n- import_base_json: removed game-data HP map and the overwrite\n- _replace_structures_impl: removed game-data HP lookup and only\n  sets current = max (preserving existing max)",
          "is_bot": false,
          "headline": "Fix import/clone base and replace structures overwriting custom HP",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T12:04:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "593a3da161b2cb18fa0b3010d830409a77ef1bb6",
          "body": "- Fix map generator missing tree-map/island bases\n- Fix base radius ring non-linear scaling\n- Fix hard crash on inventory/tech tree edits\n- Fix Repair All Structures overwriting custom max durability",
          "is_bot": false,
          "headline": "Bump version to 2.2.1",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T12:02:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9cf4871c194ad5de75d10793de2c0ad59e1f30a",
          "body": null,
          "is_bot": false,
          "headline": "Strip IsRarePal when target has no boss variant in Bulk Sync",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T04:26:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f50ab32ed0341bb45a5fa9af84fc161f99810e81",
          "body": "…e data",
          "is_bot": false,
          "headline": "Guard Bulk Sync boss prefix: only apply if boss variant exists in gam…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T03:53:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61dadcbad3b05bd848b7e1d5f69eb8a0c409c653",
          "body": "… now fills EquipWaza; fix Bulk Sync boss prefix\n\n- Learn All: removed if elements guard that skipped EquipWaza fill for\n  pals without element data (e.g. Astralym). Now prefers element-matching\n  skills first, then highest-power skills from any element.\n- + button (add single skill): now also adds to EquipWaza if <3 slots filled.\n- Bulk Sync with lucky: now prepends BOSS_ prefix to target's own\n  CharacterID instead of deep-copying source's CharacterID wrapper.",
          "is_bot": false,
          "headline": "Fix EquipWaza not filling on Learn All for elementless pals; + button…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-23T02:13:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "103a6127696df358992fe658f2470448b40661e2",
          "body": "Bulk Sync copied IsRarePal (lucky flag) via _EDITABLE_KEYS but never\ncopied CharacterID. Lucky/alpha pals have a BOSS_ prefix in CharacterID\nwhich gives increased size and the HP ×1.087 multiplier. Without it,\ntarget pals showed the lucky star but remained normal-sized.\n\nFix: after the main copy loop, both BulkSyncPalDialog and\nBulkSyncAllDialog now check if the source has a BOSS_-prefixed\nCharacterID and deep-copy it to targets that lack the prefix.",
          "is_bot": false,
          "headline": "Fix Bulk Sync not applying alpha/boss variant for lucky pals",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T23:44:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "594422d8684b80fcc32c86817d05ab62af004dc2",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 2.2.0",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T23:36:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc0799f0fb2722c41dae5dbf6dea39306fbb3552",
          "body": "Document the use-after-free pattern found and fixed in inventory_tab.py\nso future code never repeats this mistake.",
          "is_bot": false,
          "headline": "Add critical gotcha: deleteLater() during dialog.exec() = segfault",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T23:35:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "51a4a86baaa081bf35617361972b6aee4fb00583",
          "body": "Root cause: _refresh_display() called set_max_slots → deleteLater()\nduring modal dialog.exec() nested event loop. Qt's nested event loop\nprocessed deferred delete events before the dialog fully closed, then\naccept-triggered repaint accessed freed C++ widget objects → use-after-free.\n\nChanges:\n- Move\n[…]\nde nested event loop.\n- Rewrite set_max_slots to only destroy excess widgets instead of\n  nuking + recreating all; removeWidget+setParent before deleteLater\n  to eliminate layout-stale-reference race.",
          "is_bot": false,
          "headline": "Fix random segfault on add-item in inventory tab",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T23:35:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bb23b83c2ec8d3f705bf9cc513d5cb99162db8ad",
          "body": null,
          "is_bot": false,
          "headline": "fix: dialog widths, finalize spinbox fixes",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T23:06:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b393dfad9b33a05e54a723e78b26f33710751502",
          "body": "Prevents hard crash when user types values > int32 max (e.g. 777B).\nFixed in ItemPickerDialog, QuantityDialog, and PlayerItemActionDialog.\nAlso: lazy-load missions/tech tabs on tab switch, no proactive refresh.",
          "is_bot": false,
          "headline": "fix: replace QSpinBox with QLineEdit+QIntValidator for quantity inputs",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T23:04:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "010540e8084b0564c266f4e222405e75dfc331bd",
          "body": null,
          "is_bot": false,
          "headline": "changelog: bulk tech dialog redesign entry",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T22:49:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "43ab793886e531114abbebda483ddc729dfc72c9",
          "body": "- add/remove process all selected techs in one file read/write per player\n- removed dead _add_technology_to_player / _remove_technology_from_player\n- toggle selection on click (no Ctrl needed, no clear on plain click)\n- confirmation and result always show count-based messages\n- player_technology.applied i18n key for success dialog",
          "is_bot": false,
          "headline": "fix: single-pass add/remove, toggle selection, always show success",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T22:49:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aae46ad2a162e5e54fa29487ca54e7a53d31efa6",
          "body": "Replaced QListWidget with row-by-row grid matching inventory tab\nlayout (76x76 frames, level badges, divider, ancient column).\nAdded Ctrl+click multi-select, auto-show players panel on right.\nTooltips match inventory tab format.",
          "is_bot": false,
          "headline": "refactor: player_technology_dialog grid + multi-select + side panel",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T22:30:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "155ea68a67d87915271df6d1c0689a4c5e12595a",
          "body": "Adds TechnologyPanelWidget as 5th subtab in PlayerInventoryTab.\nGrid layout: grouped by level_cap, 8 regular techs per row,\nancient tech column with divider. Click to toggle unlock,\nSelect All/Deselect All/Apply. Tech point spinners.\nIn-memory edits, single file write on Apply.",
          "is_bot": false,
          "headline": "feat: Technology tab in Player Inventory editor",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T22:19:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d12b6eb0f53722688bb6564397f9486d4c9c122e",
          "body": null,
          "is_bot": false,
          "headline": "changelog: individual skill add entry",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:54:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d7871584e1f243c738749b079ea492a069a1296",
          "body": "+ button opens SkillPicker, adds chosen skill to MasteredWaza.\nReplaces misplaced + button in active skills header.\nAllows adding individual skills instead of only Learn All + remove.",
          "is_bot": false,
          "headline": "feat: add single skill button in learned moves dialog",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:51:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e42e25d9a2112e7873bfd86ddfb4091ed2a523a4",
          "body": null,
          "is_bot": false,
          "headline": "i18n: edit_pals.add_active_skill key",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:49:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "05312765b07b7f850a523ea15ad5786606b649ac",
          "body": "+ button in active skills header opens SkillPicker and appends\nthe chosen skill to EquipWaza at the next available slot.\nRespects cheat mode cap (3/255). Reuses existing _set_active_skill\nand _show_skill_picker paths.",
          "is_bot": false,
          "headline": "feat: add single active skill button",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:49:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7505c69eb0461d0818e9a59e078b24d338a6e42f",
          "body": null,
          "is_bot": false,
          "headline": "changelog: food buff stats entry",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:47:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e6dc60cb3a2bb15a61af9c8cb26b1b986690f0a2",
          "body": "- update_ui_icons() now fetches all Buff/Debuff/Base timer icons (32 icons)\n- uidata.json registers them as buff_buff_02 etc\n- pal_info_widget.py: new third row with 5 buff icons anchored to right\n- pal_info_display.py: shows relevant buff icons based on active food buff\n  (Attack/Defense/WorkSpeed/HungerResist/Exp_Increase)",
          "is_bot": false,
          "headline": "feat: buff timer icons in pal info display",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:45:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "20ce6b203c1e9ed66c387ae96e3e4803647f3b4b",
          "body": "Causes hard crash (palooz decompression conflict during inventory save).\nMissions data unchanged by inventory ops, only needs reload on player switch.",
          "is_bot": false,
          "headline": "fix: remove missions load_player from inventory _refresh_display",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:37:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5344a03346bb8e1548bfd242deef901dd76205d2",
          "body": "QListWidget.clear() while a custom item delegate is active\ncauses Qt to trigger paint events on items being destroyed,\nleading to segfault. Fix: set delegate to None before clear(),\nre-set after rebuild.",
          "is_bot": false,
          "headline": "fix: segfault in Add New Pal filter on typing",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T21:02:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bfc17154a3feadb807bb5d8583d3ea39bc8d919a",
          "body": "- Added _ensure_food_buff_map() to data.py loading foodbuffdata.json\n- Added food_bonus param to all 4 stat functions (HP/ATK/DEF/WS)\n- food_mult stored in breakdown dicts as separate multiplier\n- Tooltip shows Food Buff +X% line when active\n- pal_info_display reads FoodWithStatusEffect from save, looks up\n  food buff effects, and passes Attack/Defense/WorkSpeed bonuses\n  to calc functions",
          "is_bot": false,
          "headline": "feat: food buff stats in pal editor info panel",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T20:48:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c03c7dfc3bc89e094cdbf915344d5efb22f321f4",
          "body": "Adds update_food_buff_data() reading DT_StatusEffectFood.json (54 items)\nand save to foodbuffdata.json with duration + effects array per food item.",
          "is_bot": false,
          "headline": "feat: food buff data extraction in update_game_data.py",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T20:44:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "598de7f3801e43336f6167ee45378dcce6b17852",
          "body": "…ug prints\n\nThe menu Reset Missions function was drilling into RecordData\ninstead of SaveData.value where the quest arrays actually live.",
          "is_bot": false,
          "headline": "fix fix_missions CompletedQuestArray_FullRelease key path, remove deb…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T20:31:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "902360e2b69367e1aff060927637def599aba8d3",
          "body": null,
          "is_bot": false,
          "headline": "feat: Missions tab, changelog entry",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T20:23:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b112122fd54179e1399128f066df4e6adeb12265",
          "body": null,
          "is_bot": false,
          "headline": "debug: add print traces to missions load_player",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T19:59:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "651b12a54c20b600d5932297d3c1b112b809edbd",
          "body": "Save files use hex without dashes (00000000000000000000000000000001.sav),\nbut UID from get_players() has dashes. Added _uid_filename() helper.",
          "is_bot": false,
          "headline": "fix: missions tab UID filename format",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T19:57:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "127c71f754d493ab5c38c9ff20bb231313514a4d",
          "body": "- New MissionPanelWidget inside PlayerInventoryTab (4th subtab after Stats)\n- Reads CompletedQuestArray_FullRelease + OrderedQuestArray_FullRelease\n- Select All / Deselect All toggles, Complete Selected / Reset Selected\n- update_game_data.py: new update_quest_data() extracts DT_PalQuestData.json\n- fix_missions() now targets CompletedQuestArray_FullRelease (was broken key)\n- i18n keys for missions in all 8 languages via add_translation_keys.py",
          "is_bot": false,
          "headline": "add Missions tab in Player Inventory",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T19:54:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c669978dc903a5b6ce72758ebda6e18efaea806",
          "body": "NPC name resolution fix from 2.1.9.",
          "is_bot": false,
          "headline": "bump to v2.2.0",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T19:08:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "402d506f4f8cab3b97603df4d930bf46359a5885",
          "body": "_make_npc_entry only checked NAME_{npc_id} in the L10N table,\nmissing the indirect OverrideNameTextID -> L10N path defined in\nDT_PalHumanParameter. 154 generic NPCs (Male_Trader01 variants,\nBeliever_Bat, Hunter_Rifle, etc.) showed technical asset names\nlike 'Male Trader01 v04' instead of proper in-game names like\n'Butcher in Training', 'Free Pal Alliance Believer', 'Syndicate Gunner'.\nNow 367/370 NPCs resolve correctly.",
          "is_bot": false,
          "headline": "fix: NPC names now resolve via OverrideNameTextID from HumanParameter",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T19:04:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f35b4d740259a7a75b11cccf2b7c35f928c1ab77",
          "body": "… PR entries",
          "is_bot": false,
          "headline": "Bump to v2.1.9, move session changes to new section, add DPI + README…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T01:38:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fccd6910b4bd1f608ec9dec472b8ad5d131bfcbe",
          "body": "…ters/PalworldSaveTools",
          "is_bot": false,
          "headline": "Merge commit 'refs/pull/212/head' of https://github.com/deafdudecompu…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T01:22:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c0805e67c7ad55a941b9de9dd7a27ae0f94c3bc",
          "body": "…ters/PalworldSaveTools",
          "is_bot": false,
          "headline": "Merge commit 'refs/pull/211/head' of https://github.com/deafdudecompu…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T01:22:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c960511d6790cc54a01f5955ce7aa077b96a5e54",
          "body": null,
          "is_bot": false,
          "headline": "fix: XGP clear fog no longer accesses Steam save path",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-22T01:20:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "207ef72f40530a6963ed2414a904b66b080b1da6",
          "body": "Adds a compact overview table at the top of the Features section in\nall 9 READMEs (English + 8 translations). Makes it easy for new\nvisitors to quickly see what the tool can do without reading 80+\nbullet points. Detailed sections remain below for reference.",
          "is_bot": false,
          "headline": "feat: add features summary table to all README files",
          "author_name": "saintpepsicola",
          "author_login": "saintpepsicola",
          "committed_at": "2026-07-22T01:07:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5bb01b825dd3948f28e8ec19a34f3af333b60b1d",
          "body": null,
          "is_bot": false,
          "headline": "style: match close button to app's neon blue button style",
          "author_name": "saintpepsicola",
          "author_login": "saintpepsicola",
          "committed_at": "2026-07-22T00:49:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e9d716f4929e9a3903b0f2876649cf0091d9971f",
          "body": "- QT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough only on macOS (safe)\n- Window size adapts to screen geometry (works on 1280x800 up to 4K)\n- Minimum 1200x750 preserved for small screens",
          "is_bot": false,
          "headline": "fix: platform-aware DPI scaling + screen-adaptive window sizing",
          "author_name": "saintpepsicola",
          "author_login": "saintpepsicola",
          "committed_at": "2026-07-22T00:43:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e2ce4673ad220385cac1f6e5ec293ca434a80e70",
          "body": null,
          "is_bot": false,
          "headline": "fix: widen active tab indicator and add more spacing",
          "author_name": "saintpepsicola",
          "author_login": "saintpepsicola",
          "committed_at": "2026-07-22T00:43:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3675acb02dfcc8260579e2e96687df77f8e8a5d6",
          "body": null,
          "is_bot": false,
          "headline": "feat: add close button on results panel header",
          "author_name": "saintpepsicola",
          "author_login": "saintpepsicola",
          "committed_at": "2026-07-22T00:43:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44140fca8dcf735314620939f31bf4212723231c",
          "body": null,
          "is_bot": false,
          "headline": "feat: DPI scaling on mac and smaller resolutions",
          "author_name": "saintpepsicola",
          "author_login": "saintpepsicola",
          "committed_at": "2026-07-22T00:43:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ff698915f4880d5ca5075067592f46e9b0d603c",
          "body": null,
          "is_bot": false,
          "headline": "Fix Illegal Pals dialog: add reason badges as second row on pal cards",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T20:02:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c2af825128e0e1eec239c67978e8fcd0760d8509",
          "body": "…ligned layout",
          "is_bot": false,
          "headline": "Fix Illegal Pals dialog: add stretch to right panel for compact top-a…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T19:55:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f47efb2ca4285198128ad1976eb1a67bd684025d",
          "body": "…d/base ID resolution, per-pal detail rows",
          "is_bot": false,
          "headline": "Fix Illegal Pals dialog redesign: two-column layout, base worker guil…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T19:52:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7de902c54700a73921b7e77133dfe5897f19377d",
          "body": "… instead of rebuild",
          "is_bot": false,
          "headline": "Fix Illegal Pals dialog: pre-create all pal rows, show/hide on toggle…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T18:56:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b363a6a0c1e2dae95fa6de23bb649d672369337",
          "body": "…and illegal markers",
          "is_bot": false,
          "headline": "Fix Illegal Pals dialog: show per-pal rows with species icon, stats, …",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T17:30:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "45473b7b8f5a2ff86ee8b8aca340684bb29b5677",
          "body": "…n backward compat, add points=/players=",
          "is_bot": false,
          "headline": "Fix Unlock Fast Travel confirm text: keep count= param for translatio…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T17:26:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aad32702aa23e46cba5afeb1324dbeec2461d7f6",
          "body": "… to avoid translation ambiguity",
          "is_bot": false,
          "headline": "Fix Unlock Fast Travel confirmation text: rename count→points/players…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T17:24:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1554adc83a716a62d2f233a3da22c956359c95b9",
          "body": "… false alarm, level guard removal",
          "is_bot": false,
          "headline": "2.1.8 fixes: level edit crash, player .sav full copy, unsaved-changes…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T17:21:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "43691e698fc4bc22aadad81468ab7b664739957e",
          "body": "…rimmed",
          "is_bot": false,
          "headline": "version bump 2.1.7→2.1.8 + fix illegal pals active skills not being t…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T06:59:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "10f67a5eb2b6b0b15b9723a357e8114d75e12ce0",
          "body": null,
          "is_bot": false,
          "headline": "Remove Nuitka onefile builds from CI (cx_Freeze standalone only)",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T02:39:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "632f11fd0518e43662bbbaff9c64364a1a5a4d58",
          "body": null,
          "is_bot": false,
          "headline": "Add Windows Nuitka build to Build All & Release workflow",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T01:01:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "377c8dedbfdff321893f784aa3917dc3f07b31cb",
          "body": "- Replaced brief 2-step host swap section with detailed 7-step guide\n- Added pt_PT to translate_readme.py (LANGUAGES, TRANSLATIONS, HEADER)\n- Regenerated all 9 README translations with updated content\n- Added pt_PT link to English README header\n- Disambiguated pt_BR label as 'Português (Brasil)'",
          "is_bot": false,
          "headline": "Update README host swap guide + add pt_PT README translation",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:56:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "857aa77578c675911b1f114376758fe61eb73b0b",
          "body": "Fetched and merged pr-206 (sirj0k3r:localization/pt-PT). Adds pt_PT.json,\nregisters language, disambiguates pt_BR label. Cleaned stale GamingServices\nkeys from pt_PT.json after merge.",
          "is_bot": false,
          "headline": "Merge PR #206: Portuguese (Portugal) translation",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:51:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "93c668fbd397defc52c7a24682b4711e3b6bae8a",
          "body": null,
          "is_bot": false,
          "headline": "changelogs: add selection colors, error overlay, GamingServices cleanup",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:47:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d79ef00d2d9874900bbada3583261c2e67c87908",
          "body": "SortableTreeWidget (tree_widgets.py), PICKER_LIST_STYLE (styles.py),\nand styled_combo.py dropdown list were using #3B8ED0 instead of the\ndominant #7DD3FC selection accent. Change all to rgba(125,211,252,...)\nwith same alpha pattern as other selection styles.",
          "is_bot": false,
          "headline": "Unify selection accent color: use #7DD3FC everywhere",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:44:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a8faba0764d345c4b332df61887f6cc42a97570",
          "body": "The GamingServices stop/start code was removed in fd004827, but the\nconfirmation dialog asking about it and the is_admin() check remained.\nRemove the stale dialog, admin check, is_admin method, and all 4 i18n\nkeys from all 8 language files.",
          "is_bot": false,
          "headline": "Clean up dead GamingServices admin check and i18n keys",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:19:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "33b68a13901ebbde36470f9f19cd108cabaf48ff",
          "body": "…ds None crash",
          "is_bot": false,
          "headline": "ErrorDialog: render as overlay on parent window; fix _get_container_i…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:14:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d5698493963129fe6c0c9086e64e4b9be3a60b5",
          "body": "- Add ToggleCheckBtn 'Show all structure types' in ReplaceStructureDialog\n- _populate_right shows all families when toggle enabled (was same-family only)\n- Add _on_show_all_toggled handler that re-populates right list\n- Add base_inventory.replace_show_all i18n key, propagated to all 8 languages\n- Changelog entry",
          "is_bot": false,
          "headline": "add cross-family structure replacement toggle to ReplaceStructureDialog",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-21T00:02:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "03b572d491fe3ab5f17db44983f2356458d447c3",
          "body": "Second Portuguese entry still used the pt_BR code, so both variants\nwere being tracked under the same language key.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: correct pt_PT language code in changelog translator",
          "author_name": "sirj0k3r",
          "author_login": "sirj0k3r",
          "committed_at": "2026-07-20T23:58:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a17e51d868b48bbf3ec1acfbdba1ee2e87d3a866",
          "body": "• Add pt_PT to supported languages list\n• Update language labels to distinguish Brazilian and Portugal Portuguese variants\n• Add translations and UI mappings for Portuguese (Portugal)\n• Update changelog translation script for pt_PT",
          "is_bot": false,
          "headline": "Add Portuguese (Portugal) language support",
          "author_name": "sirj0k3r",
          "author_login": "sirj0k3r",
          "committed_at": "2026-07-20T23:49:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "479b3a9f7711734a0ab9fefc3dfa1725cb2b54e3",
          "body": "- Move global declarations before first variable use in closeEvent\n- Remove stale self.finalize_save() wrapper, add _save_and_close() with\n  callback that clears state before re-triggering close\n- finalize_save now accepts optional on_close_complete callback",
          "is_bot": false,
          "headline": "fix: character_transfer closeEvent infinite loop + async save crash",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T23:41:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd0048278fe6eb5bece5db5a1e68a9cd8578aedd",
          "body": "… stop/start\n\n- Remove unlock_self_folder (PowerShell+WMI+hidden-window) from bootup.py,\n  common.py, main_window.py — was causing Qt hang on import before QApplication\n- Remove stop_gaming_services/start_gaming_services (net stop+taskkill) from\n  common.py, game_pass_save_fix.py, gamepass_manager.p\n[…]\n launching downloaded\n  third-party tools in modify_save.py\n- Replace spoofed Mozilla/5.0 User-Agent with PalworldSaveTools/2.1.7\n- Add 7 new i18n keys (modify.confirm.*) propagated to all 8 languages",
          "is_bot": false,
          "headline": "remove AV-triggering code: unlock_self_folder, GamingServices service…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T23:21:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f3bdda0de3abde2c2e984f8795795ee13c789639",
          "body": null,
          "is_bot": false,
          "headline": "+ Added pt-PT localization",
          "author_name": "sirj0k3r",
          "author_login": "sirj0k3r",
          "committed_at": "2026-07-20T22:53:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "87821d2554a159b8644d41420f6a38bb3dda1941",
          "body": null,
          "is_bot": false,
          "headline": "changelogs: add bulk-select entry for v2.1.7",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T22:38:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c2ec9e278965773d29edee27851c50b23848a975",
          "body": "- Connect InventoryGridWidget multi_delete_requested/multi_clear_qty_requested\n- _on_bulk_remove_items: themed confirm, manager.remove_item per slot, grid refresh\n- _on_bulk_clear_qty: manager.set_item_count(0) per slot, grid refresh\n- Fix: remove default= fallback from inventory multi-count t() cal\n[…]\nidget.refresh_labels\n- Fix: use update_quantity() instead of non-existent set_item_count()\n- Fix: use _themed_message_box for bulk delete confirm\n- 2 i18n keys added for base inventory bulk operations",
          "is_bot": false,
          "headline": "base inventory: multi-select bulk remove and clear quantity",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T22:36:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a65dad39c4417b69da8dc2620742d68336dd6f54",
          "body": "…update_multi_toolbar to refresh_labels",
          "is_bot": false,
          "headline": "fix: remove default= fallback from inventory multi-count label, add _…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T22:12:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0e6384bfa32443f8f060fba7b378f0307e80e7b9",
          "body": "…ions toolbar\n\n- ItemSlotWidget: multi_selected state, set_selected_multi, modifier tracking\n- InventoryGridWidget: multi-select set, modifier dispatch on click, toolbar\n- Toolbar (Delete/Clear Qty/Deselect) appears when >=2 items selected\n- Ctrl+click toggles item in multi-set, Shift+click range-selects\n- load_items clears multi-selection on refresh\n- PlayerInventoryTab: _on_bulk_delete_items, _on_bulk_clear_qty handlers\n- 6 i18n keys added via add_translation_keys (9 languages)",
          "is_bot": false,
          "headline": "player inventory: multi-select with Ctrl+click/Shift+click + bulk act…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T22:08:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8f2a3fe5d86de006eac58aee9594e056385faceb",
          "body": "…oolbar\n\n- Ctrl+click toggles slots into multi-selection set\n- Shift+click selects range within same container (party/palbox/DPS)\n- Primary selected slot auto-included on Ctrl+click\n- Empty slots skipped on multi-select\n- Inline toolbar (Box|DPS row) with Max/Heal/Rename/Delete/Deselect\n- Absolute-i\n[…]\nlog (FramelessDialog + QLineEdit)\n- 17 i18n keys added via add_translation_keys (9 languages)\n- refresh_labels() covers toolbar buttons\n- QApplication.processEvents() before dialogs for visual refresh",
          "is_bot": false,
          "headline": "pal editor: multi-select with Ctrl+click/Shift+click + bulk actions t…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T21:59:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dfa5c95a9b2bf41436667ddb816b77324b6a8eee",
          "body": null,
          "is_bot": false,
          "headline": "restore point: before multi-select implementation",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T21:10:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "242f2351f459530c1e93eb73e43bb275be2daa3a",
          "body": null,
          "is_bot": false,
          "headline": "update changelogs.md for 2.1.7",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T20:25:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f045f9d2dc33d4fe3ee7097c113b3209e96ad5ae",
          "body": null,
          "is_bot": false,
          "headline": "+ [WIP] Adds European Portugal i18n translations",
          "author_name": "sirj0k3r",
          "author_login": "sirj0k3r",
          "committed_at": "2026-07-20T20:22:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "556e7b971a1335120f1ec85127c1f0366dc5171d",
          "body": "- Character Transfer: stale save check on target Level.sav before save,\n  unsaved-changes warning on dialog close (tracks modified_target_players)\n- Fix Host Save: stale save check before fix, stores mtime on load\n- Slot Injector: stale save check before save, stores mtime on load\n- Base Inventory: \n[…]\nirty flag on _refresh_dashboard()\n- Pal Editor: dirty flag on _update_dashboard_stats() and _refresh()\n- Translation: character_transfer.unsaved_warning and button.dont_save\n  added to all 9 languages",
          "is_bot": false,
          "headline": "stale save detection for standalone tools + unsaved changes dialog",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T20:21:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "44e8502e71c3a55026f98b42c5f7bc85a77fe7f5",
          "body": "- Unsaved changes warning on exit\n- Stale save detection before overwrite\n- Drag-and-drop .sav anywhere on window (cherry-picked from PR #200)\n- Translation keys for all features across 9 languages",
          "is_bot": false,
          "headline": "v2.1.7",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T18:38:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0a7bac176399074abf2910a6657dc130856c1aef",
          "body": "…e overwriting",
          "is_bot": false,
          "headline": "Merge PR #201: Add detection for stale save files and warn user befor…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T18:23:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8b8b973346edc11b90bd4b74c95c85d60fc3107e",
          "body": "Track modification time of loaded Level.sav to detect external changes. Show confirmation dialog before saving over disk changes. Add i18n strings for stale save warning.\n\nCo-Authored-By: claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add detection for stale save files and warn user before overwriting",
          "author_name": "sirj0k3r",
          "author_login": "sirj0k3r",
          "committed_at": "2026-07-20T14:20:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7909170c0cc6d46d93fc045a9bf3b9b3af17cb2f",
          "body": null,
          "is_bot": false,
          "headline": "Disable Nexus Mods upload (make upload step a no-op)",
          "author_name": "CyrixJD115",
          "author_login": "CyrixJD115",
          "committed_at": "2026-07-20T12:37:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e19d768c0a43312721322f265f0f1c56b43e1c0",
          "body": null,
          "is_bot": false,
          "headline": "fix: guard Fix Host Save search against unloaded save",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T01:55:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d41cc9ae6e60de4b3b6def56ad4899212306d8d",
          "body": null,
          "is_bot": false,
          "headline": "revert v2.1.7 → v2.1.6, merge changelog entry into v2.1.6 section",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-20T01:01:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef40692bdc5077b28020df347dcd6f8a42d4e1cb",
          "body": null,
          "is_bot": false,
          "headline": "bump v2.1.6 → v2.1.7 (version strings + changelog)",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T23:54:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd732ba7412adcd51405838a94e8fa96047b1d6e",
          "body": null,
          "is_bot": false,
          "headline": "add pal icons to bulk rename and bulk restore candidate lists",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T23:51:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "793dafc068e629468215473f9d061e1f37e26f37",
          "body": null,
          "is_bot": false,
          "headline": "changelog: character transfer null-safety guards",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T22:41:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5bd0e7adf7484f2d0f4f6a27ebb647f1f3e46c13",
          "body": null,
          "is_bot": false,
          "headline": "fix: guard finalize_save against unloaded target save",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T22:40:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fffd3bd649de0838b2cd07adbf32635bd6ce1529",
          "body": null,
          "is_bot": false,
          "headline": "fix: guard transfer_all_characters against unloaded source/target saves",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T22:37:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "866cddc525a002af1dc79452349d12c2462133ce",
          "body": null,
          "is_bot": false,
          "headline": "changelog: auto-reset save session on tool launch",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T22:33:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3d44a136108c4605f978e210c92df0985fe65689",
          "body": "Users clicking any standalone tool card (slot injector, character\ntransfer, fix host save, modify save, convert, restore map, etc.)\nwhile a save is loaded in main now get the session wiped clean.\nPrevents confusion where loaded save data doesn't carry into tools\nthat prompt for their own save file.",
          "is_bot": false,
          "headline": "auto-reset save session when launching external tools",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T22:33:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a5043b1cd80eebdf9ffce237f870e5b75607fe4",
          "body": "SlotNumUpdaterApp is a QDialog with custom closeEvent that calls\nevent.accept() without super().closeEvent(), so QDialog::done() is\nnever called and the finished signal never fires. Wrap closeEvent for\nQDialogs too (was only connected to finished signal), matching the\nQWidget approach that was already working.",
          "is_bot": false,
          "headline": "fix: slot injector not restoring main window on close",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T20:57:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6caa0c1f16708f14cfc1a63e1e7589e20fe34dc0",
          "body": "- Hide main window while tool dialogs (character transfer, slot injector,\n  etc.) are open to prevent wrong-window attachment of loading overlays\n- Suppress quitOnLastWindowClosed during dialog lifetime so closing the\n  last visible window (the dialog) does not exit the app\n- Fallback to QApplicatio\n[…]\ndialog as overlay parent (parented windows are not topLevelWidgets)\n- Restore main window via closeEvent wrapper (QWidget) or finished signal\n  (QDialog) with event.isAccepted() guard for cancel cases",
          "is_bot": false,
          "headline": "fix: hide main window during tool dialogs, prevent app quit on close",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T20:51:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fff2a7e36d6bb956bb58d1e669a65d68366fb0a4",
          "body": "- Player names starting with -- (e.g. --Sasok--) now selectable\n- Fix Illegal Players/Pals dialogs widened to 700px\n- deletion.illegal_players_fixed translation key added to all 8 languages\n- Purged 19 stale translation keys from all language files",
          "is_bot": false,
          "headline": "fix: player select name bug, wider dialogs, translation cleanup",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T16:59:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a8c95a4a2665a9b8e0ca64bde4ada6db45856aa5",
          "body": "…w in-window\n\n- Player select popup: fragile startswith('--') check prevented selecting names like --Sasok--\n- Skill picker: same pattern fixed with object comparison\n- Loading overlay redesigned as in-window QWidget child instead of separate subprocess",
          "is_bot": false,
          "headline": "fix: player names starting with -- not selectable, loading overlay no…",
          "author_name": "Pylar",
          "author_login": "deafdudecomputers",
          "committed_at": "2026-07-19T16:38:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 100,
      "commits_last_year": 225,
      "latest_release_at": "2026-07-23T12:52:25Z",
      "latest_release_tag": "v2.2.1",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 2,
      "days_since_latest_release": 1,
      "mean_days_between_releases": 0.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 58,
      "stars": 597,
      "watchers": 8,
      "fork_history": {
        "days": [
          {
            "date": "2024-09-26",
            "count": 1
          },
          {
            "date": "2024-10-07",
            "count": 1
          },
          {
            "date": "2024-12-16",
            "count": 1
          },
          {
            "date": "2025-01-01",
            "count": 1
          },
          {
            "date": "2025-01-07",
            "count": 1
          },
          {
            "date": "2025-01-27",
            "count": 1
          },
          {
            "date": "2025-01-28",
            "count": 1
          },
          {
            "date": "2025-01-30",
            "count": 1
          },
          {
            "date": "2025-02-08",
            "count": 1
          },
          {
            "date": "2025-02-12",
            "count": 1
          },
          {
            "date": "2025-03-16",
            "count": 1
          },
          {
            "date": "2025-03-29",
            "count": 1
          },
          {
            "date": "2025-04-05",
            "count": 1
          },
          {
            "date": "2025-05-01",
            "count": 1
          },
          {
            "date": "2025-07-04",
            "count": 1
          },
          {
            "date": "2025-07-07",
            "count": 1
          },
          {
            "date": "2025-07-09",
            "count": 1
          },
          {
            "date": "2025-07-18",
            "count": 1
          },
          {
            "date": "2025-08-10",
            "count": 1
          },
          {
            "date": "2025-08-11",
            "count": 1
          },
          {
            "date": "2025-08-30",
            "count": 1
          },
          {
            "date": "2025-10-12",
            "count": 1
          },
          {
            "date": "2025-10-17",
            "count": 1
          },
          {
            "date": "2025-11-04",
            "count": 1
          },
          {
            "date": "2026-01-11",
            "count": 1
          },
          {
            "date": "2026-01-12",
            "count": 1
          },
          {
            "date": "2026-03-17",
            "count": 1
          },
          {
            "date": "2026-03-21",
            "count": 1
          },
          {
            "date": "2026-03-31",
            "count": 1
          },
          {
            "date": "2026-04-03",
            "count": 1
          },
          {
            "date": "2026-04-23",
            "count": 1
          },
          {
            "date": "2026-05-06",
            "count": 1
          },
          {
            "date": "2026-06-11",
            "count": 1
          },
          {
            "date": "2026-06-14",
            "count": 1
          },
          {
            "date": "2026-07-01",
            "count": 1
          },
          {
            "date": "2026-07-07",
            "count": 1
          },
          {
            "date": "2026-07-11",
            "count": 2
          },
          {
            "date": "2026-07-12",
            "count": 1
          },
          {
            "date": "2026-07-13",
            "count": 3
          },
          {
            "date": "2026-07-15",
            "count": 3
          },
          {
            "date": "2026-07-17",
            "count": 3
          },
          {
            "date": "2026-07-19",
            "count": 1
          },
          {
            "date": "2026-07-21",
            "count": 5
          },
          {
            "date": "2026-07-22",
            "count": 2
          },
          {
            "date": "2026-07-23",
            "count": 2
          }
        ],
        "complete": true,
        "collected": 58,
        "total_forks": 58
      },
      "star_history": null,
      "open_issues_and_prs": 2
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 315673,
      "source_files_sampled": 245,
      "oversized_source_files": 21,
      "agent_instruction_files": [
        "AGENTS.md"
      ],
      "agent_instruction_max_bytes": 5514
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml",
        "requirements.txt"
      ],
      "advisories": {
        "error": "No resolved dependencies carried a version and a supported ecosystem",
        "scope": "repository_graph",
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 16,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "pyside6-essentials",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "Pillow",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "cx-freeze",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=8.3.0"
        },
        {
          "name": "nerdfont",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "packaging",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "palsav-flex",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "brotli",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "cbor2",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "msgpack",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "zstandard",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "orjson",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "py7zr",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "nuitka",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=4.1.2"
        },
        {
          "name": "loguru",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.7.3"
        },
        {
          "name": "orjson",
          "manifest": "src/palsav/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.11.8"
        },
        {
          "name": "palooz",
          "manifest": "src/palsav/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "setuptools",
          "manifest": "src/palsav/pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=68.0"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "brotli",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "cbor2",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "cx-freeze",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "loguru",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "msgpack",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "nerdfont",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "nuitka",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "orjson",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "palsav-flex",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "pillow",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "py7zr",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "pyside6-essentials",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "setuptools",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "zstandard",
            "direct": true,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 16,
        "direct_count": 15,
        "indirect_count": 1
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 17,
        "open_issues": 2,
        "closed_ratio": 0.989,
        "closed_issues": 188,
        "closed_unmerged_prs": 15
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "deafdudecomputers",
          "commits": 213,
          "avatar_url": "https://avatars.githubusercontent.com/u/164821928?v=4"
        },
        {
          "type": "User",
          "login": "sirj0k3r",
          "commits": 8,
          "avatar_url": "https://avatars.githubusercontent.com/u/31699976?v=4"
        },
        {
          "type": "User",
          "login": "saintpepsicola",
          "commits": 6,
          "avatar_url": "https://avatars.githubusercontent.com/u/23740604?v=4"
        },
        {
          "type": "User",
          "login": "CyrixJD115",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/129636984?v=4"
        },
        {
          "type": "User",
          "login": "msansen",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/2265488?v=4"
        }
      ],
      "contributors_sampled": 5,
      "top_contributor_share": 0.93
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "build-all-and-release.yml",
        "build-all-and-test.yml",
        "discord.yml",
        "nexus-upload.yml",
        "test-build.yml",
        "test-changelog-translation.yml",
        "test-cx-standalone.yml",
        "test-release-notes.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 24 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": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 9,
            "reason": "1 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "cbd98c44923b18d8010d94cc1ca10d1657d55c17",
        "ran_at": "2026-07-24T15:17:51Z",
        "aggregate_score": 3.5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": null,
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-22T01:24:57Z",
      "ci_last_conclusion": null,
      "oldest_open_issues": [
        {
          "number": 221,
          "created_at": "2026-07-24T07:10:58Z",
          "last_comment_at": "2026-07-24T08:15:53Z",
          "last_comment_author": "deafdudecomputers"
        },
        {
          "number": 222,
          "created_at": "2026-07-24T12:52:45Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/deafdudecomputers/PalworldSaveTools",
    "host": "github.com",
    "name": "PalworldSaveTools",
    "owner": "deafdudecomputers"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 54,
      "inputs": {
        "security": 35,
        "vitality": 75,
        "community": 57,
        "governance": 39,
        "engineering": 62
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 75,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "commits_last_year": 225,
              "human_commit_share": 1,
              "days_since_last_push": 0,
              "active_weeks_last_year": 2
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "2/52 weeks with commits",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "225 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 225
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 100,
              "latest_release_tag": "v2.2.1",
              "releases_from_tags": false,
              "days_since_latest_release": 1,
              "mean_days_between_releases": 0.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "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": 0,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 0 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "moderate",
        "name": "Community & Adoption",
        "value": 57,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 64,
            "inputs": {
              "forks": 58,
              "stars": 597,
              "watchers": 8,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "597 stars",
                "points": 45,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 597
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "58 forks",
                "points": 14.6,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 58
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "8 watchers",
                "points": 4.7,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 8
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 39,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 17,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 5,
              "top_contributor_share": 0.93
            },
            "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 93% of commits",
                "points": 1.6,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 93
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "5 contributors",
                "points": 6.8,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "moderate",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 66,
            "inputs": {
              "merged_prs": 17,
              "open_issues": 2,
              "closed_issues": 188,
              "issue_closed_ratio": 0.989,
              "closed_unmerged_prs": 15
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "99% of issues closed",
                "points": 46.2,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 99
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "17/32 decided PRs merged",
                "points": 20.3,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 17,
                      "decided": 32
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "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": 38,
            "inputs": {
              "followers": 17,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "deafdudecomputers",
              "public_repos": 7,
              "account_age_days": 851
            },
            "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": "17 followers of deafdudecomputers",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 17,
                      "login": "deafdudecomputers"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "7 public repos, account ~2 yr old",
                "points": 11.2,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 7
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 2
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 62,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "8 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 8
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": "https://discord.gg/sYcZwcT4cT",
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": "https://discord.gg/sYcZwcT4cT",
                "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": "at_risk",
        "name": "Security",
        "value": 35,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 35,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 3.5
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 24 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 not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "1 existing vulnerabilities detected",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "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": 2
            },
            "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": "at_risk",
        "name": "AI Readiness",
        "value": 49,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "good",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.66,
              "agent_instruction_files": [
                "AGENTS.md"
              ],
              "agent_instruction_max_bytes": 5514
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "66 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 35.2,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 66,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "critical",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 26,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.02,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "2 of the last 100 commits agent-authored or agent-credited",
                "points": 4,
                "status": "partial",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 2,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 315673,
              "source_files_sampled": 245,
              "oversized_source_files": 21
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "21/245 source files over 60KB",
                "points": 50.3,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 245,
                      "oversized": 21
                    }
                  }
                ],
                "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",
    "Could not fetch pypi package 'PalworldSaveTools' from its registry",
    "Could not fetch pypi package 'palsav-flex' from its registry",
    "No resolved dependencies carried a version and a supported ecosystem"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-24T15:18:07.740991Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/d/deafdudecomputers/PalworldSaveTools.svg",
  "full_name": "deafdudecomputers/PalworldSaveTools",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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 statistics.