Публічний реєстр
Звіт про здоров'я програмного забезпеченнясхема 0.27.0 · метрики 1.13.0 · 2026-07-23 00:53 UTC

Gaubee / pnpm-pub

TypeScript · SvelteMIT★ 1 зірка⑂ 0 форківз черв. 2026 р.Переглянути на GitHub ↗

Gaubee/pnpm-pub має індекс здоров’я 50 зі 100, що відповідає смузі «Помірний». Найвищий показник — Vitality (74/100), найнижчий — Security (27/100). Останнє оновлення було 4 дні тому. Більшість нещодавньої роботи виконує один учасник.

50
загалом / 100
Помірний

Індекс здоров'я програмного забезпечення

Метрики згруповано у зважені категорії на шкалі 1–100. Загальна оцінка починається як їхнє середнє; коли публічні дані активують Політику юрисдикцій високого ризику, рейтинг коригується й отримує верхню межу 49 («Під ризиком»). Готовність до ШІ не входить до індексу.

50
Відмінний85-100Зразковий; відповідає практично всім перевіреним критеріям
Добрий70-84Здоровий; незначні прогалини
Помірний50-69Прийнятний, але з помітними прогалинами; рекомендовано перевірку
У зоні ризику30-49Суттєві слабкі місця; впровадження потребує обережності
Критичний1-29Серйозні проблеми (покинутий, єдиний мейнтейнер, без базової гігієни)
ЖиттєздатністьСпільнота тавпровадженняСталість таврядуванняІнженернаякістьБезпекаГотовність доШІ

Профіль оцінок

Кожна вісь — окрема категорія. Форма важить більше, ніж середнє: здоровий об'єкт заповнює всю фігуру, тоді як профіль із піками та провалами означає, що сила в одному вимірі маскує ризик в іншому.

Власність

GaubeeОсобистий обліковий запис
100 підписників199 публічних репозиторіївз серп. 2012 р.@BioforestChain

Цей репозиторій належить особистому обліковому запису. Проєкт з єдиним власником несе більший ризик безперервності, ніж підтримуваний організацією.

Пакетні екосистеми

РеєстрПакетВерсіяЗавантажень / місВерсіїОстання публікаціяТеги
npmpnpm-pub1.4.22 058135 днів тому2fadaemonnpmoidcpublishtotptraytrusted-publish

Метрики за категоріями

Життєздатність

Чи живий проєкт — чи пишеться код і чи виходять релізи?

74Добрий · 22% загального індексу
Як обчислюється оцінка
36/36Свіжість push — останній push 4 дн. тому
2.8/36Ритм комітів — 4/52 тижнів із комітами
18/18Обсяг комітів — 199 комітів за останній рік
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Використані вхідні дані
commits_last_year199
human_commit_share1
days_since_last_push4
active_weeks_last_year4
Як обчислюється оцінка
27/27Випускає релізи — опубліковано 7 релізів
36/36Свіжість релізів — останній реліз 5 дн. тому
27/27Ритм релізів — реліз кожні ~1,2 дн.
0/10OpenSSF Scorecard: Signed-Releases — немає даних
Використані вхідні дані
releases_count7
latest_release_tagv1.4.2
releases_from_tagsні
days_since_latest_release5
mean_days_between_releases1,2
Виключено з оцінювання (немає даних або не застосовно): OpenSSF Scorecard: Signed-Releases. Залишкові ваги перенормовано.

Спільнота та впровадження

Чи має проєкт користувачів, завантаження, увагу та влаштовані умови для контриб’юторів?

39У зоні ризику · 18% загального індексу
Як обчислюється оцінка
0/60Зірки — 1 зірок
0/25Форки — 0 форків
0/15Спостерігачі — 0 спостерігачів
Використані вхідні дані
forks0
stars1
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Як обчислюється оцінка
22.5/22.5README
22.5/22.5Ліцензія — визнана ліцензія (MIT)
18/18Настанови CONTRIBUTING
0/13.5Кодекс поведінки
0/7.2Шаблон issue
0/6.3Шаблон PR
Використані вхідні дані
has_readmeтак
has_licenseтак
has_contributingтак
has_issue_templateні
has_code_of_conductні
has_pull_request_templateні
Як обчислюється оцінка
44.2/80Щомісячні завантаження — 2 058 завантажень/місяць у npm
0/20Залежні пакети в реєстрі — ця екосистема цього не повідомляє
Використані вхідні дані
packagespnpm-pub
dependents
ecosystemsnpm
total_downloads
monthly_downloads2 058
Виключено з оцінювання (немає даних або не застосовно): Залежні пакети в реєстрі. Залишкові ваги перенормовано.

Сталість та врядування

Чи переживе проєкт своїх людей — бас-фактор, реактивність, хто за ним стоїть і як супроводжуються пакети?

40У зоні ризику · 24% загального індексу
Як обчислюється оцінка
9/54Бас-фактор — на 1 контриб’ютор(ів) припадає половина всіх комітів
0/22.5Розподіл комітів — головний контриб’ютор — автор 100% комітів
1.4/13.5Широта контриб’юторів — 1 контриб’юторів
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Використані вхідні дані
bus_factor1
contributors_sampled1
top_contributor_share1
Як обчислюється оцінка
0/46.8Вирішення issue — немає issue або даних
0/38.3Прийняття PR — немає вирішених pull request-ів або даних
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
Виключено з оцінювання (немає даних або не застосовно): Вирішення issue, Прийняття PR. Залишкові ваги перенормовано.
Як обчислюється оцінка
10/30Підтримка власника — особистий (користувацький) обліковий запис
0/20Верифікований домен — не застосовно до користувацьких облікових записів
14.4/25Охоплення власника — 100 підписників у Gaubee
25/25Послужний список — 199 публічних репозиторіїв, вік облікового запису ~13 р.
Використані вхідні дані
followers100
owner_typeUser
is_verified
owner_loginGaubee
public_repos199
account_age_days5 090
Виключено з оцінювання (немає даних або не застосовно): Верифікований домен. Залишкові ваги перенормовано.

Супровід пакетів

100Відмінний
Як обчислюється оцінка
25/25Опубліковано й доступно — 1 пакет(ів) у npm
35/35Свіжість публікацій — остання публікація 5 дн. тому
20/20Історія версій — 13 опублікованих версій
20/20Не застарілий — активний, не deprecated і не yanked
Використані вхідні дані
packagespnpm-pub
ecosystemsnpm
any_deprecatedні
min_days_since_publish5

Інженерна якість

Чи наявні базові інженерні практики та документація?

62Помірний · 20% загального індексу
Як обчислюється оцінка
24/24Процеси CI — 2 процес(ів) CI
24/24Наявні тести
0/16Конфігурація лінтера
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. Залишкові ваги перенормовано.

Документація

65Помірний
Як обчислюється оцінка
30/30README
25/25Каталог документації
0/15Сайт документації / домашня сторінка
0/10Опис репозиторію
0/10Теми
10/10Wiki
Використані вхідні дані
topics
has_wikiтак
homepage
has_readmeтак
has_docs_dirтак
has_descriptionні

Безпека

Чи міцні видимі практики безпеки й ланцюга постачання, без непослабленої пов’язаності з юрисдикціями високого ризику?

27Критичний · 16% загального індексу

Стан безпеки

27Критичний
Як обчислюється оцінка
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — немає даних
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Ліцензія — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — немає даних
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0/7.5Vulnerabilities — 13 existing vulnerabilities detected
Використані вхідні дані
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate2,7
Виключено з оцінювання (немає даних або не застосовно): ci_tests, signed_releases. Залишкові ваги перенормовано.

Готовність до ШІ

Наскільки репозиторій оснащений для розробки та супроводу за участі ШІ-агентів? Незалежний, експериментальний бейдж — вага 0.0, тож він подається окремо і не впливає на загальний індекс здоров'я.

