公开记录
软件健康报告模式 0.23.0 · 指标 1.13.0 · 2026-07-21 15:51 UTC

INAVFlights / inav-configurator

JavaScript · HTMLGPL-3.0★ 727 星标⑂ 0 复刻始于 2026年3月在 GitHub 上查看 ↗

INAVFlights/inav-configurator 的健康指数为 100 分中的 46 分,处于「存在风险」区间。 其得分最高的类别是Vitality(57/100),最低的是Security(19/100)。 最近一次更新在 126 天前。 近期的大部分工作由 3 位贡献者完成。

46
总分 / 100
存在风险

软件健康指数

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

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

评分画像

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

所有权

0 关注者2 个公开仓库始于 2026年3月

该仓库由组织支持——共同承担、可问责的托管责任,可延续于任何单一维护者之后。

按类别列示的指标

活力

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

57中等 · 占总体的 22%

开发活跃度

41存在风险
评分方式
9.9/36推送新近度 — 最近一次推送于 126 天前
13.2/36提交节奏 — 52 周中有 19 周有提交
18/18提交量 — 最近一年 316 次提交
0/10OpenSSF Scorecard:Maintained — 0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
所用输入
commits_last_year316
human_commit_share1
days_since_last_push126
active_weeks_last_year19

发布纪律

81良好
评分方式
27/27有发布版本 — 已发布 84 个发布版本
27/36发布时效 — 最近一次发布版本于 126 天前
27/27发布节奏 — 约每 0 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — Project has not signed or included provenance with any releases.
所用输入
releases_count84
latest_release_taguntagged-58a74ccc453672f866b7
releases_from_tags
days_since_latest_release126
mean_days_between_releases0

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

56中等 · 占总体的 18%
评分方式
46.4/60星标 — 727 个星标
0/25复刻 — 0 个复刻
14.6/15关注者 — 420 位关注者
所用输入
forks0
stars727
watchers420
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonwindow_too_short

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(GPL-3.0)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template

可持续性与治理

项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?

39存在风险 · 占总体的 24%
评分方式
36/54巴士系数 — 3 位贡献者贡献了半数提交
16.8/22.5提交分布 — 头号贡献者编写了 25% 的提交
13.5/13.5贡献者广度 — 100 位贡献者
10/10OpenSSF Scorecard:Contributors — project has 8 contributing companies or organizations
所用输入
bus_factor3
contributors_sampled100
top_contributor_share0.254
评分方式
0/46.8议题解决 — 没有议题或无数据
0/38.3PR 接受 — 没有已裁定的拉取请求或无数据
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决, PR 接受。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
0/25所有者影响力 — INAVFlights 有 0 位关注者
4.2/25既往记录 — 2 个公开仓库,账户约 0 年
所用输入
followers0
owner_typeOrganization
is_verified
owner_loginINAVFlights
public_repos2
account_age_days139

工程质量

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

56中等 · 占总体的 20%

工程实践

60中等
评分方式
24/24CI 工作流 — 3 个工作流
24/24存在测试
0/16Linter 配置
0/9.6Pre-commit 钩子
0/6.4.editorconfig
0/20OpenSSF Scorecard:CI-Tests — 无数据
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config
已排除计分(无数据或不适用):OpenSSF Scorecard:CI-Tests。 其余权重已重新归一化。

文档

50中等
评分方式
30/30README
0/25文档目录
0/15文档 / 主页站点
0/10仓库描述
10/10主题标签 — 6 个主题标签
10/10Wiki
所用输入
topicsaircraft, drones, hacktoberfest, inav, inav-configurator, uav
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

19危急 · 占总体的 16%

安全态势

19危急
评分方式
3.8/7.5Binary-Artifacts — binaries present in source code
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 无数据
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
2.5/2.5Contributors — project has 8 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5许可证 — license file detected
0/7.5Maintained — 0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
0/5Packaging — 无数据
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
0/7.5Vulnerabilities — 83 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate1.9
已排除计分(无数据或不适用):ci_tests, packaging。 其余权重已重新归一化。

AI 就绪度

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

56中等 · 占总体的 0%
评分方式
45/45代理指令 — CLAUDE.md, js/transpiler/CLAUDE.md
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 85 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.85
agent_instruction_filesCLAUDE.md, js/transpiler/CLAUDE.md
agent_instruction_max_bytes5,925
评分方式
0/18一条命令的引导启动
22/22自动化测试
0/11Lint / 格式化配置
0/11静态类型检查
10/10可复现环境 — lockfile
10/10已体现的代理实践 — 最近 100 次提交中有 5 次由代理编写或署名代理
0/8自动化维护 — 未观察到自动依赖更新
0/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
所用输入
has_nix
has_tests
lockfilesyarn.lock
has_dockerfile
typed_language
bootstrap_files
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0.05
toolchain_manifests
dependency_bot_commit_share0
评分方式
0/45可类型检查的代码 — JavaScript,未配置类型检查
54.3/55可控的文件大小 — 采样的 237 个源文件中有 3 个超过 60KB
所用输入
primary_languageJavaScript
largest_source_bytes187,643
source_files_sampled237
oversized_source_files3

机器可读接口

40存在风险
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
0/20MCP 服务器
40/40可运行示例 — examples
所用输入
example_dirsexamples
has_mcp_signal
api_schema_files

关键数据

727GitHub 星标
100贡献者
316最近 12 个月提交数
126距最近推送天数
84发布版本数
3巴士系数(bus factor)
0开放议题
npm软件包生态系统数

数据采集警告

  • Could not fetch npm package 'inav-configurator' from its registry
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

更多细节

Star 与 Fork 历史 727 ★ / 0 ⇿
727Star
84发布

每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。

2503755006257507263202026-032026-032026-03
主版本 8次版本 11修订 26
OpenSSF Scorecard 1.9 / 10
1.9综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-07-21 15:51 UTC

5Binary-Artifactsbinaries present in source code
0Branch-Protectionbranch protection not enabled on development/release branches
不适用CI-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
10Contributorsproject has 8 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintained0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
不适用Packagingpackaging 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
0Vulnerabilities83 existing vulnerabilities detected
直接依赖 30
注册表软件包版本约束清单文件
npmacorn^8.14.0package.json
npm@electron/remote^2.1.3package.json
npmbrowserify-fs^1.0.0package.json
npmchart.js^4.4.1package.json
npmd3^7.9.0package.json
npmelectron-squirrel-startup^1.0.1package.json
npmelectron-store^10.1.0package.json
npmelectron-window-state^5.0.3package.json
npmfs0.0.1-securitypackage.json
npmi18next^25.5.0package.json
npminflection^3.0.2package.json
npmjbox^1.3.3package.json
npmjquery^3.7.1package.json
npmjquery-ui-dist1.13.3package.json
npmjquery-textcomplete^1.8.5package.json
npmmarked^16.2.1package.json
npmminimist^1.2.8package.json
npmmonaco-editor^0.54.0package.json
npmnouislider^15.8.1package.json
npmol^10.6.1package.json
npmpromise-map-series^0.3.0package.json
npmsemver^7.7.2package.json
npmserialport^13.0.0package.json
npmsmalltalk^4.1.2package.json
npmtemp^0.9.4package.json
npmthree^0.180.0package.json
npmthrottle-debounce^5.0.2package.json
npmusb^2.16.0package.json
npmwnumb^1.2.0package.json
npmxml2js^0.6.2package.json
全部依赖 未采集