68Помірний · 0% загального індексу
Як обчислюється оцінка
45/45Інструкції для агентів — AGENTS.md
0/15Машиночитана документація (llms.txt)
40/40Читабельна історія комітів — намір зазначено у 100 з 100 людських комітів (структурований заголовок або пояснювальний текст)
Використані вхідні дані
has_llms_txtні
legible_history_share1
agent_instruction_filesAGENTS.md
agent_instruction_max_bytes5 143
Як обчислюється оцінка
0/18Розгортання однією командою
22/22Автоматизовані тести
0/11Конфігурація лінтера / форматера
11/11Статична перевірка типів — tsconfig.json, webui/tsconfig.json
10/10Відтворюване середовище — lockfile
0/10Підтверджена практика роботи з агентами — серед останніх 100 комітів немає створених агентом
0/8Автоматизоване супроводження — автоматичних оновлень залежностей не виявлено
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Використані вхідні дані
has_nixні
has_testsтак
lockfilespnpm-lock.yaml
has_dockerfileні
typed_languageтак
bootstrap_files
has_devcontainerні
has_linter_configні
typecheck_configstsconfig.json, webui/tsconfig.json
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
Як обчислюється оцінка
45/45Типізований код — TypeScript (статично типізована)
54.2/55Керовані розміри файлів — 3/197 файлів вихідного коду понад 60 КБ
Використані вхідні дані
primary_languageTypeScript
largest_source_bytes191 430
source_files_sampled197
oversized_source_files3

Ключові факти

1зірок GitHub
1контриб'юторів
199комітів за останні 12 місяців
4днів від останнього пушу
7релізів
1бас-фактор
0відкритих issue
npmпакетних екосистем

Попередження щодо збору даних

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index npm:pnpm-pub@1.4.2; advisories assessed against the repository dependency graph instead

Докладніше

OpenSSF Scorecard 2.7 / 10
2.7сукупно

Незалежна, не прив'язана до інструментів оцінка безпеки від відкритого проєкту OpenSSF Scorecard. Кожна перевірка винагороджує практику безпеки, а не інструмент конкретного постачальника. Перевірки, які Scorecard не зміг визначити, позначено н/д і виключено з оцінки безпеки (вони ніколи не зараховуються як нуль).Scorecard v5.5.0 · 2026-07-23 00:53 UTC

10Binary-Artifactsno binaries found in the repo
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
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
н/дSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
0Vulnerabilities13 existing vulnerabilities detected
Прямі залежності 14
РеєстрПакетОбмеження версіїМаніфест
npm@github/keytar^7.0.0package.json
npm@opentray/ext-webview^0.14.4package.json
npmopentray^0.14.4package.json
npmvalidate-npm-package-name^8.0.0package.json
npm@humanspeak/svelte-motion^0.7.17webui/package.json
npmclsx^2.1.1webui/package.json
npmgeist^1.7.2webui/package.json
npmhighlight.js^11.11.1webui/package.json
npmhtml5-qrcode^2.3.8webui/package.json
npmmarked^18.0.6webui/package.json
npmmode-watcher^1.0.0webui/package.json
npmsvelte-i18n^4.0.1webui/package.json
npmtailwind-merge^3.0.0webui/package.json
npmzod^4.4.3webui/package.json
Усі залежності не зібрано

Не вдалося зібрати розв'язаний набір залежностей для цього звіту: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Звіт у форматі JSON машиночитний
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 3190,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "CSS": 11207,
        "HTML": 380,
        "Svelte": 638801,
        "JavaScript": 49943,
        "TypeScript": 1540325
      },
      "pushed_at": "2026-07-18T06:55:52Z",
      "created_at": "2026-06-25T10:21:11Z",
      "owner_type": "User",
      "updated_at": "2026-07-18T08:18:20Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript",
        "Svelte"
      ]
    },
    "owner": {
      "blog": "https://gaubee.com",
      "name": "Gaubee",
      "type": "User",
      "login": "Gaubee",
      "company": "@BioforestChain ",
      "location": "China-Fujian-Xiamen",
      "followers": 100,
      "avatar_url": "https://avatars.githubusercontent.com/u/2151644?v=4",
      "created_at": "2012-08-14T15:36:14Z",
      "is_verified": null,
      "public_repos": 199,
      "account_age_days": 5090
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.4.2",
          "kind": "patch",
          "published_at": "2026-07-17T17:32:31Z"
        },
        {
          "tag": "v1.4.1",
          "kind": "patch",
          "published_at": "2026-07-17T14:58:39Z"
        },
        {
          "tag": "v1.4.0",
          "kind": "minor",
          "published_at": "2026-07-14T21:06:28Z"
        },
        {
          "tag": "v1.3.1",
          "kind": "patch",
          "published_at": "2026-07-12T02:36:33Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-07-11T10:00:42Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-07-11T05:20:29Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-07-10T18:05:15Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "43c3805cd20c97394b171201cb05f9b44cd60c1a",
          "body": null,
          "is_bot": false,
          "headline": "feat(docs): add links to README.md",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-18T06:55:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7ade95c9b2afbcb817ca360216212f5b8131111",
          "body": null,
          "is_bot": false,
          "headline": "fix(tray): consume stable OpenTray WebView2 profiles",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-17T17:31:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a5bb7aa442f1fa08f5c8ba16c3314f43ea99ac4",
          "body": null,
          "is_bot": false,
          "headline": "fix(tray): expose menu transition completion",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-17T14:55:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23985631ecdfe68f81cfa3eaec15e876ce4ae94b",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): publish 1.4.1",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-17T14:44:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d70ffc4a36d81634eb525cd3af9430db4a5056d3",
          "body": null,
          "is_bot": false,
          "headline": "fix(tray): synchronize retained window visibility",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-17T14:41:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "84cbc1e13ffed4b7aa2acc6b9beecd511685c954",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): publish 1.4.0",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-14T21:01:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2253200d162d9e9affb7f6d8b679f0ad40d22e7",
          "body": null,
          "is_bot": false,
          "headline": "feat(webui): adopt OpenTray frameless controls",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-14T21:00:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eeee95364dbc6a5eb8978a0bc7ea62adaaef8fa6",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 发布 1.3.1",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T15:11:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4a140ac17ba9cbf94fe2f23598e1f5b5108c06b",
          "body": null,
          "is_bot": false,
          "headline": "fix: 加固应用升级异步任务边界",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T11:40:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d2982f35243f1a29c04ff007cfd470a9768a2af2",
          "body": null,
          "is_bot": false,
          "headline": "feat: 完善应用升级日志与重启生命周期",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T11:03:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c0638812f08673bbd3e1454cd79171a22d2c301",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 发布 1.3.0",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T09:56:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a96dfc4eaae8faaa0a9958e7bf2d7afea359e2f",
          "body": null,
          "is_bot": false,
          "headline": "feat: 对齐 placeholder 发布与整包删除生命周期",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T09:46:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "32e2c29a67981006d730fc8c82699e0036b5a3c6",
          "body": "新增 profile.otp RPC:守护进程用内存中的 totp_secret 经 otplib 生成 6 位\n动态码,返回 {code, remainingSec, epochMs, configured},密钥不离开 daemon\n(遵循 Chapter 3.1)。按 username 取密钥,并对任意已保存 profile 生效。\n\nWebUI 新增 otp-button 组件,置于 Profile 详情页右上角(仅激活 profile 显示):\n- tooltip open 由 pointerenter/pointerout 驱动,配合 disableCloseOnTriggerCl\n[…]\n  保证点击复制时 OTP 不被隐藏;未 open 时不拉取、不计时,并清空内存中的 code\n- tooltip 内用 grid 布局展示 ring | code;环形进度按 30s TOTP 窗口递减,\n  环心始终显示剩余秒数,最后 10s 弧线转为 warning 色\n- 点击复制 OTP,按钮短暂显示打勾图标;未配置 2FA 时按钮禁用并提示\n\n补齐 9 个 locale 的文案与翻译。",
          "is_bot": false,
          "headline": "feat: Profile 详情页接入 OTP 一键获取与复制",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T09:23:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "27c8433136fdf169072eb3ff02aab7a2c718a0cc",
          "body": null,
          "is_bot": false,
          "headline": "fix(webui): 完善包详情 README 渲染与原生外链",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T07:29:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "758f00d09c43dcd817a63bbf9b97bcfec066326d",
          "body": "type=\"single\" 的 ToggleGroup item 渲染 role=\"radio\" + aria-checked\n(aria-pressed 不渲染)。上次改用 data-state(on/off)虽能过测,但那是\nbits-ui 内部样式 hook 而非语义属性。改回 aria-checked(true/false)。\n\nCo-Refer: bits-ui toggle-group.svelte.js#ariaChecked/#ariaPressed",
          "is_bot": false,
          "headline": "test: 用语义属性 aria-checked 断言 ToggleGroup 选中态",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T05:26:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba584bf0288f1f0fd0a3d8165ec77ff360c4243f",
          "body": "Keep/Remove 按钮已迁移至 ToggleGroup(commit 59d5487),其选中态投影为\ndata-state(on/off)而非原先 ButtonGroup 的 aria-pressed(true/false)。\n更新浏览器断言读取 data-state;补 node 类型引用以通过 vp check。",
          "is_bot": false,
          "headline": "test: 对齐 trusted-publishing 移除评审为 ToggleGroup 语义",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T05:20:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d4459184279684ad52aa59f1bd980273c9d1d480",
          "body": "该测试(原生 pnpm 子进程下 profile token 覆盖 project token)本地一致通过,\n但在 GitHub Actions Ubuntu 环境下失败。CI 特有的 userconfig/token 优先级\n行为需要单独排查,先 skip 以解除 1.2.0 发布阻塞。",
          "is_bot": false,
          "headline": "test: 跳过 CI 环境失败的 publish-userconfig 断言",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T05:12:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "89789e95c4c3f3518c8d52635a02b6a5622a7d04",
          "body": "runtime-info 初始快照帧调用 keychain.activeService(),但 web-server-renew\n与 resolve-trust-auth 的 keychain mock 未导出该函数,导致快照生成器抛错、\nworkspaces 帧无法下发,re-broadcast 断言失败。",
          "is_bot": false,
          "headline": "fix(test): 为 keychain mock 补齐 activeService",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T04:57:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79ed92a5be2e1a2740bca9aba30f738fed219c7e",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 发布 1.2.0",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T04:35:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1572c73f5c6ac97e4360bab3d7a6e9795ac9909c",
          "body": "- SWITCH PROFILE 下拉补全 AvatarImage,复用 avatarUrlFor 加载真实头像\n- add-profile 表单:label/input 间距改用 flex gap(规避 space-y 兄弟选择器\n  失效),空头像以 user-round 图标替代 ??,TOTP/密码改用 InputGroup 并将\n  扫码与显隐按钮置于 suffix,所有输入框统一 border-black/50",
          "is_bot": false,
          "headline": "fix(webui): 完善 add-profile 表单与 sidebar 头像绑定",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T04:35:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "76c80a9dcb92144ae3eaedbca61d738c56309c9e",
          "body": "新增 add-profile-content 容器与 profile-import-form 原子,使 Add Profile\n与 Settings / Export 共享同一导入流程(本地校验、预览、选择后再下发密码\n与选中项给 Daemon)。Settings Export 标签页改为委托该原子,移除内联的\n导入状态机。同步接入 shadcn accordion / checkbox 组件并对齐 input 样式。",
          "is_bot": false,
          "headline": "refactor(webui): 抽取 profile-import 原子并复用于 add-profile",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T04:34:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a8af193bba2f5ef3c17b9d6932d8706e9253fa0",
          "body": "Daemon 通过 runtime-info 状态帧向 WebUI 投影 PID、平台、数据目录、\nprofiles.json、事件库与日志路径及凭据 service 名称,About 面板在折叠区\n展示这些诊断事实。路径由 Daemon 解析,正确反映 PNPM_PUB_HOME 覆盖;\n仅显示 service 名称,绝不投影凭据内容。",
          "is_bot": false,
          "headline": "feat(webui): 投影 Daemon 运行时信息至 About",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T04:34:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "740ad7fc089b2e5c292e59fb45816b64420e4d17",
          "body": "移除 better-sqlite3 原生依赖,改用 Node 内置的 node:sqlite (DatabaseSync),\n统一 EventDb / RepoInfo / DaemonStore 的数据库交互。同步将构建目标、CI 运行时、\n文档要求提升至 Node 24,移除 onlyBuiltDependencies 中的 better-sqlite3 条目。",
          "is_bot": false,
          "headline": "feat(daemon): 迁移至 node:sqlite 并提升 Node 24",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T04:33:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5915d8b4660aa48b0de45e06bfc00a91bfc7f6a2",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 准备 1.1.1",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T01:10:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21000e1c11d1efc973445abbfb81c434949e7686",
          "body": null,
          "is_bot": false,
          "headline": "fix(publish): 使用外部 userconfig 注入凭据",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T01:10:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7f74408a4ecb5e3d5016ecee57b8cc94798796d",
          "body": null,
          "is_bot": false,
          "headline": "docs(spec): 固化外部 userconfig 凭据注入法则",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-11T01:09:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1e96704f50e5999bf7227e3978839c52d8c8655d",
          "body": "- 新增 shadcn-svelte 依赖,用于按需生成 Toggle/ToggleGroup/Tabs 等组件\n- layout.css 引入 shadcn-svelte/tailwind.css 基础样式",
          "is_bot": false,
          "headline": "chore(webui): 接入 shadcn-svelte 依赖与样式",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T19:22:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "59d5487f438aa508c6ac9620bf52472f3e423ee2",
          "body": "- toggle.svelte 新增 primary/brand/destructive 变体,激活态改用强主色,\n  替代原先过淡的 bg-muted;default 不再自带激活样式\n- toggle-group-item 支持按 item 覆盖 group 的 variant/size(variant ?? ctx),\n  使单个 item 可独立采用 destructive 等语调\n- 将手写单选语义的 ButtonGroup 统一迁移:\n  - settings/general-tab (Theme) -> ToggleGroup brand\n  - event-card-body \n[…]\nGroup brand\n  - trusted-publishing-removal-review (keep|remove) -> ToggleGroup,\n    keep=brand / remove=destructive,消除手写 aria-pressed 与互斥状态\n- event-detail-dialog 的 inherit/customize 纯内容切换改用 Tabs(非表单值)",
          "is_bot": false,
          "headline": "refactor(webui): 将单选语义 ButtonGroup 迁移至 ToggleGroup/Tabs",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T19:21:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4ab1dac97029ac03770d1437ff328e7e533e1b17",
          "body": null,
          "is_bot": false,
          "headline": "fix(release): 输出纯净版本到 Actions",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T18:01:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f04586c9b7c5fbcb07bd15e7d4ece5a6d3f3f9f",
          "body": null,
          "is_bot": false,
          "headline": "fix(test): 使用 Node 探测 Verdaccio 健康状态",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:31:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02ccb861bb3c0092913442d9c9e4e52904c188a0",
          "body": null,
          "is_bot": false,
          "headline": "fix(ci): 安装生产构建所需 Bun 运行时",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:24:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0deb4cac3e6ceccf4b52e353cf7956ab75ffc19",
          "body": null,
          "is_bot": false,
          "headline": "fix(test): 显式使用 Node WebSocket 客户端",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:19:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af98f6f6b824954fe9a4805ef90200a7c6e61955",
          "body": null,
          "is_bot": false,
          "headline": "fix(ci): 允许构建 better-sqlite3 原生绑定",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:14:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7460e90d8328776b9616e197ccd1f15ca92fbc90",
          "body": null,
          "is_bot": false,
          "headline": "fix(ci): 统一 pnpm 与 Actions 运行时来源",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:12:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3e04345139f729e939edc22a548c33f92429c63",
          "body": null,
          "is_bot": false,
          "headline": "chore(release): 发布 1.1.0",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:10:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26b98fae0ed17ffc40f745c07c52465281ff6ced",
          "body": null,
          "is_bot": false,
          "headline": "fix(test): 隔离 unit 与 browser 测试通道",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:09:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a5268786daca0fdce91b444c7b0bbd897bd85721",
          "body": null,
          "is_bot": false,
          "headline": "docs(spec): 固化测试通道隔离法则",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:06:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "40aedfc3f4c34cc02bd20f2bae2fd286ac4a503f",
          "body": null,
          "is_bot": false,
          "headline": "fix(test): 对齐可信发布配置动作投影",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T17:01:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d22524e19ef6a8af561f0f76fe8c2e3c2ee36454",
          "body": null,
          "is_bot": false,
          "headline": "feat(release): 使用 GitHub Actions OIDC 发布",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T16:55:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "30d43c7f83096bbc834de58724ab4462e4143042",
          "body": null,
          "is_bot": false,
          "headline": "docs(spec): 定义 GitHub Actions 发布法则",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T16:53:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e187a53d9112d994694dcdb835ecf21b4e43f19f",
          "body": null,
          "is_bot": false,
          "headline": "refactor(webui): 更新设置控件与组件基线",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T16:11:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cab715c1e68c4332773d810bf57d78d193b4b763",
          "body": null,
          "is_bot": false,
          "headline": "feat(update): 添加应用内检查与显式更新",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T15:58:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "02906f2c3d8cdcef54c25329c835d2fdd70d0a5b",
          "body": null,
          "is_bot": false,
          "headline": "fix(trusted-publishing): 持久化删除快照并默认全选",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T15:49:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e6ca2b61d5d7a91288de76552ef4a1e4c69bbb80",
          "body": null,
          "is_bot": false,
          "headline": "docs(spec): 定义可信发布删除快照法则",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T15:17:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9bb3d765fd49522354e59402535dfe40721ced49",
          "body": null,
          "is_bot": false,
          "headline": "docs: reorganize product documentation",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T03:58:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c23366f29e2bc5136121cc4cff9a31d3d8ebdc01",
          "body": null,
          "is_bot": false,
          "headline": "fix(tray): keep add-profile visible on blur",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T03:41:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4c6c4b83428b5f931c94b245c8c5316f2e439207",
          "body": null,
          "is_bot": false,
          "headline": "feat(dev): upgrade OpenTray DevTools support",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T03:39:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "068edb3841497934df0f388f2a1464093ea2618c",
          "body": null,
          "is_bot": false,
          "headline": "fix(webui): preserve camera decoder geometry",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T03:27:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b759b6a5796daafd304391aa28dffdf012f1100",
          "body": null,
          "is_bot": false,
          "headline": "fix(webui): improve camera QR scanning",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-10T03:11:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c41d26d15b7058e4d69b05c1f99987c8954b6b29",
          "body": null,
          "is_bot": false,
          "headline": "fix(test): 修复发布测试通道",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-09T17:07:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af0642e0a0697781e484938c54d9290fc00b8dbe",
          "body": null,
          "is_bot": false,
          "headline": "feat(build): 并发构建 cli 和 webui",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-09T14:57:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27e89c8de568029a75fb8413b0cc520c6607650d",
          "body": null,
          "is_bot": false,
          "headline": "fix(events): 区分 canceled 并接入 oidc 事件源",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T16:47:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d4595ae989a78defeedf5a2ce547d1669dfd382",
          "body": null,
          "is_bot": false,
          "headline": "fix(webui): 修正 advanced 参数投影",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T14:20:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2566616e302a55e8214e7cad8d9f27b8e60e00a9",
          "body": null,
          "is_bot": false,
          "headline": "fix(cli): 安装入口 shebang + help 命令注册表",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T13:58:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ff9ff23378ba2795291699de2666e68e4c17210",
          "body": "Events footer 布局重构 + trust Dialog 本地暂存编辑 + i18n 系统化改造\n\n- Events 打开按钮从 header 迁到 footer(左右 cluster 对立)\n- Trust 成员 Dialog:三态按钮(关闭/放弃+保存)+ 模式/表单本地暂存\n- i18n:locale 按需加载 + 类型安全 + 键对齐检测 + 全量翻译 + CI strict\n- island:CSS 误报修复 + 冗余 toast 移除 + backdrop-filter 主题感知",
          "is_bot": false,
          "headline": "Merge branch 'feat/event-card-footer-actions'",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T13:04:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3479ede37a670fb80c8c7e12e106169febe7325d",
          "body": "原实现:backdropFilter 作为字符串写死在 Motion 的 animate 对象里\n('blur(8px) contrast(0.8) brightness(1.2)'),contrast/brightness 是暗色\n模式专用值,亮色模式下错误。\n\n改为:\n- @property --island-blur 注册为 <number>,Motion 只动画 blur 半径数字\n  (8/8/24),用 styleEffect/Motion 的 CSS 变量动画能力(WAAPI 需 @property\n  注册才能插值自定义属性,二者正好耦合)。\n- 完整 backdrop-fil\n[…]\n-island-grade 变量 + .dark 选择器切换:\n  · 亮色(默认):contrast(2) brightness(0.8)——压亮背景内容保持可读\n  · 暗色:contrast(0.8) brightness(1.2)——提升暗壁纸上的玻璃质感\n\n功能不变(blur 随 phase 平滑过渡),色彩分级正确响应明暗主题。\n\n验证:pnpm check 0/0,build 通过。",
          "is_bot": false,
          "headline": "fix(island): backdrop-filter 主题感知 + @property 数字动画",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T12:42:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b22b6de304268935916eb723e9d72f310989e8cc",
          "body": "web-server.createProactiveEvent 成功后发了一个 'Pending event created —\nreview it under Events.' 的 info toast,经 bridgeDaemonToast 上岛。但新建\n的 pending 事件本身已经通过 +layout.svelte 的 pending-group 反射上岛\n(更丰富的 live-activity:摘要/详情/进度条/跳转卡片),这个 toast 只是\n冗余地竞争同一个 island 单槽。\n\n事件已上岛,无需再 toast 提示。直接删除该 toast 发送。\n\n(该字符串是硬编码英文,从未国际化——删除顺带消除一处未国际化字符串。)\n\n验证:typecheck 通过,webui check 0/0;测试 15 failed 为预存(stash 验证\n一致),与本次改动无关。",
          "is_bot": false,
          "headline": "fix(island): 移除创建事件时冗余的 'Pending event created' toast",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T12:24:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d2fd0803c0d1d6e5db235b9ea93df938b5e88f90",
          "body": ".island / .island-detail / .island :global(svg) 写在 <motion.div>\n(@humanspeak/svelte-motion 的外部组件,内部用 {...rest} 透传 class 到\n真实 <div>)上。Svelte 的 CSS 静态分析只看本组件 markup,看不到 class\n跨组件透传,误判 selector 未使用(运行时实际生效)。\n\n按 Svelte 官方惯例改用 :global() 并锚定到本组件的 .island-anchor(原生\ndiv wrapper),既消除误报又不全局泄漏。功能完全不变。\n\n验证:pnpm check 0 errors/0 warnings(原 3 warnings 消除),build 通过。",
          "is_bot": false,
          "headline": "fix(island): 消除 3 个 css_unused_selector 误报",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T12:14:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61fb0e74fdd727e97a84596d1c2dd5ba080f7273",
          "body": "- vite.config.ts staged 钩子:locales glob 从 i18n:check 升级为\n  i18n:check:strict,与 CI 门槛一致——本地提交 locale 改动时即检测\n  untranslated 漂移,避免提交后才在 CI 挂。\n- 删除 scripts/i18n-fill.mjs + package.json 的 i18n:fill script:该脚本\n  被 i18n-translate.mjs 完全取代(translate 既保证完整键集又应用真实翻译,\n  而 fill 只会用 en 值占位,误跑会把已翻译覆盖回 en)。i18n:translate 是\n  唯一的 locale 生成入口。\n\n验证:i18n:check:strict 0 error/0 warning,pnpm check 0 errors,build 通过",
          "is_bot": false,
          "headline": "chore(i18n): staged 钩子升级 strict + 删除冗余 i18n-fill",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T12:07:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0575e355d23380103550a509548c5883fb340cda",
          "body": "oxlint TS2305 根治:\n- vite.config.ts 的 PackPlugin 从 'vite-plus/pack'(4 层 export * 透传,\n  oxlint type-check 穿不透)改为 'vite-plus'(re-exported Vite Plugin,是\n  rolldown Plugin 的超类型)。\n- 顺带把三个插件的 apply: () => 'build' 简化为 apply: 'build'(字符串字面量\n  形式),符合 Vite Plugin 的 apply 类型(build|serve|predicate)。\n  tsc --noEm\n[…]\n\nCI 收紧:\n- ci.yml: i18n:check → i18n:check:strict(翻译完整后 warning 也阻断,\n  防止退化;新增键必须翻译或加白名单才能合并)\n- package.json 加 i18n:translate script\n\n验证:i18n:check:strict 0 error/0 warning,pnpm check 0 errors,build 通过",
          "is_bot": false,
          "headline": "fix(i18n): 全量翻译 + oxlint 误报根治 + CI 收紧 strict",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T11:37:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e1c1215a8347eace03794803e69fb46d0f910cdf",
          "body": "根 vite.config.ts 的 staged 块新增 `webui/src/locales/**` glob,\n触发 `pnpm --filter ./webui i18n:check`。\n\n注:此提交用 --no-verify 绕过 pre-commit。根 vite.config.ts:23 的\n`type Plugin as PackPlugin from 'vite-plus/pack'` 被 oxlint 的\ntype-aware 模式误报 TS2305(无法解析 export * 透传的 Plugin 类型),\n但 tsc --noEmit(CI 实际跑的)通过。这是 oxlint 类型解析的既有局限,\n非本次改动引入,后续 oxlint 升级或换用 tsc-based 检查可消除。",
          "is_bot": false,
          "headline": "chore(i18n): staged 钩子加 locales glob,提交 locale 文件时本地提示键对齐",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T08:31:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3e3f827035fef0e4226bba2be6b03a48318ee52c",
          "body": "承接上一个 commit(拆分 + 检测脚本),本提交补齐遗漏的接线文件:\n- webui/src/lib/i18n.ts:2968 行原文件 → 19 行 re-export shim\n- webui/package.json:i18n:check / :check:strict / :fill script + tsx devDep\n- .github/workflows/ci.yml:i18n key-parity step\n- pnpm-lock.yaml:tsx 依赖锁定",
          "is_bot": false,
          "headline": "refactor(i18n): i18n.ts shim + package.json scripts + CI step + lockfile",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T08:12:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ffbd1e0c7de83ee804ef01484637bcc0c60a6df1",
          "body": "- locale 从单文件 i18n.ts(2968 行,9 语言全量打进首包)拆到\n  src/locales/{en,zh,es,fr,ar,ru,de,ja,ko}.ts + index.ts\n- 按需加载:en 同步作为 fallback(首屏安全),其余 locale 用 svelte-i18n\n  register + 动态 import 各自独立 chunk(首包不再含全部语言)\n- 类型安全:en as const → Messages 类型(WidenLeaves 保留键结构,叶子放宽\n  到 string);每个 locale 用 const xx: Messages 强制\n[…]\n() 调用 + initI18n/setAppLocale\n  等导入路径零改动\n- tsx 声明为 webui devDep(脚本运行依赖)\n\n检测基线:0 error,1718 untranslated warning(回填 + 真实未翻译状态)\n\n注:vite.config.ts 的 staged 钩子因预存类型错误(vite-plus/pack 未导出\nPlugin)暂未提交,后续单独处理",
          "is_bot": false,
          "headline": "refactor(i18n): 按需加载 + 类型安全 + 键对齐检测 + CI",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T08:10:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4f6c1aa2fa61c535436bf8836a863522350366e9",
          "body": "- EventCard 的 repo/folder/npm 打开按钮从 header 迁到 footer,左右\n  cluster 用 justify-between 隔离对立(左侧主操作,右侧打开链接)\n- 新增 EventCardOpenActions 组件复用,TargetTarballDialog 接入同款\n  打开按钮 + tarball 默认展开 + max-h 自适应高度\n- EventDetailDialog: group trust 成员底部改三态按钮(关闭 / 放弃+保存)\n- 根因修复:模式切换+表单从「改即生效」重构为「本地暂存,Save 才提交」\n  · deferS\n[…]\n 本地暂存\n  · 模式切换本地化:不再每切换触发 setMemberInherit RPC,避免 daemon\n    回写覆盖 initialMode 快照导致脏检查失效,且消除 custom 编辑污染\n    继承视图的问题\n- 继承视图标签 Current → Inherit Values\n- i18n: 新增 discard/saveChanges/inheritValues 等 key",
          "is_bot": false,
          "headline": "feat(events): 打开按钮迁至 footer + trust 成员 Dialog 本地暂存编辑",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-08T06:43:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8cd0f29d6712d65ab9cb2f075de1fcbe342e9a81",
          "body": null,
          "is_bot": false,
          "headline": "feat(tarball): pending 阶段预计算 tarball 预览 + 持久化(单包 & 递归)",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-07T19:12:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4ab5df9854108ab709af23f2dad764378aed515b",
          "body": "reevaluateAutoClose() 同时被 blur/focus/pin 调用,而 blur 是 hide() 的必然\n副产物。原先写在该方法里的「有 activeEvents 且窗口隐藏 ⇒ show()」规则会在\n用户点 Hide window 时立刻把窗口拉回,并因 hide/show 抖动冻结在 0.1 enter seed。\n\n将该规则收敛到 store 的 \"event\" 订阅者 — 只有真正的新事件到达才有权复活\n隐藏窗口,reevaluateAutoClose() 回归 auto-close 资格评估的单一职责。\n\n补回归测试:hide() + blur 在 activeEvents 下保持 hidden。",
          "is_bot": false,
          "headline": "fix(tray): 有 activeEvents 时 hide() 被 blur 反弹 — 弹窗规则归位到 store 事件源",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-07T17:36:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "825b2b3b756b63304e77199fba69752250120bbf",
          "body": null,
          "is_bot": false,
          "headline": "chore(pkg): opentray 系列跟进到 npm 0.11.2 — 修复 tray 挂载",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-07T15:21:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "781dc59e343ee016a4e86d39bf1f3fda902fc152",
          "body": "pointer-events 改为由 phase 声明式驱动,设在 island-anchor(普通 DOM\ndiv,可用 style: 指令)而非 motion.div(组件,不支持 style: 指令)。\nhidden 态立即禁用交互(不等淡出动画完成),避免点击落在动画中的元素上。",
          "is_bot": false,
          "headline": "fix(island): hidden 态 pointer-events:none 设在 anchor 上",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-07T07:14:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5dec9841aef12c85a2f9f966f8ef6a76d64dbb2d",
          "body": "覆盖分页、包名/关键词过滤、空组、orphan-pending sweep、\nJSON/boolean 序列化、corrupt payload 容错。全部通过。\n\n测试文件沿用现有 test/ 目录的 node:fs/os/path import 规范\n(与 avatar.test.ts 等一致)。",
          "is_bot": false,
          "headline": "test(db): event-db 分组历史查询单测(17 cases)",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-07T03:17:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dfb823eb6607be54ac389257b589160043b6198b",
          "body": "event-db 新增按 groupId 聚合的历史查询,聚合在 DB 层完成:\n- HistoryEventGroupQuery/Result:分页 + 包名/关键词过滤\n- store/web-server 接线,orpc-contract/schemas 暴露契约\n- 前端 hasGroupEvents guard 过滤空组切片(防御 daemon 边界)",
          "is_bot": false,
          "headline": "feat(db): 服务端分组历史查询(grouped history pagination)",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-07T03:14:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dae505137947a28bb9fed844b400a786642d14db",
          "body": "standalone pending 事件之前错误地显示 '0/1 resolved' 假进度条\n(单事件是 pending→done 二态,无子进度)。改为按 kind 生成有意义的\nsummary + detail text。group 事件保留真实 progress。",
          "is_bot": false,
          "headline": "feat(island): standalone 事件详情适配 — 动词+关键信息",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T17:21:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "025e132609ad8e6a7831844329aed50486aecc41",
          "body": "- 引入 @humanspeak/svelte-motion,motion.div + animate 声明式驱动\n  单一可信源:phase(hidden/compact/expanded)→ TARGETS 外观对象\n  真实 spring 物理曲线,可中断、重复触发自然收敛\n- 三态状态机:hidden(不可见)↔ compact(药丸)↔ expanded(卡片)\n  新 expandable activity 默认展开,4s 自动收起到 compact(药丸常驻)\n- backdrop-filter 纳入 animate:compact blur(8px)↔ expanded blu\n[…]\nt.svelte:pending 事件用 groupEvents,summary 体现 kind\n  (Trusted Publishing · N),detail 用 progress(resolved/total)\n- download-button 适配 showActivity(primaryAction=打开文件)\n- 灵动岛点击跳转 GroupEventCard + 布局稳定后平滑滚动",
          "is_bot": false,
          "headline": "feat(island): Dynamic Island 重构为 iOS 三态声明式动画",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T17:05:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "204f9f5ee5c7d0aa2e27af36619ff1771721c4b6",
          "body": "opentray / @opentray/ext-webview 已发布到 npm(latest 0.11.0),不再\n需要 link:。同时它们带原生二进制(optionalDependencies 里按平台分发的\n.node),daemon 通过 index.ts 里的 dynamic `await import(\"opentray\")` 在\n运行时从 node_modules 解析(vite.config.ts 的 neverBundle 把它们保持为\nexternal),所以**必须在 dependencies**(host 安装 pnpm-pub 时才会拉取它\n们及其平台二进制),不\n[…]\nus 运行正常。\n\nNOTE: webui 构建因未提交的 motion-sv(webui/package.json 里的既有未提交\n改动)触发 motion-dom activeAnimations 缺失而失败——与本次 opentray 改动\n无关,是独立的 webui 依赖问题,需单独处理(pin motion-dom 或修 motion-sv\n版本)。本次用 --no-verify 提交。",
          "is_bot": false,
          "headline": "chore(pkg): opentray 系列跟进到 npm 0.11.0 + 移到 dependencies",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T16:12:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f9ebd934b930ebc7664353caa0f40ddcb1c291e4",
          "body": "新增 src/daemon/db.ts:同步 Database/Statement 接口(shaped like\nbetter-sqlite3),+ openDatabase() 工厂按运行时选驱动:\n- Node  → better-sqlite3(createRequire 加载,保持 external)\n- Bun   → bun:sqlite(createRequire,运行时守卫,bundler 不静态解析)\n- Deno  → @db/sqlite(jsr WASM,同步)\n\n三个驱动都是同步 API,所以 event-db/store/oRPC 全部保持原 sync 签名,\n零 \n[…]\nexisting,与本次改动无关;项目 tsc 干净)。\n\n验证:daemon tsc 0 错误;webui check 0 错误;event-db/store/orpc/\nproactive-events 共 92/92 通过;build 成功,better-sqlite3 仍 external、\nbun/deno 驱动以字符串守卫存在;node dist/cli.js status 运行正常。",
          "is_bot": false,
          "headline": "feat(db): 运行时可移植的 SQLite 抽象层(支持 Node/Bun/Deno)",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T11:48:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4ccad91e86a386b62f24c1cffa4e0f16e19b0597",
          "body": null,
          "is_bot": false,
          "headline": "chore(pkg): safe-npm-sdk 改用 npm 发布版 ^0.4.0(不再 link)",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T06:17:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a9786bccfebaee08def94f96b0d8a7efda034072",
          "body": "files: 新增 [\"dist\", \"README.md\"],确保发布只含产物 + 文档,不含源码/\n测试/spec。\n\n依赖整理(vp pack 把 dependencies 视为 external、devDependencies 视为\nbundle,已实测验证):\n- dependencies 只保留原生二进制依赖:better-sqlite3、@github/keytar。\n- 其余纯 JS 依赖(execa/otplib/ws/yargs/zod/@orpc/*/...)全部挪到\n  devDependencies,由 vp pack bundle 进 dist,运行时不再从 nod\n[…]\n,其它依赖全部 bundle 进去。\n- npm pack --dry-run:tarball 只含 dist/ + README.md + package.json\n  (106 文件,打包 1.5MB / 解压 4.0MB),无源码/测试泄漏。\n- node dist/cli.js status 正常运行,无模块解析错误。\n- daemon tsc 0 错误;webui check 0 错误。",
          "is_bot": false,
          "headline": "chore(pkg): 配置 files 字段 + 依赖整理(发包准备)",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T05:38:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9b13940b2166ab255bb44c27dab713db28654de0",
          "body": "1. GroupEventCard 日志显示所有成员的结果(而非仅 group.latest.result)。\n   折叠态:tally pill(成功/跳过/失败各一个小 chip,带状态色)+ 首个错误\n   首行预览。展开态:每个成员一块(包名 + 状态 pill 头部 + 10px 结果文本,\n   错误 destructive/90、其它 muted),柔和卡片分隔。\n\n2. ConfirmAll/RejectAll 进入 loading 并显示进度。batchRunning 在所有目标\n   成员异步 resolve 完成前保持 true(不再同步 try/finally 立即清零);\n   按钮显示 spinner + \"{done}/{total} resolved\"。批量目标 id 单独追踪,\n   进度准确反映 confirm/reject 的目标子集。\n\n验证:webui check 0 错误、build 成功;41/41 单测通过。",
          "is_bot": false,
          "headline": "feat(group): 多成员结果日志 + ConfirmAll loading/进度",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T05:15:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cfdb2f44a553182b0894da57a6a282268e2ac310",
          "body": "批量 configure-trust 时,npm 的 POST 在包已有任一配置时返回 409\n(\"trusted publisher config already exists\"),无论 add 还是 update。旧实现\n凭前端 currentConfig 缓存决定 add/update,缓存为空就发 add → 已配置的包\n全失败。\n\n正交预检模型(webui 预显 + daemon 权威,两边都做):\n- 新增 config 相等比较 trustedPublisherConfigsEqual(webui + daemon 镜像),\n  忽略 registry id、归一化 Circle\n[…]\nkSkip / precheckConflict)。\naggregateGroupStatus 把 skipped 视为成功中性。\n\nspec/06.md 新增 6.2.7 节(含决策原话)。\n\n验证:webui check 0 错误、build 成功;daemon tsc 0 错误;\ntrusted-publishing-equality 8/8、store 31/31 等共 56/56 通过。",
          "is_bot": false,
          "headline": "feat(trust): batch OIDC skip/conflict 预检 + delete-then-put 自动解决",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-06T05:15:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4024f1b5fbfbf0f594a7ca1e18434679062cd655",
          "body": "…m gate\n\n1. GroupEvent 日志显示:GroupEventCard 增加组级可展开日志区(复用\n   EventCardBody 的折叠样式),resolved 后展示 group.latest.result 的\n   首行+全文。批量失败时错误信息直接显示在组卡片上,不再需要逐个点开\n   成员 Dialog。\n\n2. Retry/Reset 新 groupId:recreateMember/retryAll/resetAll 改为生成\n   新的 groupId(重试成员全部进新组),EventCard.retry() 同理(仅当\n   原事件有 groupId 时)。避免重试事件折回旧失败组导致的\"任务翻倍 +\n   残留错误任务\"。\n\n3. 继承成员的 confirm 门控:trustedPublishingReady 对 inherit 成员\n   改为认 group default 是否存在(而非成员自身 config),修复\"填了组\n   默认表单但成员确认按钮仍 disabled / ConfirmAll 后 config 为空\"的\n   问题。",
          "is_bot": false,
          "headline": "fix: group log visibility, retry groupId reuse, inherit-member confir…",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-05T17:45:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2720f2a472e6aaafb45b59129daeaa7c046bddc0",
          "body": "## EventCard 三段式重构\n将单体 EventCard 拆分为 Header / Body / Footer 三个 shell-agnostic\n子组件,由 EventCard 装配器按 surface ('card' | 'dialog') 组合:\n- card 模式:包进 <Card> 三段(列表用)\n- dialog 模式:裸输出三段,由 EventDetailDialog 融合进 DialogHeader /\n  可滚动 body / footer 三行 grid——消除\"卡片套卡片\"的双层边框/padding\n\nEventDetailDialog 融合点:\n- 可见标题即 \n[…]\nentity+repositoryHint,断掉\n  custom 成员编辑→回声→reset 循环\n\nspec/06.md 新增 6.2.5(只读展示三变体)+ 6.2.6(继承模型)两节,\n含决策原话。\n\n验证:daemon tsc 0 错误;pnpm check 0 错误;store.test.ts 31/31;\nbrowser trusted-publishing-dialog 测试通过。",
          "is_bot": false,
          "headline": "feat: EventCard 三段式重构 + Trusted Publishing 继承模型",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-05T16:54:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5fa0721444eaa5826206d9b4dd39d8cfedb2f97a",
          "body": "…fixes\n\nDownloadButton: global component that triggers a download and listens for\nopentray's downloadcompleted event, then surfaces a Dynamic Island success\nnotification with an \"Open file\" action (daemon openExternal now expands ~\nto homedir so the action works). Island gains an optional action but\n[…]\nlocks private:true) — scope was a flawed heuristic that blocked\nlegitimate org-scoped packages. The disabled Publish button shows a tooltip\nwith the reason (pointer-events kept active so hover fires).",
          "is_bot": false,
          "headline": "feat: DownloadButton + Island actions, workspaces batch UX, settings …",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-05T07:35:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "32a797ab7ea78369b7d8172c73807521defcb261",
          "body": "SettingsDialog: a global dialog (general / preferences / export) opened from\nthe main-shell toolbar. Built on the shadcn-svelte sidebar-13 block pattern\nwith a glass surface. General tab has theme (ButtonGroup) + language (Combobox);\npreferences is the single read/write source for the keep-open pin \n[…]\nts still have TS\nerrors on union-typed claims and are WIP.\n\nCommitted with --no-verify because the pre-commit hook fails on those\npre-existing trusted-publishing TS issues, not on SettingsDialog code.",
          "is_bot": false,
          "headline": "feat(settings): SettingsDialog (sidebar-13) + trusted-publishing WIP",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-05T03:47:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f35a0a22770b3dd0252ef7010b6a229c36564922",
          "body": "Page reload drives visibilitychange->hidden while the document unloads,\nwhich the hide reporter mistook for a real window hide: it called\nwindowHidden(), and TrayHost.markHidden() poisoned visibility='hidden'.\nLater blurs short-circuit in reevaluateAutoClose (requires visibility\n'shown'), so the exi\n[…]\na show().\n\nArm an unload flag on pagehide/beforeunload (capture phase, before\nvisibilitychange) and skip the report when set. Real X-close/host hide\nare not page unloads, so their paths are unchanged.",
          "is_bot": false,
          "headline": "fix(tray): keep blur auto-close alive after page reload",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T14:40:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "405597b03ce321b7474eab8c5c7846947be8fe63",
          "body": "Replace background-fill hover/active with backdrop-filter contrast so the\nnative blur reads through. Sidebar active uses contrast(2), hover contrast(1);\ntoolbar (pin/theme) reuses the same hover. Switch the Events nav icon to\nListTodo.",
          "is_bot": false,
          "headline": "style(ui): contrast-based hover/active for sidebar + toolbar",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T14:40:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "745d58c9ff98fa83d7944f6fe95669c727f20048",
          "body": null,
          "is_bot": false,
          "headline": "fix(tray): align auto-close opacity timeline",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T12:41:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "aa014ced7f66063fdf34913bf2ab7c3791d522d1",
          "body": null,
          "is_bot": false,
          "headline": "fix(dev): stabilize OpenTray WebUI startup",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T11:19:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f83398315afb98bace8bb8a335c9c06ee3c91157",
          "body": "kezhaofeng's avatar was reachable but never cached: gravatar serves it as a\nJPEG, and fetchAndCacheAvatar only accepted PNG (isPngBuffer guard). So every\nfetch was rejected → null → a notfound.json negative-cache entry → the WebUI\nsaw a 404 and initials forever, even though the avatar genuinely exis\n[…]\n.png — the extension is just a stable URL; the\nserved type follows the actual cache).\n\nVerified: /api/avatar/kezhaofeng.png → 200 image/jpeg (128×128). Cleared the\nstale notfound.json so it re-caches.",
          "is_bot": false,
          "headline": "fix(avatar): accept JPEG/WebP/GIF avatars, not just PNG",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T07:07:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c18ecd584149c7d164ff9b241839b48c4d1e07e7",
          "body": "… route\n\navatarUrlFor returned \"./api/avatar/...\". On nested routes like\n/profiles/<username> the relative \"./\" resolves against the current path,\nproducing /profiles/api/avatar/<user>.png → 404 even though the avatar is\ncached. Switched to an absolute \"/api/avatar/...\". The SPA has no base path, so\nthis resolves correctly everywhere.",
          "is_bot": false,
          "headline": "fix(avatar): use absolute path for avatar URL so it resolves from any…",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T06:58:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9a031c6caf21432f0571db008825fbec3c8bdaa1",
          "body": "The daemon now owns avatar resolution/caching as the single source of truth,\nand the WebUI reads from it instead of each component independently hitting the\nnpm/gravatar network.\n\nBackend:\n  - avatar.ts: new getCachedAvatarPath() entry point. Returns the on-disk PNG if\n    hot, returns null on a rec\n[…]\nthat's the one legitimate anonymous lookup).\n\nVerified: /api/avatar/sindresorhus.png → 200 image/png (128×128) via the dev\nproxy; 404 for unresolved users; 401 without token. tsc + svelte-check clean.",
          "is_bot": false,
          "headline": "feat(avatar): unify avatar fetching — frontend reads from backend cache",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T06:51:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d95b0aa88302dd8f7875b8226d89eb76814bc673",
          "body": "`safe-npm-sdk` now ships `lookupAvatar`, which is a faithful port of\nour own `lookupNpmProfileIdentity` (the SDK JSDoc says so). Drop the\nduplicated fallback chain (auth-profile email→Gravatar → registry\n`/-/user` → maintainer-search→Gravatar) and call the SDK instead,\nkeeping pnpm-pub's two layers \n[…]\n check's TS plugin reports a\npre-existing TS2591 false-positive (missing node:os/Buffer/process) on\navatar.test.ts — it reproduces on the pre-change file too; tsc and the\nreal test run are both clean.",
          "is_bot": false,
          "headline": "refactor(avatar): delegate resolution to safe-npm-sdk lookupAvatar",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-04T03:16:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8074487c499f1dc50e26a1a6d2a8e8f7e4e2f7f8",
          "body": "addWorkspace() overwrote pinned and addedAt on an already-tracked\nworkspace. The WorkspaceDetail page's scan-on-mount $effect calls\nworkspace.scan -> addWorkspace({ pinned: false }), which silently reset\na user-set pin to false and re-broadcast the unpinned state — so opening\na workspace detail page\n[…]\nee call sites pass pinned:false). pinWorkspace and\nremoveWorkspace are unchanged.\n\nAdds a regression test covering both the in-memory and the\nreload-from-disk persistence of the pin through a re-scan.",
          "is_bot": false,
          "headline": "fix(store): preserve workspace pin/addedAt across re-scan",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T19:36:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9bafe8c597acda07e2d147a6821d6ccfaa796f61",
          "body": "Complete the TrayHost API that index.ts already referenced at HEAD:\nsetIcon() swaps the tray projection between the default mono template\nand the active color icon as pending-event state changes, and the menu\nnow relabels the primary item (Hide/Show window) to match real visibility\nand delegates a d\n[…]\n / Quit\n  labels; drive iconProjection through trayHost.setIcon on pending changes.\n- tray-host.test.ts: cover setIcon no-op, Quit menu delegation, and the\n  show/hide label sync; tighten mock typing.",
          "is_bot": false,
          "headline": "feat(tray): dynamic tray icon + show/hide/Quit menu wiring",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T19:35:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3b1f08dbfb1671ba4f442ef4190764b3c0a8f743",
          "body": "Replaces the split REST + hand-rolled WebSocket protocol with one oRPC\nWebSocket mounted at /ws/rpc, carrying every WebUI action and the\nstate.subscribe projection stream. /api/* is now an explicit tombstone\nthat returns a 404 pointing at /ws/rpc.\n\n- Add the shared `webRpcContract` (Zod + oRPC) as t\n[…]\ngrate\n  web-server-renew/ws-profile-authstatus/resolve-trust-auth/\n  webui-protocol-types/publish-intercept coverage to oRPC.\n- Record milestones 228/229/230 in TASKS.md and archive the closed issues.",
          "is_bot": false,
          "headline": "refactor: migrate WebUI transport to a single /ws/rpc oRPC WebSocket",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T19:32:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b8d149c8fa7fc036199d205b2fdcfdb69cf2cc9f",
          "body": "… all\n\nfetchAndCacheAvatar was called WITHOUT the profile's npm token at daemon\nstartup, so lookupNpmProfileIdentity skipped the authenticated-profile path\n(email → Gravatar) — the only path that reliably resolves an npm avatar today,\nand the one the WebUI's own profile.lookupNpm RPC uses. It instea\n[…]\n actually land (and cache) on first boot.\n\nThe fire-and-forget + negative-cache changes from the previous commit stand:\nstartup is still unblocked, and only deterministic not-found results are cached.",
          "is_bot": false,
          "headline": "fix(avatar): pass the profile token so the startup avatar resolves at…",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T18:27:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c5390fa8ffe26d03a22dee55d8a64189a671f154",
          "body": "…esults\n\nThe daemon startup was slow and the avatar cache \"never hit\" for two compounding\nreasons, both in the avatar pre-fetch on the default profile:\n\n1. fetchAndCacheAvatar was awaited synchronously in bootDaemon, so the\n   multi-second registry/gravatar probe blocked \"WebUI available\" (and the t\n[…]\ner URL is known up front. Removed leftover debug\nconsole.log breakpoints in bootDaemon.\n\nMeasured: failed-user lookup 2175ms → 0ms on next boot; dev startup ~15.5s →\n~5.3s with WS still returning 101.",
          "is_bot": false,
          "headline": "fix(daemon): avatar fetch no longer blocks startup + cache negative r…",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T18:16:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8b056e7a9b7cc32da147dfda95dde9166b720d1a",
          "body": "The dev proxy was silently disabled, so every /ws/rpc upgrade fell through to\nSvelteKit (which neither upgrades nor rejects WS), and the connection hung —\nthe exact symptom reported.\n\nRoot cause: server.proxy was evaluated at config-load time via devDaemonProxy(),\nwhich reads PNPM_PUB_DEV_DAEMON_POR\n[…]\ngrade to /ws/rpc through the proxy returns\nHTTP 101 with a valid token (and 401 with a bad one), /__token proxies to the\ndaemon's response. Daemon-exit teardown still tears down the whole dev session.",
          "is_bot": false,
          "headline": "fix(dev): wire daemon proxy in configureServer so /ws/rpc doesn't hang",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T16:50:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ccbdbc7d2dac97fb1131fcf42b7b9fcfd96b1b06",
          "body": "…rapper\n\nThe previous multi-PID supervisor-watch + ancestor-walk + SIGKILL exit-handler\nwas compensating for two things execa + a flat process chain make unnecessary.\n\nTwo realizations:\n\n1. execa already handles cleanup (the daemon dies when vite exits) and signal\n   forwarding (SIGINT to vite reach\n[…]\nts pre-bloat state, and the dev script is one line.\n\nVerified both directions: kill daemon → dev session exits; SIGINT the top\nprocess → daemon + vite all gone, no survivors. tsc + svelte-check clean.",
          "is_bot": false,
          "headline": "refactor(dev): simplify daemon lifecycle with execa; drop pnpm-exec w…",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T16:15:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cc53585481537f44c9138620196022eb54c8e650",
          "body": "The daemon-dev Vite plugin now guarantees neither the daemon nor the UI can\noutlive the other, mirroring the old src/dev.ts supervisor contract.\n\nDaemon dies → dev session exits:\n  The plugin's daemon `exit` handler calls shutdown(), which closes the Vite\n  HTTP server and force-exits. Without the d\n[…]\n still works) and exits when ANY watched PID\n    disappears, not just the one.\n\nVerified both directions: kill daemon → dev exits clean; SIGINT the pnpm\nwrapper → daemon + vite all gone, no survivors.",
          "is_bot": false,
          "headline": "fix(dev): daemon exit tears down the whole dev session, both directions",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T16:03:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "12c07df7a5f3289f775e9a91ab97dcc0224ad9cc",
          "body": "….config.ts\n\nThree consolidations on top of the Vite+ migration, each eliminating a\nhand-rolled orchestration layer in favour of native Vite+ config blocks.\n\n1. Tests — merge 3 vitest configs into root vite.config.ts test.projects\n   The standalone vitest.config.ts / vitest.browser.config.ts /\n   vi\n[…]\nlp runs.\n\nAlso: .gitignore now ignores root .svelte-kit/ (a stray dev artifact).\n\nUnrelated concurrent edits left unstaged: src/shared/orpc-contract.ts,\nsrc/daemon/tray-host.ts, webui/src/lib/i18n.ts.",
          "is_bot": false,
          "headline": "refactor(toolchain): consolidate dev/build/test into vp + single vite…",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T13:20:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ab467c72b0bdf7e1e2d72bbe6fdb0e1c8c2ddc07",
          "body": "This commit combines two streams of work onto a single fast-forward into main.\n\n1. Vite+ toolchain migration (vite-plus 0.2.1)\n   - Bumped root vite ^5.4.21 -> ^8, vitest ^2.1.8 -> ^4.1 (installed: vite\n     8.1.0, vitest 4.1.9) to satisfy the migration baseline.\n   - Ran `vp migrate --no-interactiv\n[…]\n run build: full pipeline green (webui + core + copy); bundled CLI runs.\n   - Unit tests: 448/453 pass in-suite; the 5 \"failures\" are forks-worker\n     timeouts under load and pass 15/15 in isolation.",
          "is_bot": false,
          "headline": "chore: merge Vite+ migration + in-flight feature work into main",
          "author_name": "Gaubee",
          "author_login": "Gaubee",
          "committed_at": "2026-07-03T12:34:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 7,
      "commits_last_year": 199,
      "latest_release_at": "2026-07-17T17:32:31Z",
      "latest_release_tag": "v1.4.2",
      "releases_from_tags": false,
      "days_since_last_push": 4,
      "active_weeks_last_year": 4,
      "days_since_latest_release": 5,
      "mean_days_between_releases": 1.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": true,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "pnpm-pub",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "2fa",
            "daemon",
            "npm",
            "oidc",
            "publish",
            "totp",
            "tray",
            "trusted-publish"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/pnpm-pub",
          "is_deprecated": false,
          "latest_version": "1.4.2",
          "repository_url": "https://github.com/Gaubee/pnpm-pub",
          "versions_count": 13,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2058,
          "first_published_at": "2026-06-24T11:28:04.539000Z",
          "latest_published_at": "2026-07-17T17:34:46.972000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 5
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 1,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json",
        "webui/tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 191430,
      "source_files_sampled": 197,
      "oversized_source_files": 3,
      "agent_instruction_files": [
        "AGENTS.md"
      ],
      "agent_instruction_max_bytes": 5143
    },
    "dependencies": {
      "manifests": [
        "package.json",
        "webui/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@github/keytar",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^7.0.0"
        },
        {
          "name": "@opentray/ext-webview",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.14.4"
        },
        {
          "name": "opentray",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.14.4"
        },
        {
          "name": "validate-npm-package-name",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^8.0.0"
        },
        {
          "name": "@humanspeak/svelte-motion",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^0.7.17"
        },
        {
          "name": "clsx",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.1.1"
        },
        {
          "name": "geist",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.7.2"
        },
        {
          "name": "highlight.js",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^11.11.1"
        },
        {
          "name": "html5-qrcode",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^2.3.8"
        },
        {
          "name": "marked",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^18.0.6"
        },
        {
          "name": "mode-watcher",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.0.0"
        },
        {
          "name": "svelte-i18n",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.0.1"
        },
        {
          "name": "tailwind-merge",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^3.0.0"
        },
        {
          "name": "zod",
          "manifest": "webui/package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.4.3"
        }
      ],
      "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": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "Gaubee",
          "commits": 199,
          "avatar_url": "https://avatars.githubusercontent.com/u/2151644?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "pnpm-lock.yaml"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "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": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 0,
            "reason": "13 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "43c3805cd20c97394b171201cb05f9b44cd60c1a",
        "ran_at": "2026-07-23T00:53:51Z",
        "aggregate_score": 2.7,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-18T06:58:31Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/Gaubee/pnpm-pub",
    "host": "github.com",
    "name": "pnpm-pub",
    "owner": "Gaubee"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 50,
      "inputs": {
        "security": 27,
        "vitality": 74,
        "community": 39,
        "governance": 40,
        "engineering": 62
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 74,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 57,
            "inputs": {
              "commits_last_year": 199,
              "human_commit_share": 1,
              "days_since_last_push": 4,
              "active_weeks_last_year": 4
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 4 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "4/52 weeks with commits",
                "points": 2.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "199 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 199
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 7,
              "latest_release_tag": "v1.4.2",
              "releases_from_tags": false,
              "days_since_latest_release": 5,
              "mean_days_between_releases": 1.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "7 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~1.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 1.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 39,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 1,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "1 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "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": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 55,
            "inputs": {
              "packages": [
                "pnpm-pub"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2058
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,058 downloads/month across npm",
                "points": 44.2,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2058,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 40,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "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": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 62,
            "inputs": {
              "followers": 100,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "Gaubee",
              "public_repos": 199,
              "account_age_days": 5090
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "100 followers of Gaubee",
                "points": 14.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 100,
                      "login": "Gaubee"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "199 public repos, account ~13 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 199
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 13
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "pnpm-pub"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 5
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 5 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "13 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 13
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 62,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 60,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "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": 25,
                "status": "met",
                "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "critical",
        "name": "Security",
        "value": 27,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 27,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 2.7
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "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": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "13 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": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 68,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                "AGENTS.md"
              ],
              "agent_instruction_max_bytes": 5143
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 43,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "pnpm-lock.yaml"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json",
                "webui/tsconfig.json"
              ],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json, webui/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json, webui/tsconfig.json"
                    }
                  }
                ],
                "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": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 191430,
              "source_files_sampled": 197,
              "oversized_source_files": 3
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "3/197 source files over 60KB",
                "points": 54.2,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 197,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index npm:pnpm-pub@1.4.2; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-23T00:53:56.349611Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/Gaubee/pnpm-pub.svg",
  "full_name": "Gaubee/pnpm-pub",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Оцінки — це сигнали, а не гарантії. Вони відображають публічно видимі практики на GitHub — це не аудит коду й не гарантія безпеки.

Відсутні дані виключаються, а ваги перенормовуються — нуль за відсутність ніколи не ставиться. Методологія версіонована й відкрита: метрики v1.13.0, схема v0.27.0 — повна методологія · вікі метрик.

Як окремий результат виглядає на тлі всього реєстру: сукупна статистикаnpm.