本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [
        "aircraft",
        "drones",
        "hacktoberfest",
        "inav",
        "inav-configurator",
        "uav"
      ],
      "is_fork": false,
      "size_kb": 100728,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "CSS": 198464,
        "HTML": 632731,
        "Ruby": 13410,
        "JavaScript": 2286018
      },
      "pushed_at": "2026-03-17T02:03:31Z",
      "created_at": "2026-03-04T01:49:26Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-21T04:46:26Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "GPL-3.0",
      "default_branch": "master",
      "license_spdx_raw": "GPL-3.0",
      "primary_language": "JavaScript",
      "significant_languages": [
        "JavaScript",
        "HTML"
      ]
    },
    "owner": {
      "blog": "http://www.inavflight.com",
      "name": "INAVFlight",
      "type": "Organization",
      "login": "INAVFlights",
      "company": null,
      "location": null,
      "followers": 0,
      "avatar_url": "https://avatars.githubusercontent.com/u/265407387?v=4",
      "created_at": "2026-03-04T00:48:34Z",
      "is_verified": null,
      "public_repos": 2,
      "account_age_days": 139
    },
    "license": {
      "state": "standard",
      "spdx_id": "GPL-3.0",
      "raw_spdx": "GPL-3.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "untagged-58a74ccc453672f866b7",
          "kind": "other",
          "published_at": "2026-03-17T01:21:58Z"
        },
        {
          "tag": "9.0.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:22:15Z"
        },
        {
          "tag": "9.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:22:32Z"
        },
        {
          "tag": "9.0.0-RC4",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:22:49Z"
        },
        {
          "tag": "9.0.0-RC3",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:23:06Z"
        },
        {
          "tag": "9.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:23:23Z"
        },
        {
          "tag": "8.0.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:23:43Z"
        },
        {
          "tag": "8.0.1-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:24:00Z"
        },
        {
          "tag": "8.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:24:17Z"
        },
        {
          "tag": "8.0.0-RC4",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:24:35Z"
        },
        {
          "tag": "8.0.0-RC3",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:24:49Z"
        },
        {
          "tag": "8.0.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:25:03Z"
        },
        {
          "tag": "8.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:25:18Z"
        },
        {
          "tag": "7.1.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:25:31Z"
        },
        {
          "tag": "7.1.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:25:44Z"
        },
        {
          "tag": "7.1.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:25:57Z"
        },
        {
          "tag": "7.1.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:26:10Z"
        },
        {
          "tag": "7.0.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:26:22Z"
        },
        {
          "tag": "7.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:26:33Z"
        },
        {
          "tag": "7.0.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:26:42Z"
        },
        {
          "tag": "7.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:26:52Z"
        },
        {
          "tag": "6.1.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:27:06Z"
        },
        {
          "tag": "6.1.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:27:18Z"
        },
        {
          "tag": "6.0.0-RC4",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:27:42Z"
        },
        {
          "tag": "6.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:27:30Z"
        },
        {
          "tag": "6.0.0-RC3",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:27:54Z"
        },
        {
          "tag": "6.0.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:28:06Z"
        },
        {
          "tag": "6.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:28:17Z"
        },
        {
          "tag": "6.0.0-FP2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:28:27Z"
        },
        {
          "tag": "6.0.0-FP1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:28:36Z"
        },
        {
          "tag": "5.1.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:28:45Z"
        },
        {
          "tag": "5.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:28:53Z"
        },
        {
          "tag": "5.0.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:29:00Z"
        },
        {
          "tag": "5.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:29:08Z"
        },
        {
          "tag": "4.1.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:29:15Z"
        },
        {
          "tag": "4.1.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:29:22Z"
        },
        {
          "tag": "4.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:29:28Z"
        },
        {
          "tag": "4.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:29:35Z"
        },
        {
          "tag": "3.0.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:29:42Z"
        },
        {
          "tag": "3.0.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:29:49Z"
        },
        {
          "tag": "3.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:29:56Z"
        },
        {
          "tag": "3.0.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:30:09Z"
        },
        {
          "tag": "3.0.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:30:03Z"
        },
        {
          "tag": "2.6.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:30:15Z"
        },
        {
          "tag": "2.6.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:30:23Z"
        },
        {
          "tag": "2.6.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:30:30Z"
        },
        {
          "tag": "2.5.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:30:37Z"
        },
        {
          "tag": "2.5.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:30:44Z"
        },
        {
          "tag": "2.5.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:30:51Z"
        },
        {
          "tag": "2.4.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:30:59Z"
        },
        {
          "tag": "2.4.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:31:06Z"
        },
        {
          "tag": "2.4.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:31:13Z"
        },
        {
          "tag": "2.4.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:31:20Z"
        },
        {
          "tag": "2.3.3",
          "kind": "patch",
          "published_at": "2026-03-17T01:31:27Z"
        },
        {
          "tag": "2.3.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:31:35Z"
        },
        {
          "tag": "2.3.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:31:42Z"
        },
        {
          "tag": "2.3.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:31:49Z"
        },
        {
          "tag": "2.3.0-RC",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:31:56Z"
        },
        {
          "tag": "2.3.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:32:03Z"
        },
        {
          "tag": "2.3.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:32:09Z"
        },
        {
          "tag": "2.2.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:32:15Z"
        },
        {
          "tag": "2.2.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:32:22Z"
        },
        {
          "tag": "2.2.0-RC2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:32:29Z"
        },
        {
          "tag": "2.2.0-RC1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:32:36Z"
        },
        {
          "tag": "2.1.4",
          "kind": "patch",
          "published_at": "2026-03-17T01:32:43Z"
        },
        {
          "tag": "2.1.3",
          "kind": "patch",
          "published_at": "2026-03-17T01:32:50Z"
        },
        {
          "tag": "2.1.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:32:56Z"
        },
        {
          "tag": "2.1.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:33:02Z"
        },
        {
          "tag": "2.1.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:33:08Z"
        },
        {
          "tag": "2.0.0",
          "kind": "major",
          "published_at": "2026-03-17T01:33:14Z"
        },
        {
          "tag": "2.0.0-rc3",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:33:21Z"
        },
        {
          "tag": "2.0.0-rc2",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:33:27Z"
        },
        {
          "tag": "2.0.0-rc1",
          "kind": "prerelease",
          "published_at": "2026-03-17T01:33:32Z"
        },
        {
          "tag": "1.9.3",
          "kind": "patch",
          "published_at": "2026-03-17T01:33:37Z"
        },
        {
          "tag": "1.9.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:33:41Z"
        },
        {
          "tag": "1.9.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:33:46Z"
        },
        {
          "tag": "1.8.1",
          "kind": "patch",
          "published_at": "2026-03-17T01:33:51Z"
        },
        {
          "tag": "1.8.0",
          "kind": "minor",
          "published_at": "2026-03-17T01:33:55Z"
        },
        {
          "tag": "1.7.3",
          "kind": "patch",
          "published_at": "2026-03-17T01:33:59Z"
        },
        {
          "tag": "1.7.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:34:02Z"
        },
        {
          "tag": "1.6.3",
          "kind": "patch",
          "published_at": "2026-03-17T01:34:04Z"
        },
        {
          "tag": "1.6.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:34:06Z"
        },
        {
          "tag": "1.6",
          "kind": "other",
          "published_at": "2026-03-17T01:34:08Z"
        },
        {
          "tag": "v1.5.2",
          "kind": "patch",
          "published_at": "2026-03-17T01:34:09Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "705cd1a1a43c43974a6980042eb6a2ca8d883f1e",
          "body": null,
          "is_bot": false,
          "headline": "Update README.md",
          "author_name": "INAVFlightDev",
          "author_login": "INAVFlightDev",
          "committed_at": "2026-03-17T02:03:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "955513e1dd5a82935b6398a97d85541372a82f36",
          "body": "Maintenance 9.x",
          "is_bot": false,
          "headline": "Merge pull request #2547 from iNavFlight/maintenance-9.x",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-30T16:41:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a85fc540678748e1d227b2c03b51c3d1a8d4c52",
          "body": "Fix BLE byte counter regression introduced in 9.0.0",
          "is_bot": false,
          "headline": "Merge pull request #2542 from sensei-hacker/fix/ble-byte-counter",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-30T15:32:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "545ed921fa674ee9c20120eb929da8d3e7381e7e",
          "body": "User confirmed BLE connection is working correctly after the byte\ncounter fix, but reported slower performance compared to 8.0.1.\n\nAnalysis showed 4 console.log() statements in the data path:\n- 2 logs on every BLE notification received (hot path)\n- 2 logs during listener add/remove (cold path)\n\nThe \n[…]\nation as they\nexecute on every 20-byte BLE packet received. Removed all 4\ndebug logs as they were marked TODO for removal after testing.\n\nThe core fix (using _onReceiveListeners array) remains intact.",
          "is_bot": false,
          "headline": "Remove debug logging from BLE connection fix",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-30T02:55:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3742221de5c5c6021792f9ffe6ddf73e670e7acc",
          "body": "In 8.0.0, addOnReceiveListener() called addOnReceiveCallback() which\nregistered callbacks in both _onReceiveListeners and the BLE-specific\n_onCharateristicValueChangedListeners array. In 9.0.0 this was removed\nto \"avoid duplicate push\", but Serial's addOnReceiveCallback() pushes\nto _onReceiveListene\n[…]\nlign BLE with Serial by using _onReceiveListeners throughout,\nremoving the now-unnecessary _onCharateristicValueChangedListeners array.\nIncludes debug logging to aid diagnosis if further issues arise.",
          "is_bot": false,
          "headline": "Fix BLE byte counter regression introduced in 9.0.0",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-28T05:47:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "23f031c1c6e840975a9adcb15d95656919b0c302",
          "body": "Update SITL binaries for 9.0.0 final release",
          "is_bot": false,
          "headline": "Merge pull request #2520 from sensei-hacker/update-sitl-9.0.0-final",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-28T05:32:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b1ef976e67755af747f1618a220f3179a90d8662",
          "body": "Fix formatting of OSD element document",
          "is_bot": false,
          "headline": "Merge pull request #2505 from iNavFlight/MrD-RC-patch-1",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-28T05:27:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d7a1e84093281cf11690e5e3925a2a03890cc864",
          "body": "Remove 'set' prefix from nav_fw keys",
          "is_bot": false,
          "headline": "Merge pull request #2537 from b14ckyy/b14ckyy-corrected-vspeed-defaults",
          "author_name": "b14ckyy",
          "author_login": "b14ckyy",
          "committed_at": "2026-01-25T17:52:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0ded586873aeb8e2bd3cb3d8e1a350bf76089db4",
          "body": "oops",
          "is_bot": false,
          "headline": "Remove 'set' prefix from nav_fw keys",
          "author_name": "b14ckyy",
          "author_login": "b14ckyy",
          "committed_at": "2026-01-25T16:46:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7f6b27925e0aba9c9b50950875dcb4a15588de09",
          "body": "correcting vspeed defaults in presets",
          "is_bot": false,
          "headline": "Merge pull request #2533 from b14ckyy/b14ckyy-corrected-vspeed-defaults",
          "author_name": "b14ckyy",
          "author_login": "b14ckyy",
          "committed_at": "2026-01-24T19:04:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b75aad392cca6d2a126918f326292e677f8c5ee",
          "body": "removed old pre 9.0 values I missed",
          "is_bot": false,
          "headline": "Update defaults_dialog_entries.js",
          "author_name": "b14ckyy",
          "author_login": "b14ckyy",
          "committed_at": "2026-01-22T09:25:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b917e15cbfc2611b93302c95af45c74941f13f2e",
          "body": null,
          "is_bot": false,
          "headline": "Added correct VSpeed PIDFF parameters for FW-WT",
          "author_name": "b14ckyy",
          "author_login": "b14ckyy",
          "committed_at": "2026-01-22T09:21:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "882c18386e7e5eddce15e7d03e9a6868caae8a8b",
          "body": "- Linux x64 SITL: built locally with glibc 2.34 compatibility\n- Linux arm64, macOS, Windows SITL: from nightly v9.0.0-20260114.184\n- Firmware commit: a7932b92eadd92ba7851a009a5c974b9cc24835d\n- All binaries match 9.0.0 final release candidate",
          "is_bot": false,
          "headline": "Update SITL binaries for 9.0.0 final release",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-14T21:57:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aed18934a6015317d809e8381b7f88cbcfc9d844",
          "body": "…rt-esm\n\nFix: Re-enable terrain elevation chart with Chart.js ESM support",
          "is_bot": false,
          "headline": "Merge pull request #2518 from sensei-hacker/fix/terrain-elevation-cha…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-13T15:41:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "73df5e7d46dced331a9ec087d78d75af0f3d8a24",
          "body": "…aults\n\nAdd TPA rate defaults to fixed-wing presets",
          "is_bot": false,
          "headline": "Merge pull request #2515 from sensei-hacker/platform-specific-tpa-def…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-13T15:40:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1652298e07bd9c5235a91e8dd018ee8c72aee368",
          "body": "Fix transpiler validation and improve error messages",
          "is_bot": false,
          "headline": "Merge pull request #2514 from sensei-hacker/fix-transpiler-validation",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-13T15:39:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f379acaf0adaea662f7ab839dbee0754d7d507c6",
          "body": "…aries\n\nFix postPackage hook to remove non-native SITL binaries from macOS builds",
          "is_bot": false,
          "headline": "Merge pull request #2508 from sensei-hacker/fix-macos-dmg-windows-bin…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-13T15:38:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9649161e611ec57301bc17c9bc43d00056c11441",
          "body": "Update ru translation",
          "is_bot": false,
          "headline": "Merge pull request #2506 from funkill/update-ru-translation",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-13T15:37:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9bed4c09d226aaabbf62f8e45a0321c5d9f6f8a7",
          "body": "readme: Add debugging info",
          "is_bot": false,
          "headline": "Merge pull request #2509 from sensei-hacker/docs_add_debug_commands",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-13T15:32:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bef73fc5288f7160b21d1a07072663c0a6ea8aaf",
          "body": "Per code review feedback, adds two important improvements:\n\n1. Race condition protection:\n   - Track elevation update sequence number\n   - Ignore stale data from late-returning API calls\n   - Prevents chart showing outdated elevation when waypoints dragged rapidly\n\n2. Disable chart animations during\n[…]\n operations\n   - Prevents animation queueing and visual lag\n\nThese fixes ensure the chart always shows current data and responds\nsmoothly even with rapid waypoint dragging or slow network connections.",
          "is_bot": false,
          "headline": "Fix: Add race condition protection and disable chart animations",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f0a1ffdd803a3da55be8a6300aaf73010085c7c3",
          "body": "…cted\n\nPreviously, plotElevation() was only called if the dragged waypoint\nmatched selectedMarker. This meant dragging an unselected waypoint\nwouldn't update the chart.\n\nNow plotElevation() is called for all waypoint drags:\n- If waypoint is selected: updates elevation + runs full async logic\n- If waypoint is not selected: updates elevation chart only\n\nThis ensures the elevation profile always reflects the current mission\ngeometry after any waypoint is moved.",
          "is_bot": false,
          "headline": "Fix: Update elevation chart when dragging any waypoint, not just sele…",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b13a08380448bf4fb5bebede0ba256f9ea8c8a04",
          "body": "…ctivity\n\nWhen waypoints are dragged, the elevation chart should update smoothly.\nThe previous approach of destroying and recreating the chart on every\nupdate was causing the chart to not refresh when waypoints were moved.\n\nChart.js update() method is designed for this use case:\n- Preserves the char\n[…]\ntance\n- Updates data and options\n- Triggers smooth re-render with animations\n- More efficient than destroy/recreate\n\nThis fixes the issue where dragging a waypoint didn't update the\nelevation profile.",
          "is_bot": false,
          "headline": "Fix: Use chart.update() instead of destroy/recreate for better intera…",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0c5229e208617765d627bf758893ae0549c107d4",
          "body": null,
          "is_bot": false,
          "headline": "Update yarn.lock for Chart.js v4.4.1 dependency",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b5f66e74cf3396af617db3306427acbed467c3bb",
          "body": "Code review identified several issues that needed addressing:\n\nCRITICAL fixes:\n- Replace hardcoded test data in empty mission case with proper empty chart\n- Add canvas element validation before Chart instantiation\n- Remove all unused Plotly code structures (trace objects, layout vars)\n- Fix chart ti\n[…]\nter destruction\n- Add console error messages for debugging\n\nThe plotElevation() function is now a clean Chart.js-only implementation\nwithout any Plotly remnants, proper error handling, and validation.",
          "is_bot": false,
          "headline": "Refactor: Clean up plotElevation() and remove Plotly remnants",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "77893b4c44abb8dafb021c86697bf85d4c72da57",
          "body": "The plotElevation() function had Chart.js code only for empty missions\n(dummy data). When missions had waypoints, it prepared elevation data\nbut only had a commented-out Plotly.newPlot() call, so no chart\nrendered.\n\nChanges:\n- Add Chart.js rendering after elevation data preparation (line 4352+)\n- Co\n[…]\nt markers)\n- Properly destroy existing chart before creating new one\n- Store chart instance globally for cleanup on subsequent calls\n\nBoth empty and non-empty mission cases now create Chart.js charts.",
          "is_bot": false,
          "headline": "Fix: Add Chart.js rendering for actual mission elevation data",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "415e5e70d74a1c4195b05fbb72e304d9e7204aba",
          "body": "The plotElevation() function calls `new Chart()` which expects Chart\nto be available in the global scope. While we correctly imported\nChart.js as an ES module, it was only available within the module\nscope. This change exposes Chart on the window object so the\nelevation plotting function can access it.",
          "is_bot": false,
          "headline": "Fix: Make Chart.js globally accessible for plotElevation",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "393c8b60fdf4124444ec0f7cf4abc0c6a13970e3",
          "body": null,
          "is_bot": false,
          "headline": "Fix: Restore comment markers broken during uncomment",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "70fc41ba0949c7e5c89653b018d8b70ad62ecac6",
          "body": "The plotElevation() function was commented out in commit 8d5870b0ae\ndue to ESM module compatibility issues. This fix:\n- Adds Chart.js v4.4.1 with full ESM support to package.json\n- Imports Chart.js properly as ES module\n- Uncomments the plotElevation() function\n\nThis restores the terrain elevation profile chart feature for\nmission planning safety checks.",
          "is_bot": false,
          "headline": "Fix: Re-enable terrain elevation chart with Chart.js ESM support",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-12T19:58:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61c48fe0a8cd124fd0e3bb52db00e31cd065d822",
          "body": "…y key\n\nPrevents generating error suggestions containing 'undefined' when\nnested.properties is an empty object.\n\nAddresses qodo-merge-pro bot suggestion on PR #2514.\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix: Add empty properties check before accessing first nested propert…",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-10T20:36:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "aa2b7d0f92806486c600487669b8d4a85db6db01",
          "body": "Set tpa_rate = 80 for airplane presets (\"Airplane with a Tail\" and\n\"Airplane without a Tail\"). This addresses feedback from PR #11222\nthat fixed-wing aircraft benefit from higher TPA values.\n\nMulticopter presets retain their existing tpa_rate = 20 setting.",
          "is_bot": false,
          "headline": "Add TPA rate defaults to fixed-wing presets",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-07T05:16:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "66bff8ffc7eeb26b9c063469a87704db5a342a95",
          "body": "Address Qodo code review feedback: check result.warnings.errors\ninstead of result.errors for semantic/validation errors.",
          "is_bot": false,
          "headline": "Fix test to check correct field (warnings.errors)",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-06T18:15:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c644cb847f762b1163ec578d60ad887d719e848",
          "body": "This commit completes the transpiler validation improvements by:\n\n1. Enhanced intermediate object detection (property_access_checker.js):\n   - Now uses raw API definitions instead of processed structure\n   - Simplified logic per user suggestion: just check typeof === 'object'\n   - Catches 2-level ob\n[…]\n with cryptic messages\n- Passing through to generate invalid logic conditions\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add comprehensive validation with improved error messages",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-06T04:02:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "36989e8043f1ac479be21aab2fc0a9d7e51f68a0",
          "body": "- Changed addError to addWarning with type 'error' in parser\n- Made transpile() fail when parser errors are present\n- Prevents silent code dropping from succeeding compilation",
          "is_bot": false,
          "headline": "Fix parser error reporting",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-06T03:26:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab583418098cb7219a054c32764e522bacc66173",
          "body": "This commit fixes three issues in the JavaScript Programming tab:\n\n1. **Fix silent code dropping for invalid function calls**\n   - Previously, code like `inav.override.flightAxis(180);` was silently\n     discarded without any error message\n   - Now generates clear error: \"Cannot call 'X' as a functi\n[…]\nming.js (lines 84, 91)\n     * tabs/javascript_programming.html (line 217-219)\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix transpiler validation and i18n display issues",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-06T03:21:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f733ffbb55c52e89a80755e780810e50f323a38e",
          "body": "Fix transpiler conflict detection and AST consistency",
          "is_bot": false,
          "headline": "Merge pull request #2513 from sensei-hacker/fix-transpiler-qodo-issues",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-06T01:36:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40402fea4dfdcfe085750ac63eddb522b75f5fb4",
          "body": "…d-naming\n\nFix decompiler to output whenChanged() instead of delta()",
          "is_bot": false,
          "headline": "Merge pull request #2504 from sensei-hacker/fix-decompiler-whenchange…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2026-01-06T01:36:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "50001fd0d3f6454475a0b0d293fbbcb367508adf",
          "body": "This addresses two issues identified by Qodo bot code review:\n\nIssue #3: Conflict detection indexing bug\n- Previously only ifthen handlers got unique keys\n- All on.always() blocks collapsed to single key, causing:\n  * False positives: assignments in different blocks flagged as conflicts\n  * Disabled\n[…]\n 'Literal', value: ...} objects\n- Maintains AST consistency throughout pipeline\n- Location: js/transpiler/transpiler/condition_generator.js:300,307\n\nAll 27 transpiler test suites pass with 0 failures.",
          "is_bot": false,
          "headline": "Fix transpiler conflict detection and AST consistency",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-31T23:40:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "64b906ffe92af4525f8048912f135f28edfd1c1e",
          "body": null,
          "is_bot": false,
          "headline": "readme: Add debugging info",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-31T06:08:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d28fa437f1473a58decd2ee4ca38e2d583c84e71",
          "body": "The previous fix used the wrong path for macOS app bundles. It was missing\nthe .app directory name in the path construction.\n\nProblem:\n- Was looking for: <outputPath>/Contents/Resources/sitl\n- Actual location: <outputPath>/<AppName>.app/Contents/Resources/sitl\n\nFix:\n- Dynamically find the .app bundle in outputPath\n- Construct correct path with .app directory included\n\nThis should now properly remove non-native SITL binaries from macOS builds.",
          "is_bot": false,
          "headline": "Fix macOS app bundle path - find .app directory dynamically",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-29T05:04:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "204c08231294a28f2f00acbff82f91f7f5221680",
          "body": "…ilds\n\nThe postPackage hook was using the wrong path for macOS app bundles,\ncausing it to fail to find and remove non-native SITL binaries.\n\nProblem:\n- macOS DMG packages included Windows SITL binaries (cygwin1.dll, inav_SITL.exe)\n- These should have been removed by the postPackage hook\n- Hook was l\n[…]\n platforms (darwin, win32, linux)\n- Console logging added to aid verification\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix postPackage hook to remove non-native SITL binaries from macOS bu…",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-29T04:37:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0f024778bc707294728ab949ff4fc25c9b4893e3",
          "body": null,
          "is_bot": false,
          "headline": "added translate for javascriptOptimizationsApplied",
          "author_name": "Funkill",
          "author_login": "funkill",
          "committed_at": "2025-12-29T04:36:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd9a73ef64d44b9872209950746b6ad7127296fa",
          "body": null,
          "is_bot": false,
          "headline": "added ru locale to files",
          "author_name": "Funkill",
          "author_login": "funkill",
          "committed_at": "2025-12-28T15:55:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6455a285f8bfaa8b6c3a55b14ffc28fe7521c650",
          "body": null,
          "is_bot": false,
          "headline": "translate new strings",
          "author_name": "Funkill",
          "author_login": "funkill",
          "committed_at": "2025-12-28T15:53:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "96ae77da9c17ae6ae3a14deb4f773718ae22c8e1",
          "body": null,
          "is_bot": false,
          "headline": "Fix rendering of md",
          "author_name": "Darren Lines",
          "author_login": "MrD-RC",
          "committed_at": "2025-12-28T07:31:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83dd3f49abaf5f0df404a249f17f70617b369868",
          "body": "- Decompiler now outputs whenChanged() to match the API definition\n- Use OPERAND_TYPE.LC from constants instead of hardcoded value\n- Add test for whenChanged() decompilation\n- Add test for OPERAND_TYPE.LC usage in handleNot()",
          "is_bot": false,
          "headline": "Fix decompiler to output whenChanged() instead of delta()",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-27T05:42:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a869ede0413a675a0d57a99e1f58c7b1d8a0e84e",
          "body": "Merge maintenance-9.x to master",
          "is_bot": false,
          "headline": "Merge pull request #2503 from iNavFlight/maintenance-9.x",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-26T22:15:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d0ded946dc6303ca9210a8932b90d208f8a08967",
          "body": "Fix MSP decoder state corruption and send_message parameter error",
          "is_bot": false,
          "headline": "Merge pull request #2502 from sensei-hacker/fix_double_crc",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T20:00:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b1f1f3d668213a2d891a36e8ebb47a9bd0a6958d",
          "body": "The 5th parameter of MSP.send_message() is protocolVersion (a number),\nnot an error callback. Passing a function caused 'Invalid MSP protocol\nversion' exception which propagated to the isolated context, breaking\nserial communication until reconnect.",
          "is_bot": false,
          "headline": "Fix incorrect send_message parameter in loadLogicConditions",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T19:53:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c9f8d59691c5c5ec1155ed38f4ebb855713d2e80",
          "body": null,
          "is_bot": false,
          "headline": "reset state if processData throws, so the CRC isn't re-entered",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T19:33:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c2007bc916cf368162f22a975b07ad2a915d92f5",
          "body": "Update SITL binaries for 9.0.0-RC4",
          "is_bot": false,
          "headline": "Merge pull request #2500 from sensei-hacker/update-sitl-9.0.0-rc4",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T16:07:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26b1e8492314a39c0ea855a31c4635b3b52b5252",
          "body": "- Linux x64: Built locally with glibc 2.34 for Ubuntu 22.04 LTS compatibility\n- Linux arm64: From CI\n- macOS: From CI\n- Windows: From CI (includes cygwin1.dll from PR #11203)",
          "is_bot": false,
          "headline": "Update SITL binaries for 9.0.0-RC4",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T15:55:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b32d363b1cc9e946eaa3d1b459a54118113ccd4",
          "body": "Merge build fix from master to maintenance-9.x",
          "is_bot": false,
          "headline": "Merge pull request #2499 from iNavFlight/master",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T06:55:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d9d143105e7a27c39561547b80792ba6ebc9b64b",
          "body": "Fix SITL binary path resolution for dev and packaged modes",
          "is_bot": false,
          "headline": "Merge pull request #2498 from sensei-hacker/fix-sitl-path-resolution",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T06:41:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47d2a46767210b8f1da7c363595d8e93f7ebfffe",
          "body": "Fix SITL remove wrong architecture",
          "is_bot": false,
          "headline": "Merge pull request #2497 from sensei-hacker/master",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T06:18:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac7cb282a8d15fa686e4bed230eb2e91751996e9",
          "body": "The SITL feature was broken because the code looked for binaries in\nthe wrong location. The path used __dirname which points to the Vite\nbuild output (.vite/build/), but SITL binaries are in resources/public/sitl/.\n\nChanges:\n- Add getSitlBasePath() function that returns correct path based on\n  wheth\n[…]\netAppPath()/resources/public/sitl)\n- Add extraResource in forge.config.js to include SITL in packages\n- Add afterCopy hook to remove binaries for other platforms/architectures,\n  reducing package size",
          "is_bot": false,
          "headline": "Fix SITL remove wrong architecture",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T06:16:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0b8b5a6a6093a5085d795bc7937698dc8ae94d3e",
          "body": "The SITL feature was broken because the code looked for binaries in\nthe wrong location. The path used __dirname which points to the Vite\nbuild output (.vite/build/), but SITL binaries are in resources/public/sitl/.\n\nChanges:\n- Add getSitlBasePath() function that returns correct path based on\n  wheth\n[…]\netAppPath()/resources/public/sitl)\n- Add extraResource in forge.config.js to include SITL in packages\n- Add afterCopy hook to remove binaries for other platforms/architectures,\n  reducing package size",
          "is_bot": false,
          "headline": "Fix SITL binary path resolution for dev and packaged modes",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T06:04:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "01d957eb9548e6b214f07341b11778a8aaee8c94",
          "body": "Maintenance 9.x to master",
          "is_bot": false,
          "headline": "Merge pull request #2479 from iNavFlight/maintenance-9.x",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T05:22:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ac5180b0d7855f252795a5743cf75c783a149a51",
          "body": "Fix SITL binary path resolution for dev and packaged modes",
          "is_bot": false,
          "headline": "Merge pull request #2496 from sensei-hacker/fix-sitl-path-resolution",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T05:06:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34d26968c0966cdbdfa5ff2f366701d7d8d8452c",
          "body": "The SITL feature was broken because the code looked for binaries in\nthe wrong location. The path used __dirname which points to the Vite\nbuild output (.vite/build/), but SITL binaries are in resources/public/sitl/.\n\nChanges:\n- Add getSitlBasePath() function that returns correct path based on\n  wheth\n[…]\netAppPath()/resources/public/sitl)\n- Add extraResource in forge.config.js to include SITL in packages\n- Add afterCopy hook to remove binaries for other platforms/architectures,\n  reducing package size",
          "is_bot": false,
          "headline": "Fix SITL binary path resolution for dev and packaged modes",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-24T04:31:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5bf903c4aca5fcff7375cdadb64f6b5a3dcbeabd",
          "body": "…ing-error-handler\n\nFix logic conditions loading to handle MSP errors",
          "is_bot": false,
          "headline": "Merge pull request #2495 from sensei-hacker/fix-logic-conditions-load…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-23T23:43:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "212917f7b62bf5c55deee53d56f03140589c672b",
          "body": "Add error callback to MSP.send_message in processNextCondition() so that\nif an individual logic condition fetch fails, loading continues with the\nnext condition rather than halting indefinitely.\n\nPreviously, only a success callback was provided, meaning any MSP error\nwould stop the loading sequence without ever calling the final callback.",
          "is_bot": false,
          "headline": "Fix logic conditions loading to handle MSP errors",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-23T21:56:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6cce81e7fff4de6415288d198d3d21f08c7fb1f3",
          "body": "…iability\n\nFix serial connection reliability issues",
          "is_bot": false,
          "headline": "Merge pull request #2494 from sensei-hacker/fix-serial-connection-rel…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-23T21:33:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "19af8c4bf8579b925fc967c46eba81dbf215055d",
          "body": "…emove-destructuring\n\nRefactor JavaScript Programming to use fully namespaced inav.* syntax",
          "is_bot": false,
          "headline": "Merge pull request #2490 from sensei-hacker/fix-monaco-autocomplete-r…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-23T21:32:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e45a79ff4a9dc7e1568861e5a7ed99fcd561826",
          "body": "When serial port errors occurred, the port handle wasn't being properly\ncleaned up, leaving zombie handles that blocked reconnection attempts.\n\nChanges:\n- Add cleanup in error handler: removeAllListeners() + destroy()\n- Make connect() async to properly await cleanup of existing ports\n- Add 100ms del\n[…]\nfore close callback\n- Handle case where port exists but isn't open\n\nThis fixes the \"Resource temporarily unavailable Cannot lock port\"\nerror that occurred when reconnecting after a connection failure.",
          "is_bot": false,
          "headline": "Fix serial port handle leak causing \"Cannot lock port\" errors",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-23T02:56:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "da609414c79fea43eff29b0f7d69a564a15faabd",
          "body": "Two fixes for intermittent connection failures:\n\n1. Fix error handler in serial.js to correctly report errors\n   - The error handler was resolving with {error: false} when there\n     was an actual error, causing confusing \"connection canceled\"\n     messages and preventing proper error handling\n\n2. R\n[…]\ne connection sequence\n   - Add MSP.disconnect_cleanup() to reset decoder state\n   - This ensures garbage bytes or boot messages received during\n     USB enumeration don't corrupt the MSP decoder state",
          "is_bot": false,
          "headline": "Fix serial connection reliability issues",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-23T00:25:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c85b75a010b78855926f35e631a3f08100a1b3fa",
          "body": "…ns-9-rc3\n\nAdd missing ukrainian translations 9 rc",
          "is_bot": false,
          "headline": "Merge pull request #2491 from smsnvc/Add-missing-Ukrainian-translatio…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T17:23:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c67df60d2a97732ddc90701111aac21b7eaa2d1b",
          "body": "…s-9-rc",
          "is_bot": false,
          "headline": "Merge branch 'maintenance-9.x' into Add-missing-Ukrainian-translation…",
          "author_name": "smsnvc",
          "author_login": "smsnvc",
          "committed_at": "2025-12-21T17:04:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a8b37907bae41942873ed34ad80132e9c1d1eb71",
          "body": "…reach\n\nFix auto-select target functionality in firmware flasher",
          "is_bot": false,
          "headline": "Merge pull request #2489 from sensei-hacker/fix-auto-select-target-fo…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T16:50:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "768478f2100e4c20d521366c63544db9271d362d",
          "body": "Replace strict truthy check with duck typing that verifies the forEach\nmethod exists and is callable. This is more flexible and future-proof:\n- Works with arrays, NodeLists, and any iterable with forEach\n- More JavaScript-idiomatic (duck typing over type checking)\n- Focuses on behavior (\"can iterate\n[…]\nto Set, NodeList, or custom collection,\n  code continues to work without modification\n- More aligned with JavaScript best practices\n- Clearer intent: we care about iteration capability, not array type",
          "is_bot": false,
          "headline": "Improve forEach check with duck typing for future-proofing",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T16:34:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ade6997211db0c19b2a9cabeec5f8d816e2fb03",
          "body": "…tenance-9x\n\nFix blackbox save to file functionality",
          "is_bot": false,
          "headline": "Merge pull request #2488 from sensei-hacker/fix-dialog-undefined-main…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T16:11:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5a87c1feefc85531b93d6699ad4f5acef42d4962",
          "body": null,
          "is_bot": false,
          "headline": "Adding recent Ukrainian translations for INAV 9 RC",
          "author_name": "smsnvc",
          "author_login": "smsnvc",
          "committed_at": "2025-12-21T09:28:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0cf3278305dc8c2236256bbb7d0151fe568f3908",
          "body": null,
          "is_bot": false,
          "headline": "Adding recent Ukrainian translations for INAV 9 RC",
          "author_name": "smsnvc",
          "author_login": "smsnvc",
          "committed_at": "2025-12-21T09:08:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "508dc2d273f9130323359319d8ecaabbdce2dd84",
          "body": "The main process appendFile() handler throws/rejects on error, not\nresolves with an error object. The previous code checking `if (err)`\nin the .then() callback would never catch errors.\n\nThis fixes the bug by properly using .catch() to handle rejections.\n\nAddresses Qodo code review suggestion #1.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Fix error handling to use .catch() for promise rejection",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T03:20:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "74d75f1fb87d0ea607c8e401dbe8df117cd894dd",
          "body": "Fixes Qodo comment #2 from PR #2490.\n\nPreviously, flight axis overrides with unprefixed syntax (e.g.,\noverride.flightAxis.roll.angle) failed because the regex in\naction_generator.js matched against the raw target instead of\nnormalized target. This broke backward compatibility.\n\nChanges:\n- action_gen\n[…]\nchecker.js: Accept both prefixed and unprefixed targets\n- codegen.js: Normalize target in getOverrideOperation()\n- Added comprehensive test suite for flight axis overrides\n\nAll 27 test suites passing.",
          "is_bot": false,
          "headline": "Fix: Flight axis override backward compatibility",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T03:12:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "30f27fc021ba7c41aa55afe1c8a437a1742876e8",
          "body": "Added new test suite to verify consistent namespace-based routing:\n\nTests cover:\n- Helper function calls: inav.helpers.mapInput() vs mapInput() (backward compat)\n- Invalid namespace rejection: inav.pid[0].mapInput() should fail\n- Property access validation for all namespaces (flight, override, gvar,\n[…]\ny index validation (gvar, rc, pid)\n- Invalid namespace detection\n\nAlso added run_all_tests.cjs script to execute complete test suite.\n\nAll 26 test suites pass (25 existing + 1 new with 15 test cases).",
          "is_bot": false,
          "headline": "Add comprehensive namespace validation tests",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T02:47:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4e7743f2974f992480d895ed447b7595c8eb0458",
          "body": "Changed from prefix matching ('gvar[', 'rc[', 'events.', 'helpers.') to\nnamespace extraction for cleaner, more consistent routing.\n\nNew approach:\n1. Extract namespace (first word before . or [)\n2. Route to namespace-specific handler based on extracted namespace\n3. Special handlers only for array-bas\n[…]\ned the same way through checkApiPropertyAccess()\n\nBefore: Used prefix matching with special empty handlers for helpers/events\nAfter: Extract namespace, route consistently to special or generic handler",
          "is_bot": false,
          "headline": "Refactor: Consistent namespace-based routing in property access checker",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T02:40:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a3b9a9d32a550d9596d977e6a0500ca39c56eeaf",
          "body": "Removed extractHelperFunctionName() methods from both condition_generator.js\nand expression_generator.js. Inlined the namespace checking directly in\ngenerateCall() for better clarity and efficiency.\n\nBenefits:\n- More explicit: only checks namespace when callee.object.property.name === 'helpers'\n- Mo\n[…]\nobject?.property?.name === 'helpers') {\n    funcName = callee.property?.name;\n  }\n\nFor invalid namespaces like inav.pid[0].mapInput(), funcName remains null\nand produces 'Unknown function call' error.",
          "is_bot": false,
          "headline": "Refactor: Inline helper function namespace checking",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T02:34:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cbb70abd598bc71a986147f7dc9e7ff80557da77",
          "body": "Changed extractHelperFunctionName() to return null for invalid namespaces\ninstead of returning an object with invalidNamespace flag. This matches the\npattern used in condition_generator.js.\n\nNow inav.pid[0].mapInput() correctly produces 'Unknown function call' error\ninstead of the confusing 'Helper \n[…]\nstring for valid calls (mapInput() or inav.helpers.mapInput())\n- Returns null for invalid namespaces (inav.pid[0].mapInput())\n- generateCall() treats null as 'not a helper function' with generic error",
          "is_bot": false,
          "headline": "Simplify helper function namespace validation in expression_generator.js",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T02:29:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6aca22b4bc28747454f31fbe1a2bc5316ac90b81",
          "body": "Add xor, nand, nor, and approxEqual to the helpers.js API definition\nalongside the existing mapInput and mapOutput functions.\n\nUpdate condition_generator.js and expression_generator.js to:\n- Extract function names from both simple calls (xor()) and namespaced\n  calls (inav.helpers.xor())\n- Validate \n[…]\nelper functions are properly namespaced for consistency\nwith the rest of the INAV API.\n\nBackward compatibility: Global function calls (xor(), mapInput(), etc.)\ncontinue to work for existing user code.",
          "is_bot": false,
          "headline": "Add helper functions to inav.helpers namespace and validate usage",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T02:25:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9effe210af4a155007ef815378c477675517c130",
          "body": "Complete the namespace refactoring by adding inav. prefix to the\nremaining operand types in the decompiler's operand-to-string conversion:\n\n- gvar[N] → inav.gvar[N]\n- rc[N] → inav.rc[N]\n- pid[N].output → inav.pid[N].output\n\nThis matches the changes already made to action_decompiler.js and ensures\nall decompiled output uses the fully namespaced syntax consistently.",
          "is_bot": false,
          "headline": "Decompiler: Add inav. prefix to gvar, rc, and pid operands",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T02:09:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1efed60f74efa3fd66a0b8039bf7bc0e85e98cc7",
          "body": "Fix variable handler to detect inav.gvar[N] in addition to gvar[N]\nwhen identifying explicitly used gvar slots. This ensures var variables\navoid collisions with explicitly referenced gvar slots in user code.\n\nFix action decompiler RC channel override output to include inav. prefix\n(inav.rc[N] = valu\n[…]\ninstead of gvar[N]\n- inav.rc[N] instead of rc[N]\n- inav.override.* instead of override.*\n- inav.events.edge() instead of edge()\n- inav.events.sticky() instead of sticky()\n\nAll 25 test suites now pass.",
          "is_bot": false,
          "headline": "Tests: Update test suite for namespaced syntax",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T01:52:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5ae49fc0c72e8a95170d3af714285ce91efab143",
          "body": "New script tests that all examples in examples/index.js compile\nsuccessfully. Provides quick validation that the transpiler works\nwith all user-facing examples.",
          "is_bot": false,
          "headline": "Add test runner for all 22 examples",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T01:38:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44cae10e648c9aa50f3e0941517b7e43ff5fefa3",
          "body": "Support both rc[N].low/mid/high and inav.rc[N].low/mid/high syntax\nin condition generator for member expression handling.",
          "is_bot": false,
          "headline": "Fix RC channel boolean properties with inav. namespace",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T01:33:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "927f8efd39f362297e12975ba1297103a459d995",
          "body": "Convert JavaScript Programming transpiler from destructuring-based\nsyntax to fully namespaced API:\n\n- Update all 22 examples to use inav.flight.*, inav.override.*, etc.\n- Add support for inav.events.edge() and inav.events.sticky()\n- Implement dispatch tables for cleaner handler routing\n- Add namespa\n[…]\normalization\n- property_access_checker.js: API validation with dispatch tables\n- examples/index.js: All examples updated to namespaced syntax\n- tabs/javascript_programming.*: Default templates updated",
          "is_bot": false,
          "headline": "Refactor transpiler to use fully namespaced inav.* syntax",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-21T01:29:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8bd229e6efeb9f877586c3ca625fc0ec44a4d80c",
          "body": "Fixes four bugs that prevented the auto-select target feature from working correctly:\n\n1. Board selection handler using .text() instead of .val() (line 326)\n   - The releases object is keyed by value (raw_target), not display text\n   - This caused releases[target] lookups to fail, leading to forEach\n[…]\n\n   - This caused \"{-1}\" to appear in firmware version dropdown\n   - Now only triggers change if board was successfully selected\n\nTested with both stable and unstable release filters enabled/disabled.",
          "is_bot": false,
          "headline": "Fix auto-select target functionality in firmware flasher",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-20T16:08:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2b7a2f93cb83ac4fb371213f91e68c859d187594",
          "body": "The blackbox tab was using the deprecated fs.writeFileSync()\nwhich is not available in the Electron renderer process due to context\nisolation. Updated to use the secure window.electronAPI.appendFile()\nmethod exposed through the preload script.\n\nChanges:\n- Replace fs.writeFileSync() with window.elect\n[…]\nd proper error handling with GUI feedback\n- Use Promise-based async flow for file writing\n\nThis brings the code in line with other tabs (cli.js, logging.js) that\nalready use the electronAPI correctly.",
          "is_bot": false,
          "headline": "Fix blackbox save to file functionality",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-20T02:38:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a1be10b0b54cead26d2e2b903b47598a54496fcd",
          "body": "…ementation\n\nFlight axis override test + idiot-proof mag alignment handling for FCs without a mag",
          "is_bot": false,
          "headline": "Merge pull request #2487 from sensei-hacker/flight-axis-override-impl…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-19T18:23:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3dc3f8ce0704576a13a50a2e7df48b83124dc155",
          "body": "fix serial port open",
          "is_bot": false,
          "headline": "Merge pull request #2476 from error414/fix-serial-port--open",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-19T06:45:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb651623ca9bf1df05b5079f4bd3c056cb245038",
          "body": "Fix async settings loading race condition in Configuration and Receiver tabs",
          "is_bot": false,
          "headline": "Merge pull request #2485 from sensei-hacker/fix-async-settings-triggers",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-19T06:45:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a8344d4d6188acc428eaee3df92eb4ad07dd22e2",
          "body": "Fix receiver MSP control page nouislider migration",
          "is_bot": false,
          "headline": "Merge pull request #2480 from sensei-hacker/fix-receiver-msp-nouislider",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-19T06:44:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e87f05f3dd9a1fd7cb56a7db99c537210cea920d",
          "body": "…sitioning\n\nFix motor number positioning in Mixer tab",
          "is_bot": false,
          "headline": "Merge pull request #2475 from sensei-hacker/fix-mixer-motor-number-po…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-19T06:44:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9986d94241d9470faf1383f8d57ec173503882e2",
          "body": "…rrides\n\nTranspiler: Add 9 missing override operations",
          "is_bot": false,
          "headline": "Merge pull request #2474 from sensei-hacker/transpiler-additional-ove…",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-19T06:43:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9e614a4335f8af7eb448ab548281d35f69911f9f",
          "body": "Configuration.js:\n- Add .catch() handler to log settings load failures\n- Improves debugging visibility for async errors\n\nReceiver.js:\n- Only trigger receiverMode (not both receiverMode and serialRxProvider)\n- receiverMode handler already triggers serialRxProvider when mode is SERIAL\n- Avoids double-triggering and brief incorrect FrSky visibility\n\nAddresses Qodo PR review comments on #2485",
          "is_bot": false,
          "headline": "Apply Qodo bot suggestions: error handling and trigger optimization",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-18T17:49:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c55d203840a39ffd24428690a5b1c34816bafff4",
          "body": "…er tabs\n\nThis commit fixes a bug where change event handlers were triggered before\nsettings had finished loading asynchronously, causing incorrect UI state.\n\nRoot Cause:\nSettings.processHtml() now loads settings asynchronously via configureInputs()\nbut calls the callback immediately, passing a sett\n[…]\nrrect)\n\nReceiver tab:\n- SERIAL/CRSF: Loads correctly\n- Changed to SBUS: FrSky Options section appears dynamically (correct)\n- No console errors\n\nRelated async settings PR: (settings.js async refactor)",
          "is_bot": false,
          "headline": "Fix async settings loading race condition in Configuration and Receiv…",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-18T17:24:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c8c819d9ff45565068f7449979e88bb8be04eba3",
          "body": "Add Chrome DevTools Protocol remote debugging support",
          "is_bot": false,
          "headline": "Merge pull request #2483 from sensei-hacker/add-remote-debugging-support",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-18T15:28:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "96dca3c05cfc564bd704089a10a516bd9b2a2df7",
          "body": "Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Update js/main/main.js",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-18T15:27:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95ca8eae3a951598bd9bde228c9ab9470f9926ca",
          "body": "Co-authored-by: qodo-code-review[bot] <151058649+qodo-code-review[bot]@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Update js/main/main.js",
          "author_name": "Sensei",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-18T15:26:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d08e49ce7152da6255fe83fb6780b0a29fbc7a68",
          "body": "Enables Chrome DevTools Protocol (CDP) remote debugging on port 9222\nautomatically in development mode. This allows developers to:\n\n- Debug the configurator with Chrome DevTools (chrome://inspect)\n- Write automated tests using Playwright CDP\n- Capture screenshots and inspect DOM programmatically\n- M\n[…]\nt on production builds\n\nTechnical details:\n- Port: 9222 (standard CDP port)\n- Enabled: Development mode only\n- Protocol: Chrome DevTools Protocol 1.3\n- Location: js/main/main.js (before app.whenReady)",
          "is_bot": false,
          "headline": "Add Chrome DevTools Protocol remote debugging support",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-18T07:51:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5267c82d1759faf9b4bcb935988ddea541740971",
          "body": null,
          "is_bot": false,
          "headline": "receiver_msp.js: remove debug logging",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-15T05:03:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "696f9edb14f44c01f979d63661dc637c88f8677e",
          "body": "The receiver MSP control popup was using old jQuery nouislider plugin\nreferences that no longer exist. Updated to use modern nouislider API\nconsistent with other tabs (auxiliary, adjustments, magnetometer).\n\nChanges:\n- Updated CSS imports to use nouislider from node_modules\n- Migrated JS from jQuery\n[…]\nt support\n- Removed nodeIntegration flag (not needed, caused Vite bundling issues)\n- Added debug logging for troubleshooting\n\nFixes CSS import error and JavaScript runtime errors on receiver MSP page.",
          "is_bot": false,
          "headline": "Fix receiver MSP control page nouislider migration",
          "author_name": "Ray Morris",
          "author_login": "sensei-hacker",
          "committed_at": "2025-12-15T04:52:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 84,
      "commits_last_year": 316,
      "latest_release_at": "2026-03-17T01:21:58Z",
      "latest_release_tag": "untagged-58a74ccc453672f866b7",
      "releases_from_tags": false,
      "days_since_last_push": 126,
      "active_weeks_last_year": 19,
      "days_since_latest_release": 126,
      "mean_days_between_releases": 0
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 727,
      "watchers": 420,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [
          {
            "date": "2026-03-16",
            "count": 320
          },
          {
            "date": "2026-03-18",
            "count": 224
          },
          {
            "date": "2026-03-20",
            "count": 182
          }
        ],
        "complete": true,
        "collected": 726,
        "total_stars": 727
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "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": 187643,
      "source_files_sampled": 237,
      "oversized_source_files": 3,
      "agent_instruction_files": [
        "CLAUDE.md",
        "js/transpiler/CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 5925
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "acorn",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.14.0"
        },
        {
          "name": "@electron/remote",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.3"
        },
        {
          "name": "browserify-fs",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.0.0"
        },
        {
          "name": "chart.js",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.4.1"
        },
        {
          "name": "d3",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.9.0"
        },
        {
          "name": "electron-squirrel-startup",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.0.1"
        },
        {
          "name": "electron-store",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^10.1.0"
        },
        {
          "name": "electron-window-state",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.0.3"
        },
        {
          "name": "fs",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "0.0.1-security"
        },
        {
          "name": "i18next",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^25.5.0"
        },
        {
          "name": "inflection",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.0.2"
        },
        {
          "name": "jbox",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.3.3"
        },
        {
          "name": "jquery",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.7.1"
        },
        {
          "name": "jquery-ui-dist",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "1.13.3"
        },
        {
          "name": "jquery-textcomplete",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.8.5"
        },
        {
          "name": "marked",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^16.2.1"
        },
        {
          "name": "minimist",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.2.8"
        },
        {
          "name": "monaco-editor",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.54.0"
        },
        {
          "name": "nouislider",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^15.8.1"
        },
        {
          "name": "ol",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^10.6.1"
        },
        {
          "name": "promise-map-series",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.3.0"
        },
        {
          "name": "semver",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.7.2"
        },
        {
          "name": "serialport",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^13.0.0"
        },
        {
          "name": "smalltalk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.1.2"
        },
        {
          "name": "temp",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.9.4"
        },
        {
          "name": "three",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.180.0"
        },
        {
          "name": "throttle-debounce",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.0.2"
        },
        {
          "name": "usb",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.16.0"
        },
        {
          "name": "wnumb",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.2.0"
        },
        {
          "name": "xml2js",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.6.2"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 3,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "DzikuVx",
          "commits": 1597,
          "avatar_url": "https://avatars.githubusercontent.com/u/966811?v=4"
        },
        {
          "type": "User",
          "login": "cTn-dev",
          "commits": 1078,
          "avatar_url": "https://avatars.githubusercontent.com/u/2289413?v=4"
        },
        {
          "type": "User",
          "login": "MrD-RC",
          "commits": 577,
          "avatar_url": "https://avatars.githubusercontent.com/u/17590174?v=4"
        },
        {
          "type": "User",
          "login": "hydra",
          "commits": 434,
          "avatar_url": "https://avatars.githubusercontent.com/u/57075?v=4"
        },
        {
          "type": "User",
          "login": "skaman82",
          "commits": 330,
          "avatar_url": "https://avatars.githubusercontent.com/u/11768024?v=4"
        },
        {
          "type": "User",
          "login": "sensei-hacker",
          "commits": 297,
          "avatar_url": "https://avatars.githubusercontent.com/u/1971284?v=4"
        },
        {
          "type": "User",
          "login": "mmosca",
          "commits": 295,
          "avatar_url": "https://avatars.githubusercontent.com/u/23555060?v=4"
        },
        {
          "type": "User",
          "login": "digitalentity",
          "commits": 232,
          "avatar_url": "https://avatars.githubusercontent.com/u/11059099?v=4"
        },
        {
          "type": "User",
          "login": "fiam",
          "commits": 227,
          "avatar_url": "https://avatars.githubusercontent.com/u/41529?v=4"
        },
        {
          "type": "User",
          "login": "Scavanger",
          "commits": 119,
          "avatar_url": "https://avatars.githubusercontent.com/u/1850465?v=4"
        }
      ],
      "contributors_sampled": 100,
      "top_contributor_share": 0.254
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "nightly-build.yml",
        "pr-branch-suggestion.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "yarn.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 5,
            "reason": "binaries present in source code",
            "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": 10,
            "reason": "project has 8 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
            "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": 0,
            "reason": "83 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "705cd1a1a43c43974a6980042eb6a2ca8d883f1e",
        "ran_at": "2026-07-21T15:51:37Z",
        "aggregate_score": 1.9,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/INAVFlights/inav-configurator",
    "host": "github.com",
    "name": "inav-configurator",
    "owner": "INAVFlights"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "at_risk",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 46,
      "inputs": {
        "security": 19,
        "vitality": 57,
        "community": 56,
        "governance": 39,
        "engineering": 56
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 57,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "at_risk",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 41,
            "inputs": {
              "commits_last_year": 316,
              "human_commit_share": 1,
              "days_since_last_push": 126,
              "active_weeks_last_year": 19
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 126 days ago",
                "points": 9.9,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 126
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "19/52 weeks with commits",
                "points": 13.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 19
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "316 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 316
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "good",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "releases_count": 84,
              "latest_release_tag": "untagged-58a74ccc453672f866b7",
              "releases_from_tags": false,
              "days_since_latest_release": 126,
              "mean_days_between_releases": 0
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "84 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 84
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 126 days ago",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 126
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0
                    }
                  }
                ],
                "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": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "moderate",
        "name": "Community & Adoption",
        "value": 56,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 61,
            "inputs": {
              "forks": 0,
              "stars": 727,
              "watchers": 420,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "window_too_short"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "727 stars",
                "points": 46.4,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 727
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "420 watchers",
                "points": 14.6,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 420
                    }
                  }
                ],
                "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 (GPL-3.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "GPL-3.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "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": "good",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "bus_factor": 3,
              "contributors_sampled": 100,
              "top_contributor_share": 0.254
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "3 contributor(s) cover half of all commits",
                "points": 36,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 25% of commits",
                "points": 16.8,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 25
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "100 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 8 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "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": null,
            "notes": [],
            "value": 34,
            "inputs": {
              "followers": 0,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "INAVFlights",
              "public_repos": 2,
              "account_age_days": 139
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "0 followers of INAVFlights",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 0,
                      "login": "INAVFlights"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "2 public repos, account ~0 yr old",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 2
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "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": 56,
        "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": "3 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "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": 50,
            "inputs": {
              "topics": [
                "aircraft",
                "drones",
                "hacktoberfest",
                "inav",
                "inav-configurator",
                "uav"
              ],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "6 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "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": "critical",
        "name": "Security",
        "value": 19,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "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": 19,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 1.9
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "binaries present in source code",
                "points": 3.8,
                "status": "partial",
                "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 8 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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": "83 existing vulnerabilities detected",
                "points": 0,
                "status": "missed",
                "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": 8
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 56,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.85,
              "agent_instruction_files": [
                "CLAUDE.md",
                "js/transpiler/CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 5925
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md, js/transpiler/CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md, js/transpiler/CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "85 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 85,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 42,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "yarn.lock"
              ],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.05,
              "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": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "5 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 5,
                      "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": 54,
            "inputs": {
              "primary_language": "JavaScript",
              "largest_source_bytes": 187643,
              "source_files_sampled": 237,
              "oversized_source_files": 3
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "JavaScript without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "JavaScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "3/237 source files over 60KB",
                "points": 54.3,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 237,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "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": [
    "Could not fetch npm package 'inav-configurator' from its registry",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-21T15:51:58.221711Z",
  "schema_version": "0.23.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/INAVFlights/inav-configurator.svg",
  "full_name": "INAVFlights/inav-configurator",
  "license_state": "standard",
  "license_spdx": "GPL-3.0"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v1.13.0、模式 v0.23.0—— 完整方法论 · 指标知识库.

单项结果在整体记录中的位置: 汇总统计.