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

buliwyf42 / shellyadmin

Self-hosted web app to discover, inventory, firmware-check, and provision Shelly Gen2+ devices on a trusted LAN. Single Go binary + Svelte UI, Docker-ready, with an opt-in MCP server.

Go · SvelteMIT★ 3 stars⑂ 0 forkssince Apr 2026View on GitHub ↗

buliwyf42/shellyadmin holds a health index of 60 out of 100, placing it in the Moderate band. It scores highest on Vitality (85/100) and lowest on Sustainability & Governance (24/100). It was last updated 1 day ago. A single contributor accounts for most of its recent work.

60
overall / 100
Moderate

Software health index

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

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

Score profile

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

Ownership

Dominik SennfelderPersonal account
2 followers4 public repossince Jun 2013

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

Metrics by category

Vitality

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

85Excellent · 22% of overall
How it's scored
36/36Push recency — last push 1 days ago
11.1/36Commit cadence — 16/52 weeks with commits
18/18Commit volume — 325 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year325
human_commit_share0.75
days_since_last_push1
active_weeks_last_year16

Release discipline

100Excellent
How it's scored
27/27Ships releases — 70 releases published
36/36Release recency — latest release 1 days ago
27/27Release cadence — a release every ~6.6 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count70
latest_release_tagv0.6.3
releases_from_tagsno
days_since_latest_release1
mean_days_between_releases6.6
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

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

46At risk · 18% of overall
How it's scored
4.9/60Stars — 3 stars
0/25Forks — 0 forks
0/15Watchers — 0 watchers
Inputs used
forks0
stars3
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

Community health

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

Sustainability & Governance

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

24Critical · 24% of overall
How it's scored
9/54Bus factor — 1 contributor(s) cover half of all commits
0/22.5Commit distribution — top contributor authored 100% of commits
1.4/13.5Contributor breadth — 1 contributors
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Inputs used
bus_factor1
contributors_sampled1
top_contributor_share1
How it's scored
0/46.8Issue resolution — 0% of issues closed
27.7/38.3PR acceptance — 60/83 decided PRs merged
0/15OpenSSF Scorecard: Code-Review — Found 0/25 approved changesets -- score normalized to 0
Inputs used
merged_prs60
open_issues1
closed_issues0
issue_closed_ratio0
closed_unmerged_prs23
How it's scored
10/30Ownership backing — personal (user) account
0/20Verified domain — not applicable to user accounts
3.4/25Owner reach — 2 followers of buliwyf42
17.1/25Track record — 4 public repos, account ~13 yr old
Inputs used
followers2
owner_typeUser
is_verified
owner_loginbuliwyf42
public_repos4
account_age_days4,792
Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.

Engineering Quality

Are baseline engineering and documentation practices in place?

84Good · 20% of overall
How it's scored
24/24CI workflows — 3 workflow(s)
24/24Tests present
16/16Linter config — .golangci.yml, eslint.config.js
0/9.6Pre-commit hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
Inputs used
has_ciyes
has_testsyes
has_editorconfigno
has_linter_configyes
has_precommit_configno

Documentation

85Excellent
How it's scored
30/30README
25/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
10/10Topics — 10 topics
10/10Wiki
Inputs used
topicsdocker, firmware-management, golang, home-automation, iot, mcp, self-hosted, shelly, smart-home, svelte
has_wikiyes
homepage
has_readmeyes
has_docs_diryes
has_descriptionyes

Security

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

67Moderate · 16% of overall
How it's scored
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — no data
2.5/2.5CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/25 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5License — license file detected
7.5/7.5Maintained — 30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
4.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 9
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
2/5Security-Policy — security policy file detected
0/7.5Signed-Releases — no data
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
6/7.5Vulnerabilities — 2 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate6.1
Excluded from scoring (no data or not applicable): branch_protection, signed_releases. Remaining weights renormalized.
How it's scored
26.6/35Direct dependencies free of known advisories — 1 affected: golang.org/x/crypto v0.54.0 (unknown)
0/25Indirect dependencies free of known advisories — transitive set not separable from development and test dependencies in this scope
40/40No advisories left outstanding — no advisory has been public longer than 90 days
Inputs used
sourceosv
advisories2
affected_packages2
assessed_packages334
unassessed_packages0
affected_by_severityhigh 1, unknown 1
direct_affected_packages1
Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories. Remaining weights renormalized. Matched 334 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.

AI Readiness

How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score.

83Good · 0% of overall
How it's scored
45/45Agent instructions — CLAUDE.md
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 72 of 75 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.96
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes43,430
How it's scored
18/18One-command bootstrap — Makefile
22/22Automated tests
11/11Lint / format config — .golangci.yml, eslint.config.js
11/11Static type checking — web/tsconfig.json
10/10Reproducible environment — Dockerfile, lockfile
10/10Demonstrated agent practice — 20 of the last 100 commits agent-authored or agent-credited
8/8Automated maintenance — 25 of the last 100 commits are automated dependency updates
9/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 9
Inputs used
has_nixno
has_testsyes
lockfilesgo.sum, package-lock.json
has_dockerfileyes
typed_languageyes
bootstrap_filesMakefile
has_devcontainerno
has_linter_configyes
typecheck_configsweb/tsconfig.json
agent_commit_share0.2
toolchain_manifestsgo.mod
dependency_bot_commit_share0.25
How it's scored
45/45Type-checkable code — Go (statically typed)
55/55Manageable file sizes — 0/209 source files over 60KB
Inputs used
primary_languageGo
largest_source_bytes52,308
source_files_sampled209
oversized_source_files0
How it's scored
0/40API schema (OpenAPI/GraphQL/proto)
20/20MCP server
0/40Runnable examples
Inputs used
example_dirs
has_mcp_signalyes
api_schema_files

Key facts

3GitHub stars
1contributors
325commits, last 12 months
1days since last push
70releases
1bus factor
1open issues
Go, npmpackage ecosystems

Data collection warnings

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

More detail

OpenSSF Scorecard 6.1 / 10
6.1aggregate

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

10Binary-Artifactsno binaries found in the repo
n/aBranch-Protectioninternal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
10CI-Tests5 out of 5 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/25 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
9Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 9
0SASTSAST tool is not run on all commits -- score normalized to 0
4Security-Policysecurity policy file detected
n/aSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
8Vulnerabilities2 existing vulnerabilities detected
Direct dependencies 10
RegistryPackageVersion constraintManifest
Gogithub.com/gin-contrib/sessionsv1.1.0go.mod
Gogithub.com/gin-gonic/ginv1.12.0go.mod
Gogithub.com/modelcontextprotocol/go-sdkv1.6.1go.mod
Gogolang.org/x/cryptov0.54.0go.mod
Gogolang.org/x/modv0.38.0go.mod
Gogolang.org/x/netv0.57.0go.mod
Gogopkg.in/natefinch/lumberjack.v2v2.2.1go.mod
Gomodernc.org/sqlitev1.54.0go.mod
npmqrcode^1.5.4web/package.json
npmsvelte^5.56.6web/package.json
All dependencies 334

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

RegistryPackageVersionRelation
Gogithub.com/gin-contrib/sessionsv1.1.0direct
Gogithub.com/gin-gonic/ginv1.12.0direct
Gogithub.com/modelcontextprotocol/go-sdkv1.6.1direct
Gogolang.org/x/cryptov0.54.0direct
Gogolang.org/x/modv0.38.0direct
Gogolang.org/x/netv0.57.0direct
Gogopkg.in/natefinch/lumberjack.v2v2.2.1direct
Gomodernc.org/sqlitev1.54.0direct
npmqrcode1.5.4direct
npmsvelte5.56.6direct
Gogithub.com/bytedance/gopkgv0.1.3indirect
Gogithub.com/bytedance/sonicv1.15.0indirect
Gogithub.com/bytedance/sonic/loaderv0.5.0indirect
Gogithub.com/cloudwego/base64xv0.1.6indirect
Gogithub.com/dustin/go-humanizev1.0.1indirect
Gogithub.com/gabriel-vasile/mimetypev1.4.12indirect
Gogithub.com/gin-contrib/ssev1.1.0indirect
Gogithub.com/go-playground/localesv0.14.1indirect
Gogithub.com/go-playground/universal-translatorv0.18.1indirect
Gogithub.com/go-playground/validator/v10v10.30.1indirect
Gogithub.com/goccy/go-jsonv0.10.5indirect
Gogithub.com/goccy/go-yamlv1.19.2indirect
Gogithub.com/google/jsonschema-gov0.4.3indirect
Gogithub.com/google/uuidv1.6.0indirect
Gogithub.com/gorilla/contextv1.1.2indirect
Gogithub.com/gorilla/securecookiev1.1.2indirect
Gogithub.com/gorilla/sessionsv1.4.0indirect
Gogithub.com/json-iterator/gov1.1.12indirect
Gogithub.com/klauspost/cpuid/v2v2.3.0indirect
Gogithub.com/leodido/go-urnv1.4.0indirect
Gogithub.com/mattn/go-isattyv0.0.20indirect
Gogithub.com/modern-go/concurrentv0.0.0-20180306012644-bacd9c7ef1ddindirect
Gogithub.com/modern-go/reflect2v1.0.2indirect
Gogithub.com/ncruces/go-strftimev1.0.0indirect
Gogithub.com/pelletier/go-toml/v2v2.2.4indirect
Gogithub.com/quic-go/qpackv0.6.0indirect
Gogithub.com/quic-go/quic-gov0.59.1indirect
Gogithub.com/remyoudompheng/bigfftv0.0.0-20230129092748-24d4a6f8daecindirect
Gogithub.com/segmentio/asmv1.1.3indirect
Gogithub.com/segmentio/encodingv0.5.4indirect
Gogithub.com/twitchyliquid64/golang-asmv0.15.1indirect
Gogithub.com/ugorji/go/codecv1.3.1indirect
Gogithub.com/yosida95/uritemplate/v3v3.0.2indirect
Gogo.mongodb.org/mongo-driver/v2v2.5.0indirect
Gogolang.org/x/archv0.22.0indirect
Gogolang.org/x/oauth2v0.35.0indirect
Gogolang.org/x/sysv0.47.0indirect
Gogolang.org/x/textv0.40.0indirect
Gogoogle.golang.org/protobufv1.36.10indirect
Gomodernc.org/libcv1.74.1indirect
Gomodernc.org/mathutilv1.7.1indirect
Gomodernc.org/memoryv1.11.0indirect
npm@asamuzakjp/css-color5.1.11indirect
npm@asamuzakjp/dom-selector7.1.1indirect
npm@asamuzakjp/generational-cache1.0.1indirect
npm@asamuzakjp/nwsapi2.3.9indirect
npm@babel/helper-string-parser7.29.7indirect
npm@babel/helper-validator-identifier7.29.7indirect
npm@babel/parser7.29.7indirect
npm@babel/types7.29.7indirect
npm@bcoe/v8-coverage1.0.2indirect
npm@bramus/specificity2.4.2indirect
npm@csstools/color-helpers6.0.2indirect
npm@csstools/css-calc3.2.0indirect
npm@csstools/css-color-parser4.1.0indirect
npm@csstools/css-parser-algorithms4.0.0indirect
npm@csstools/css-syntax-patches-for-csstree1.1.3indirect
npm@csstools/css-tokenizer4.0.0indirect
npm@emnapi/core1.11.1indirect
npm@emnapi/runtime1.11.1indirect
npm@emnapi/wasi-threads1.2.2indirect
npm@eslint-community/eslint-utils4.9.1indirect
npm@eslint-community/regexpp4.12.2indirect
npm@eslint/config-array0.23.5indirect
npm@eslint/config-helpers0.6.0indirect
npm@eslint/core1.2.1indirect
npm@eslint/js10.0.1indirect
npm@eslint/object-schema3.0.5indirect
npm@eslint/plugin-kit0.7.2indirect
npm@exodus/bytes1.15.0indirect
npm@humanfs/core0.19.2indirect
npm@humanfs/node0.16.8indirect
npm@humanfs/types0.15.0indirect
npm@humanwhocodes/module-importer1.0.1indirect
npm@humanwhocodes/retry0.4.3indirect
npm@jridgewell/gen-mapping0.3.13indirect
npm@jridgewell/remapping2.3.5indirect
npm@jridgewell/resolve-uri3.1.2indirect
npm@jridgewell/sourcemap-codec1.5.5indirect
npm@jridgewell/trace-mapping0.3.31indirect
npm@napi-rs/wasm-runtime1.1.6indirect
npm@oxc-project/types0.138.0indirect
npm@playwright/test1.61.1indirect
npm@rolldown/binding-android-arm641.1.4indirect
npm@rolldown/binding-darwin-arm641.1.4indirect
npm@rolldown/binding-darwin-x641.1.4indirect
npm@rolldown/binding-freebsd-x641.1.4indirect
npm@rolldown/binding-linux-arm-gnueabihf1.1.4indirect
npm@rolldown/binding-linux-arm64-gnu1.1.4indirect
npm@rolldown/binding-linux-arm64-musl1.1.4indirect
npm@rolldown/binding-linux-ppc64-gnu1.1.4indirect
npm@rolldown/binding-linux-s390x-gnu1.1.4indirect
npm@rolldown/binding-linux-x64-gnu1.1.4indirect
npm@rolldown/binding-linux-x64-musl1.1.4indirect
npm@rolldown/binding-openharmony-arm641.1.4indirect
npm@rolldown/binding-wasm32-wasi1.1.4indirect
npm@rolldown/binding-win32-arm64-msvc1.1.4indirect
npm@rolldown/binding-win32-x64-msvc1.1.4indirect
npm@rolldown/pluginutils1.0.1indirect
npm@standard-schema/spec1.1.0indirect
npm@sveltejs/acorn-typescript1.0.10indirect
npm@sveltejs/vite-plugin-svelte7.1.3indirect
npm@tybys/wasm-util0.10.3indirect
npm@types/chai5.2.3indirect
npm@types/deep-eql4.0.2indirect
npm@types/esrecurse4.3.1indirect
npm@types/estree1.0.9indirect
npm@types/json-schema7.0.15indirect
npm@types/node25.7.0indirect
npm@types/qrcode1.5.6indirect
npm@types/trusted-types2.0.7indirect
npm@typescript-eslint/eslint-plugin8.62.1indirect
npm@typescript-eslint/parser8.62.1indirect
npm@typescript-eslint/project-service8.62.1indirect
npm@typescript-eslint/scope-manager8.62.1indirect
npm@typescript-eslint/tsconfig-utils8.62.1indirect
npm@typescript-eslint/type-utils8.62.1indirect
npm@typescript-eslint/types8.62.1indirect
npm@typescript-eslint/typescript-estree8.62.1indirect
npm@typescript-eslint/utils8.62.1indirect
npm@typescript-eslint/visitor-keys8.62.1indirect
npm@vitest/coverage-v84.1.10indirect
npm@vitest/expect4.1.10indirect
npm@vitest/mocker4.1.10indirect
npm@vitest/pretty-format4.1.10indirect
npm@vitest/runner4.1.10indirect
npm@vitest/snapshot4.1.10indirect
npm@vitest/spy4.1.10indirect
npm@vitest/utils4.1.10indirect
npmacorn8.16.0indirect
npmacorn-jsx5.3.2indirect
npmajv6.15.0indirect
npmansi-regex5.0.1indirect
npmansi-styles4.3.0indirect
npmaria-query5.3.1indirect
npmassertion-error2.0.1indirect
npmast-v8-to-istanbul1.0.4indirect
npmaxobject-query4.1.0indirect
npmbalanced-match4.0.4indirect
npmbidi-js1.0.3indirect
npmbrace-expansion5.0.6indirect
npmcamelcase5.3.1indirect
npmchai6.2.2indirect
npmcliui6.0.0indirect
npmclsx2.1.1indirect
npmcolor-convert2.0.1indirect
npmcolor-name1.1.4indirect
npmconvert-source-map2.0.0indirect
npmcross-spawn7.0.6indirect
npmcss-tree3.2.1indirect
npmcssesc3.0.0indirect
npmdata-urls7.0.0indirect
npmdebug4.4.3indirect
npmdecamelize1.2.0indirect
npmdecimal.js10.6.0indirect
npmdeep-is0.1.4indirect
npmdeepmerge4.3.1indirect
npmdetect-libc2.1.2indirect
npmdevalue5.8.1indirect
npmdijkstrajs1.0.3indirect
npmemoji-regex8.0.0indirect
npmentities8.0.0indirect
npmes-module-lexer2.1.0indirect
npmescape-string-regexp4.0.0indirect
npmeslint10.6.0indirect
npmeslint-config-prettier10.1.8indirect
npmeslint-plugin-svelte3.20.0indirect
npmeslint-scope8.4.0indirect
npmeslint-scope9.1.2indirect
npmeslint-visitor-keys3.4.3indirect
npmeslint-visitor-keys4.2.1indirect
npmeslint-visitor-keys5.0.1indirect
npmesm-env1.2.2indirect
npmespree10.4.0indirect
npmespree11.2.0indirect
npmesquery1.7.0indirect
npmesrap2.2.13indirect
npmesrecurse4.3.0indirect
npmestraverse5.3.0indirect
npmestree-walker3.0.3indirect
npmesutils2.0.3indirect
npmexpect-type1.3.0indirect
npmfast-deep-equal3.1.3indirect
npmfast-json-stable-stringify2.1.0indirect
npmfast-levenshtein2.0.6indirect
npmfdir6.5.0indirect
npmfile-entry-cache8.0.0indirect
npmfind-up4.1.0indirect
npmfind-up5.0.0indirect
npmflat-cache4.0.1indirect
npmflatted3.4.2indirect
npmfsevents2.3.2indirect
npmfsevents2.3.3indirect
npmget-caller-file2.0.5indirect
npmglob-parent6.0.2indirect
npmglobals16.5.0indirect
npmhas-flag4.0.0indirect
npmhtml-encoding-sniffer6.0.0indirect
npmhtml-escaper2.0.2indirect
npmignore5.3.2indirect
npmignore7.0.5indirect
npmimurmurhash0.1.4indirect
npmis-extglob2.1.1indirect
npmis-fullwidth-code-point3.0.0indirect
npmis-glob4.0.3indirect
npmis-potential-custom-element-name1.0.1indirect
npmis-reference3.0.3indirect
npmisexe2.0.0indirect
npmistanbul-lib-coverage3.2.2indirect
npmistanbul-lib-report3.0.1indirect
npmistanbul-reports3.2.0indirect
npmjs-tokens10.0.0indirect
npmjsdom29.1.1indirect
npmjson-buffer3.0.1indirect
npmjson-schema-traverse0.4.1indirect
npmjson-stable-stringify-without-jsonify1.0.1indirect
npmkeyv4.5.4indirect
npmknown-css-properties0.37.0indirect
npmlevn0.4.1indirect
npmlightningcss1.32.0indirect
npmlightningcss-android-arm641.32.0indirect
npmlightningcss-darwin-arm641.32.0indirect
npmlightningcss-darwin-x641.32.0indirect
npmlightningcss-freebsd-x641.32.0indirect
npmlightningcss-linux-arm-gnueabihf1.32.0indirect
npmlightningcss-linux-arm64-gnu1.32.0indirect
npmlightningcss-linux-arm64-musl1.32.0indirect
npmlightningcss-linux-x64-gnu1.32.0indirect
npmlightningcss-linux-x64-musl1.32.0indirect
npmlightningcss-win32-arm64-msvc1.32.0indirect
npmlightningcss-win32-x64-msvc1.32.0indirect
npmlilconfig2.1.0indirect
npmlocate-character3.0.0indirect
npmlocate-path5.0.0indirect
npmlocate-path6.0.0indirect
npmlru-cache11.3.6indirect
npmmagic-string0.30.21indirect
npmmagicast0.5.3indirect
npmmake-dir4.0.0indirect
npmmdn-data2.27.1indirect
npmminimatch10.2.5indirect
npmms2.1.3indirect
npmnanoid3.3.12indirect
npmnatural-compare1.4.0indirect
npmobug2.1.1indirect
npmoptionator0.9.4indirect
npmp-limit2.3.0indirect
npmp-limit3.1.0indirect
npmp-locate4.1.0indirect
npmp-locate5.0.0indirect
npmp-try2.2.0indirect
npmparse58.0.1indirect
npmpath-exists4.0.0indirect
npmpath-key3.1.1indirect
npmpathe2.0.3indirect
npmpicocolors1.1.1indirect
npmpicomatch4.0.4indirect
npmplaywright1.61.1indirect
npmplaywright-core1.61.1indirect
npmpngjs5.0.0indirect
npmpostcss8.5.16indirect
npmpostcss-load-config3.1.4indirect
npmpostcss-safe-parser7.0.1indirect
npmpostcss-scss4.0.9indirect
npmpostcss-selector-parser7.1.1indirect
npmprelude-ls1.2.1indirect
npmprettier3.9.4indirect
npmprettier-plugin-svelte4.1.1indirect
npmpunycode2.3.1indirect
npmrequire-directory2.1.1indirect
npmrequire-from-string2.0.2indirect
npmrequire-main-filename2.0.0indirect
npmrolldown1.1.4indirect
npmsaxes6.0.0indirect
npmsemver7.8.0indirect
npmset-blocking2.0.0indirect
npmshebang-command2.0.0indirect
npmshebang-regex3.0.0indirect
npmsiginfo2.0.0indirect
npmsource-map-js1.2.1indirect
npmstackback0.0.2indirect
npmstd-env4.1.0indirect
npmstring-width4.2.3indirect
npmstrip-ansi6.0.1indirect
npmsupports-color7.2.0indirect
npmsvelte-eslint-parser1.8.0indirect
npmsymbol-tree3.2.4indirect
npmtinybench2.9.0indirect
npmtinyexec1.1.2indirect
npmtinyglobby0.2.17indirect
npmtinyrainbow3.1.0indirect
npmtldts7.0.30indirect
npmtldts-core7.0.30indirect
npmtough-cookie6.0.1indirect
npmtr466.0.0indirect
npmts-api-utils2.5.0indirect
npmtslib2.8.1indirect
npmtype-check0.4.0indirect
npmtypescript6.0.3indirect
npmtypescript-eslint8.62.1indirect
npmundici7.28.0indirect
npmundici-types7.21.0indirect
npmuri-js4.4.1indirect
npmutil-deprecate1.0.2indirect
npmvite8.1.3indirect
npmvitefu1.1.3indirect
npmvitest4.1.10indirect
npmw3c-xmlserializer5.0.0indirect
npmwebidl-conversions8.0.1indirect
npmwhatwg-mimetype5.0.0indirect
npmwhatwg-url16.0.1indirect
npmwhich2.0.2indirect
npmwhich-module2.0.1indirect
npmwhy-is-node-running2.3.0indirect
npmword-wrap1.2.5indirect
npmwrap-ansi6.2.0indirect
npmxml-name-validator5.0.0indirect
npmxmlchars2.2.0indirect
npmy18n4.0.3indirect
npmyaml1.10.3indirect
npmyargs15.4.1indirect
npmyargs-parser18.1.3indirect
npmyocto-queue0.1.0indirect
npmzimmerframe1.1.4indirect
Dependency advisories 2

This repository publishes no package the index resolves, so its own dependency graph was assessed — 334 packages, which also include development and test pins that never ship: 2 carry known advisories, of which 1 are direct.

PackageVersionRelationSeverityAdvisoriesFixed in
brace-expansion5.0.6indirecthigh15.0.7
golang.org/x/cryptov0.54.0directunknown1

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

Raw JSON report machine-readable
{
  "data": {
    "repo": {
      "topics": [
        "docker",
        "firmware-management",
        "golang",
        "home-automation",
        "iot",
        "mcp",
        "self-hosted",
        "shelly",
        "smart-home",
        "svelte"
      ],
      "is_fork": false,
      "size_kb": 5932,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 1056708,
        "CSS": 29203,
        "HTML": 361,
        "Shell": 3057,
        "Svelte": 313750,
        "Makefile": 966,
        "Dockerfile": 2173,
        "JavaScript": 8176,
        "TypeScript": 145700
      },
      "pushed_at": "2026-07-23T06:11:23Z",
      "created_at": "2026-04-08T18:24:09Z",
      "owner_type": "User",
      "updated_at": "2026-07-23T06:08:12Z",
      "description": "Self-hosted web app to discover, inventory, firmware-check, and provision Shelly Gen2+ devices on a trusted LAN. Single Go binary + Svelte UI, Docker-ready, with an opt-in MCP server.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Go",
      "significant_languages": [
        "Go",
        "Svelte"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Dominik Sennfelder",
      "type": "User",
      "login": "buliwyf42",
      "company": null,
      "location": null,
      "followers": 2,
      "avatar_url": "https://avatars.githubusercontent.com/u/4658822?v=4",
      "created_at": "2013-06-10T07:17:51Z",
      "is_verified": null,
      "public_repos": 4,
      "account_age_days": 4792
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.6.3",
          "kind": "patch",
          "published_at": "2026-07-23T06:21:10Z"
        },
        {
          "tag": "v0.6.2",
          "kind": "patch",
          "published_at": "2026-07-22T17:35:26Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-07-22T15:37:45Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-07-22T15:07:56Z"
        },
        {
          "tag": "v0.5.7",
          "kind": "patch",
          "published_at": "2026-07-17T10:07:05Z"
        },
        {
          "tag": "v0.5.5",
          "kind": "patch",
          "published_at": "2026-07-01T20:32:42Z"
        },
        {
          "tag": "v0.5.4",
          "kind": "patch",
          "published_at": "2026-07-01T19:39:55Z"
        },
        {
          "tag": "v0.5.3",
          "kind": "patch",
          "published_at": "2026-06-10T18:13:43Z"
        },
        {
          "tag": "v0.5.2",
          "kind": "patch",
          "published_at": "2026-05-29T07:20:28Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-05-24T19:11:09Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-05-23T09:09:49Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-05-20T16:37:54Z"
        },
        {
          "tag": "v0.3.6",
          "kind": "patch",
          "published_at": "2026-05-20T12:35:26Z"
        },
        {
          "tag": "v0.3.5",
          "kind": "patch",
          "published_at": "2026-05-20T10:20:33Z"
        },
        {
          "tag": "v0.3.4",
          "kind": "patch",
          "published_at": "2026-05-20T07:59:16Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-05-12T08:54:13Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-05-12T06:14:02Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-05-12T05:51:23Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-05-12T04:45:44Z"
        },
        {
          "tag": "v0.2.13",
          "kind": "patch",
          "published_at": "2026-05-11T14:28:44Z"
        },
        {
          "tag": "v0.2.12",
          "kind": "patch",
          "published_at": "2026-05-11T13:48:33Z"
        },
        {
          "tag": "v0.2.11",
          "kind": "patch",
          "published_at": "2026-05-11T12:30:49Z"
        },
        {
          "tag": "v0.2.10",
          "kind": "patch",
          "published_at": "2026-05-11T11:56:07Z"
        },
        {
          "tag": "v0.2.9",
          "kind": "patch",
          "published_at": "2026-05-11T09:27:25Z"
        },
        {
          "tag": "v0.2.8",
          "kind": "patch",
          "published_at": "2026-05-11T08:18:28Z"
        },
        {
          "tag": "v0.2.7",
          "kind": "patch",
          "published_at": "2026-05-11T05:07:56Z"
        },
        {
          "tag": "v0.2.6",
          "kind": "patch",
          "published_at": "2026-05-11T04:59:45Z"
        },
        {
          "tag": "v0.2.5",
          "kind": "patch",
          "published_at": "2026-05-11T04:56:58Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-05-11T04:51:36Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-05-10T20:15:59Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-05-10T19:29:20Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-05-10T18:34:17Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-05-10T17:32:53Z"
        },
        {
          "tag": "v0.1.23",
          "kind": "patch",
          "published_at": "2026-05-10T06:57:46Z"
        },
        {
          "tag": "v0.1.22",
          "kind": "patch",
          "published_at": "2026-05-09T21:21:44Z"
        },
        {
          "tag": "v0.1.21",
          "kind": "patch",
          "published_at": "2026-05-09T20:41:54Z"
        },
        {
          "tag": "v0.1.20",
          "kind": "patch",
          "published_at": "2026-05-09T14:36:04Z"
        },
        {
          "tag": "v0.1.19",
          "kind": "patch",
          "published_at": "2026-05-09T13:40:52Z"
        },
        {
          "tag": "v0.1.18",
          "kind": "patch",
          "published_at": "2026-05-08T21:50:53Z"
        },
        {
          "tag": "v0.1.17",
          "kind": "patch",
          "published_at": "2026-05-08T21:41:31Z"
        },
        {
          "tag": "v0.1.16",
          "kind": "patch",
          "published_at": "2026-05-08T14:41:45Z"
        },
        {
          "tag": "v0.1.15",
          "kind": "patch",
          "published_at": "2026-05-08T14:29:24Z"
        },
        {
          "tag": "v0.1.13",
          "kind": "patch",
          "published_at": "2026-05-09T07:07:37Z"
        },
        {
          "tag": "v0.1.12",
          "kind": "patch",
          "published_at": "2026-05-07T13:19:49Z"
        },
        {
          "tag": "v0.1.11",
          "kind": "patch",
          "published_at": "2026-05-07T12:54:23Z"
        },
        {
          "tag": "v0.1.10",
          "kind": "patch",
          "published_at": "2026-05-07T12:26:16Z"
        },
        {
          "tag": "v0.1.9",
          "kind": "patch",
          "published_at": "2026-05-07T12:07:39Z"
        },
        {
          "tag": "v0.1.8",
          "kind": "patch",
          "published_at": "2026-05-07T11:56:19Z"
        },
        {
          "tag": "v0.1.7",
          "kind": "patch",
          "published_at": "2026-05-06T20:26:14Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-05-06T13:54:38Z"
        },
        {
          "tag": "v0.1.5",
          "kind": "patch",
          "published_at": "2026-05-06T13:54:36Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-05-04T05:51:40Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-05-04T04:22:42Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-05-03T20:48:18Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-05-03T19:09:47Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-05-03T18:29:17Z"
        },
        {
          "tag": "v0.0.16",
          "kind": "patch",
          "published_at": "2026-04-24T09:04:05Z"
        },
        {
          "tag": "v0.0.15",
          "kind": "patch",
          "published_at": "2026-04-22T04:33:33Z"
        },
        {
          "tag": "v0.0.14",
          "kind": "patch",
          "published_at": "2026-04-21T15:15:45Z"
        },
        {
          "tag": "v0.0.13",
          "kind": "patch",
          "published_at": "2026-04-21T13:22:43Z"
        },
        {
          "tag": "v0.0.12",
          "kind": "patch",
          "published_at": "2026-04-21T11:47:52Z"
        },
        {
          "tag": "v0.0.11",
          "kind": "patch",
          "published_at": "2026-04-18T21:21:20Z"
        },
        {
          "tag": "v0.0.10",
          "kind": "patch",
          "published_at": "2026-04-18T10:05:26Z"
        },
        {
          "tag": "v0.0.9",
          "kind": "patch",
          "published_at": "2026-04-17T21:58:18Z"
        },
        {
          "tag": "v0.0.8",
          "kind": "patch",
          "published_at": "2026-04-16T14:59:41Z"
        },
        {
          "tag": "v0.0.7",
          "kind": "patch",
          "published_at": "2026-04-16T11:52:10Z"
        },
        {
          "tag": "v0.0.6",
          "kind": "patch",
          "published_at": "2026-04-16T10:27:37Z"
        },
        {
          "tag": "v0.0.5",
          "kind": "patch",
          "published_at": "2026-04-15T14:12:44Z"
        },
        {
          "tag": "v0.0.4",
          "kind": "patch",
          "published_at": "2026-04-14T06:55:27Z"
        },
        {
          "tag": "v0.0.3",
          "kind": "patch",
          "published_at": "2026-04-14T06:47:16Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "c580f1054f27a87e07bb176023a7aa42294cbd58",
          "body": "…eanup\n\nBundles everything since v0.6.2: the ponytail-audit dead-code removal\n(42ad598, bae92ee) and the Model-column app-vs-marketing-name precedence\nfix (db59dd9).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.6.3 — fix Model-column marketing name + ponytail-audit cl…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-23T06:07:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d00d219356e58dc61e6ecb3c88e743b426fefbde",
          "body": "42ad598 and bae92ee landed without a CHANGELOG entry. Documenting them\nnow so the v0.6.3 release notes cover everything since v0.6.2, not just\nthe Model-column precedence fix.",
          "is_bot": false,
          "headline": "docs: changelog entry for the ponytail-audit cleanup commits",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-23T06:05:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "db59dd9c5041300046e1c16cdb7eff8f7f8bc9a6",
          "body": "Firmware.svelte and DeviceTable.svelte displayed `app || friendly || model`\nin the Model column. Shelly's own `app` field (e.g. \"Plus1\") is populated on\nvirtually every real device, so it always beat the marketing name added in\n0.6.1 — the friendly name only ever reached the tooltip, never the visible\ncell. Flipped to `friendly || app || model`.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: marketing name never showed — app code always won the precedence",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-23T06:02:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bae92ee64f55a9bbc58e508c6c8d960288acacbc",
          "body": "CI's Model schema drift check caught internal/models/schema.gen.json\nbeing stale after the TOTPRequired field removal — regenerated via\ngo run ./cmd/modelschema.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Regenerate model schema after removing TOTPRequired",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-23T05:57:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "42ad5984abec65d6e83980bdf3660c941dffff5c",
          "body": "Cuts dead code and refactor debris flagged by a repo-wide audit: unused\nTOTPRequired/JobID fields, a single-caller RequireAnyScope, hand-rolled\nlastIndexByte/jsonMarshal wrappers, MCPBuilder/MCPController aliases, the\nGroupSaver single-impl interface, duplicate request-ID sanitizers between\nmcp/serv\n[…]\napp_jobs.go's larger ~200-line forwarding shim is intentionally left in\nplace (~15 live call sites across api/mcp/cmd) as a separate follow-up.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Remove over-engineering findings from ponytail-audit",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-23T05:51:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ffff54d2cf36999fd455b343404c53cdf22cb888",
          "body": "See 55b2325 for the implementation.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.6.2 — configurable badge color for feature-frozen devices",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T17:21:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "55b2325ad0d091ea704c798dd2ef7506ffc81959",
          "body": "Extends the existing gen2/gen3/gen4 badge-color settings with a fourth,\ngen_frozen_badge_class (default amber/orange, matching gen2's), that\noverrides the generation badge for any device with fw_frozen=true,\nregardless of its actual gen. Shows as \"Gen N.x (frozen)\" on both the\nDevices table and the \n[…]\neded.\n\nRemoves the standalone \"frozen\" text badge from the Firmware page's\nModel column; the enhanced generation badge now carries that signal.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add configurable badge color for feature-frozen devices",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T17:19:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "72c03dade07d3c95641148214c3b308f49fb29da",
          "body": "CI's Go lint job (golangci-lint v2.12, staticcheck) started flagging 7\nsites in probe_clock_test.go/probe_strict_test.go as possible nil\ndereferences after \"if dev == nil { t.Fatal(...) }\" — a standard Go test\nidiom that relies on t.Fatal's runtime.Goexit() to halt the test. Not\nreproducible with th\n[…]\nss of whether the analyzer can prove\n*testing.T's method is non-returning, which is the standard fix for this\nstaticcheck false-positive class.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(lint): silence SA5011 false positive on t.Fatal(f) nil-guards",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T15:37:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8c0b67323547c967ba1264f54e89087093497786",
          "body": "The Model column on the Firmware and Devices pages now shows the Shelly\nmarketing name alongside/instead of the raw SKU. See 4f7dfcb for the\nimplementation.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.6.1 — show Shelly marketing names next to model SKUs",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T15:08:10Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4f7dfcbcf30952f19b9e40a20f3e680ba4c8de91",
          "body": "The Model column on the Firmware and Devices pages only ever showed the\nraw SKU (SNSW-001X16EU) or Shelly's own app code (Plus1PM) - neither is\nthe name a user recognizes. modelName() in web/src/lib/shellyModels.ts\nresolves a SKU to its marketing name (\"Shelly Plus 1\") from a static\n144-entry table \n[…]\nnst.py MODEL_NAMES, the same\nsource already used for the feature-frozen allowlist. Frontend-only: pure\ndisplay formatting, no Go/DB/API change.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Show Shelly marketing names next to model SKUs",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T15:08:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1833c8555262c6f7d625f2f1442b74a780ab8308",
          "body": "CI's Go lint job caught this on the v0.6.0 push — my flag_frozen_firmware\nedit broke gofmt's column alignment for the surrounding fields.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: gofmt ComplianceRules struct alignment",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T14:59:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "94006567cd782d71ebc20cb9462970fcb59ac82b",
          "body": null,
          "is_bot": false,
          "headline": "Merge remote-tracking branch 'origin/main' into main",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T14:48:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "379138af1ddb1597c7a67f2cb99c9554f673c69c",
          "body": "Devices on a Shelly firmware line that will never receive 2.0.0+ now get a\n\"frozen\" badge on the Firmware page, plus an opt-in compliance rule\n(flag_frozen_firmware). See d34d9ed for the implementation.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.6.0 — flag feature-frozen Shelly firmware lines",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T14:48:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d34d9edf7649c596484eec01457c538a5615e16b",
          "body": "Devices on a Shelly firmware line that will never receive 2.0.0+ (Plus 1,\nPlus 1 Mini, Plus 1 PM, Plus 1 PM Mini, Plus 2 PM, Plus PM Mini, Plus i4,\nPlus Plug S/US, Plus H&T, Plus 0-10V Dimmer, BLU Gateway Gen2) now get a\n\"frozen\" badge on the Firmware page, and can optionally be surfaced as a\ncompli\n[…]\ned\nat GetDevices() time like FWAlt/Provisioning, no migration, no extra RPC.\nPurely informational per ADR-0002: never gates the install action.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Flag feature-frozen Shelly firmware lines (Firmware Update Policy)",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T14:46:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "51e882a4befeafb8d8ab17649aa45d04119f0dc0",
          "body": "…settled\n\nCorrected the fleet count while at it (27, not 31, run 2.0.0 -- a\ncounting slip from the prior commit). Uptime dating shows nothing\nadopted 2.0.0 in the three days after release, and nothing has moved\nin five nights since the 2026-07-17 fleet OTA despite daily\nstage:stable polling -- consi\n[…]\nce) doesn't distinguish that from ordinary per-device\nbucketing. Left open pending an index snapshot over time rather than\nasserted either way.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: mark firmware-2.0.0-rollout-paused question as unresolved, not …",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T07:45:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d4c80e987a687f208dfd07e1b82f1b61a0b110db",
          "body": "…t shortcut a rollout\n\nContrary to the forum consensus that Gen2+ has no offline update path,\n`curl -k https://updates.shelly.cloud/update/<APP>` returns stable/beta\nwith a direct fwcdn URL (-k required: Allterco internal CA). Verified the\nCDN serves the ZIP to a LAN host.\n\nRecords the negative resu\n[…]\nthe open\n`premature end of data` failures, and the missing beta branch on\nPlus1/Plus2PM dates the Gen2 Plus EOL without trusting a vendor post.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: firmware index at updates.shelly.cloud — found, and why it can'…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-22T07:37:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cd1a365ff54fab7ef535442c9c98f23417dc07ce",
          "body": "…t a floor\n\nTwo traps hit while diagnosing why one of two identical S4PL-00416EU strips\nwas not offered 2.0.0:\n\n- The phased rollout is keyed per device id, so the same model can be offered\n  different stable versions in the same minute. Not a device fault.\n- Schedule stage \"beta\" installs only the beta slot; it never picks up a later\n  stable release. For a device parked ahead of its own stable channel,\n  \"stable\" is the correct setting.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Docs: firmware rollout is per device; auto-update stage is a slot, no…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-21T06:33:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "34a0399ad46b0a1e08f34276f7d3a5cc6972381f",
          "body": "Bumps the go-dependencies group with 2 updates: [golang.org/x/mod](https://github.com/golang/mod) and [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).\n\n\nUpdates `golang.org/x/mod` from 0.37.0 to 0.38.0\n- [Commits](https://github.com/golang/mod/compare/v0.37.0...v0.38.0)\n\nUpdates `modernc.org/s\n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump the go-dependencies group with 2 updates (#85)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-20T17:49:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c8af61910f3ecced8b44df0013948a680c017ff6",
          "body": "Bumps the npm-prod-dependencies group in /web with 1 update: [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte).\n\n\nUpdates `svelte` from 5.56.4 to 5.56.6\n- [Release notes](https://github.com/sveltejs/svelte/releases)\n- [Changelog](https://github.com/sveltejs/svelte/blob/main/pack\n[…]\ndate:semver-patch\n  dependency-group: npm-prod-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump svelte in /web in the npm-prod-dependencies group (#83)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-20T17:48:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b666a22b857991477c0079565c68d3afe090df60",
          "body": "…the image\n\nThe release path told operators to pull the image and then call start_stack\n(\"or restart_stack if already up\"). Neither recreates the container, so both\nleave the old image running while reporting success.\n\nVerified 2026-07-17 during the v0.5.7 deploy: pull_image + start_stack returned\n{\n[…]\nongside\nthe verification step that would have caught this: check the container's\nImageID and a version-specific API field, not the tool output.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: correct the deploy step — start_stack/restart_stack don't swap …",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-17T11:21:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6db037c10a5c422dfab36728e1bae8ee6976c532",
          "body": "v0.5.6 claimed firmware installs failed because ShellyAdmin polled the device\nduring the download, starving it. That claim was wrong and is withdrawn.\n\nIt rested on comparing two different devices — one unpolled that succeeded, one\npolled that failed — and crediting the difference to polling. The po\n[…]\nd 150s, so the persisted\n  and effective values diverged and the timeout floor under-sized the polling\n  window. Normalize now defaults it too.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.5.7 — retract v0.5.6's root cause; patch the build's Go",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-17T09:53:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "218400ee73ccad55dbe90d8386bf1ba4c35286a9",
          "body": "…period\n\nThe v0.5.6 release commit added AppSettings.FirmwareInstallQuietPeriod and the\nmatching web/src/lib/types.ts field, but left internal/models/schema.gen.json\nstale, so the \"Model schema drift check\" step of the Go tests job failed on main.\n\nThe snapshot is a CI drift guard only — it is never embedded or read at runtime,\nso the published v0.5.6 image is unaffected.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(models): regenerate schema snapshot for firmware_install_quiet_…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-17T07:13:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bdd17800451e9f86e3202e096c62091831d1fe4e",
          "body": "Firmware installs triggered from ShellyAdmin failed on every attempt, while\nthe same update applied fine from Shelly's cloud rollout or the device's own\nweb UI. The cause was ShellyAdmin itself.\n\ninstallOne began polling Shelly.GetDeviceInfo every 5s immediately after\ntriggering Shelly.Update. A dev\n[…]\nst firmware_check, so a device installing anything else was reported as\n\"unknown\" despite having updated. Any move off the original now counts.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.5.6 — stop starving the OTA we're waiting for",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-17T06:59:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "abcb6876542e9697290697a67eed2e9cb233f766",
          "body": "Bumps the go-dependencies group with 2 updates: [golang.org/x/crypto](https://github.com/golang/crypto) and [golang.org/x/net](https://github.com/golang/net).\n\n\nUpdates `golang.org/x/crypto` from 0.53.0 to 0.54.0\n- [Commits](https://github.com/golang/crypto/compare/v0.53.0...v0.54.0)\n\nUpdates `golan\n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump the go-dependencies group with 2 updates (#81)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-13T17:53:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e80cde0ca1dbb3d9aa10913a5cd9f3d624ca078a",
          "body": "Bumps the npm-dev-dependencies group in /web with 5 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [@sveltejs/vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte/tree/HEAD/packages/vite-plugin-svelte) | `7.1.2` | `7.1.3` |\n| [@vitest/coverage-v8](https://github.com/vitest-dev\n[…]\npdate:semver-patch\n  dependency-group: npm-dev-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps-dev): bump the npm-dev-dependencies group (#80)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-06T17:49:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d0c03fcdfecf675ddf29508acbf4f1fec51011c8",
          "body": "Bumps the github-actions group with 5 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `4.1.0` | `4.2.0` |\n| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.1.0` | `4.2.0` |\n| [docker/lo\n[…]\nsion-update:semver-minor\n  dependency-group: github-actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "ci(deps): bump the github-actions group with 5 updates (#79)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-06T17:48:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb7da0efdd0afe03c25b3aaa5fd6cdae57493882",
          "body": "Housekeeping roll-up, no runtime behaviour change:\n- Dependabot: Alpine runtime base 3.23→3.24 (CVE-clean, verified locally\n  with trivy: 0 HIGH/CRITICAL), node/golang build-stage digests, web dev-deps\n  (playwright/eslint/prettier/vitest/vite), CI actions (checkout v6→v7,\n  setup-go, golangci-lint)\n[…]\nonytail-audit dead-code removal (ProgressBar label prop, supportsWebSocket\n  placeholder, FirmwareUpdateResult type).\n\nBundles PRs #78, #77, #75 + the ponytail cleanup. Full changelog in\nCHANGELOG.md.",
          "is_bot": false,
          "headline": "release: v0.5.5",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-01T20:19:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f00efcf05735254886e0a9703254122334a539ad",
          "body": "…ates\n\nBumps the github-actions group with 3 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [actions/setup-go](https://github.com/actions/setup-go) and [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action).\n\n\nUpdates `actions/checkout\n[…]\n\n  dependency-version: 9.3.0\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n  dependency-group: github-actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "ci(deps): bump the github-actions group across 1 directory with 3 upd…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-01T20:13:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "865978a90bacb9966c9ae98d90b8ef4f77ff954d",
          "body": "…y with 12 updates\n\nBumps the npm-dev-dependencies group with 10 updates in the /web directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [@playwright/test](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.1` |\n| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint\n[…]\nndency-version: 4.1.9\n  dependency-type: direct:development\n  update-type: version-update:semver-patch\n  dependency-group: npm-dev-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "deps(deps-dev): bump the npm-dev-dependencies group across 1 director…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-01T20:13:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a01b9862f9b9f25abb8e743e48389d1016829aeb",
          "body": "…h 3 updates\n\nBumps the docker-dependencies group with 3 updates in the /docker directory: node, golang and alpine.\n\n\nUpdates `node` from `144769e` to `725aeba`\n\nUpdates `golang` from `f23e8b2` to `3ad5730`\n\nUpdates `alpine` from 3.23 to 3.24\n\n---\nupdated-dependencies:\n- dependency-name: alpine\n  de\n[…]\npendencies\n- dependency-name: node\n  dependency-version: 26-alpine\n  dependency-type: direct:production\n  dependency-group: docker-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump the docker-dependencies group across 1 directory wit…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-01T20:13:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dfaec4fbbeaea3c5eac1b5297fcef6b88a7ff6a7",
          "body": "Three verified-unused items (grep-confirmed zero references), net -37 lines:\n- ProgressBar `label` prop + both {#if label} branches + labelInside\n  reactive + .pb-label/.pb-label-below CSS — no caller ever passed label.\n- deviceFormatters.supportsWebSocket() — speculative placeholder, 0 callers.\n- t\n[…]\nt's other \"dead type\" hits (AltFirmwareVariant, FWResult,\nBulkActionTarget, ProvisionDeviceInfo/SectionResult) were false positives —\nall used via parent interfaces in api.ts — and were left in place.",
          "is_bot": false,
          "headline": "chore(web): remove dead code found by ponytail-audit",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-01T19:46:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "55b7117012705e9b8a304f345c84910c89e3e92d",
          "body": "The pinned digest carried libcrypto3/libssl3 3.5.6-r0 (openssl heap\nuse-after-free in PKCS7_verify, HIGH). Trivy gates publish-image.yml on\nHIGH/CRITICAL, blocking the v0.5.4 image release. Bumped to a newer\nalpine:3.23 point-in-time digest shipping 3.5.7-r0 (verified: same\nmulti-arch manifest list, amd64 included). Confirmed 0 vulns with a\nlocal build + trivy scan using the same severity/ignore-unfixed flags\nas CI before pushing.",
          "is_bot": false,
          "headline": "fix(docker): bump alpine 3.23 runtime base to clear CVE-2026-45447",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-01T19:26:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2c87b8a8a2c364540cfcceb37ace55f7c83dd0ea",
          "body": "…sioning\n\nThe v0.5.4 release commit failed CI: alt_firmware_test.go had two\nseparate import declarations instead of one grouped block (goimports),\nand schema.gen.json wasn't regenerated after adding FWAlt/Provisioning\nto models.Device (cmd/modelschema --check catches Go struct fields\nadded without an update to the tracked schema).",
          "is_bot": false,
          "headline": "fix(ci): goimports grouping + regenerate model schema for FWAlt/Provi…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-01T19:08:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "33fac53e3461b4c06c790e94368c22028b7bba3c",
          "body": "Shelly firmware 2.0.0-beta3 support: read-only visibility of alternative\nfirmware variants (sys.alt — Zigbee/Matter builds of the same hardware)\nand secure-provisioning status (sys.provisioning), surfaced on\n/api/devices, MCP get_device/list_devices, and the Firmware page. Purely\nadditive to the API/MCP surface; no install/auto-update capability added\n(Shelly.Update has no documented way to select alt firmware). Full\nchangelog in CHANGELOG.md.",
          "is_bot": false,
          "headline": "release: v0.5.4",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-01T18:57:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3adc8c9773a1822c9ca78eee66873582ccf30c75",
          "body": "…us (read-only)\n\nShelly firmware 2.0.0-beta3 adds an alt object (alternative firmware\nvariants, e.g. Zigbee/Matter builds of the same hardware) and a\nprovisioning object (secure-provisioning state) to Shelly.GetStatus's\nsys block. Both are derived from the already-cached RawStatus at\nGetDevices() ti\n[…]\nd> badge\non the Firmware page.\n\nRead-only by design: Shelly.Update has no stage:\"alt\" and the alt\nobject carries no url, so switching a device's firmware variant isn't\npossible via the documented API.",
          "is_bot": false,
          "headline": "feat(firmware): surface sys.alt firmware variants + provisioning stat…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-07-01T18:57:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "14925ffbb2631a2360fc94c59c569558a33ef8da",
          "body": "Bumps the npm-prod-dependencies group in /web with 1 update: [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte).\n\n\nUpdates `svelte` from 5.56.3 to 5.56.4\n- [Release notes](https://github.com/sveltejs/svelte/releases)\n- [Changelog](https://github.com/sveltejs/svelte/blob/main/pack\n[…]\ndate:semver-patch\n  dependency-group: npm-prod-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump svelte in /web in the npm-prod-dependencies group (#76)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-29T17:52:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "de84bdb9dbe9622b3038aa805950cf5be17637fe",
          "body": "Bumps the go-dependencies group with 1 update: [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).\n\n\nUpdates `modernc.org/sqlite` from 1.52.0 to 1.53.0\n- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)\n- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.52.0...v1.53.0)\n\n-\n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump modernc.org/sqlite in the go-dependencies group (#73)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-22T17:49:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e24c2152ffd1403231887f2403546d47c236cb14",
          "body": "Transitive dev-only dependency via jsdom (test tooling); 7.28.0 stays\nwithin jsdom's ^7.25.0 range, so no jsdom bump needed. Clears the high\n-severity undici advisory cluster (TLS bypass via SOCKS5, cache\nwhitespace bypass, Set-Cookie injection, WS DoS, etc.). Not shipped in\nthe embedded SPA bundle \n[…]\n runtime impact, no release\nrequired. `npm audit` now reports 0 vulnerabilities.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(web): bump undici 7.25.0→7.28.0 to clear npm audit advisory (#72)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-20T16:35:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9124ae85c039c085f3b8e4a1ec2049db67c153de",
          "body": "Bumps [undici](https://github.com/nodejs/undici) from 7.25.0 to 7.28.0.\n- [Release notes](https://github.com/nodejs/undici/releases)\n- [Commits](https://github.com/nodejs/undici/compare/v7.25.0...v7.28.0)\n\n---\nupdated-dependencies:\n- dependency-name: undici\n  dependency-version: 7.28.0\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps-dev): bump undici from 7.25.0 to 7.28.0 in /web (#71)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-20T13:29:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a92002acd0314a78263020b1167bb5f407dde19f",
          "body": "Bumps the go-dependencies group with 1 update: [golang.org/x/net](https://github.com/golang/net).\n\n\nUpdates `golang.org/x/net` from 0.55.0 to 0.56.0\n- [Commits](https://github.com/golang/net/compare/v0.55.0...v0.56.0)\n\n---\nupdated-dependencies:\n- dependency-name: golang.org/x/net\n  dependency-versio\n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump golang.org/x/net in the go-dependencies group (#69)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-15T17:51:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2759357a07f0f20ff603080d1c1c568968e49d77",
          "body": "services.GetSettings hands the tool the decrypted MCP token, so\nget_settings exposed it in plaintext over the MCP surface — the HTTP API\nGET handler has always masked it to services.MCPTokenRedacted (\"<set>\")\nbefore the SPA sees it. The comment above the tool even said AppSettings\ncarries no secret \n[…]\nact.go gains a redaction-inventory note so the next secret-bearing\ntool finds the pattern. Regression test asserts the placeholder comes\nback and the plaintext never appears in the structured content.",
          "is_bot": false,
          "headline": "fix(mcp): redact the MCP token in the get_settings tool",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T18:54:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d39b4ab8a9f9b59b8f73ad6328d78c01b4f466f1",
          "body": "…ardening summary\n\nThe German README's Status section had drifted: it named only the\nv0.4.0 UI/API baseline and never the current release, while the English\none carries both. Now mirrors README.md's v0.5.3 status.",
          "is_bot": false,
          "headline": "docs(readme.de): mirror the English status line — current release + h…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T18:32:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acb644c56f8d3e359d974456c233405d648beb47",
          "body": "DEPLOYMENT.md's env table still said 'losing or rotating it orphans\nevery stored credential' — rotation is supported as of v0.5.3, only\nloss (or an unrotated swap) orphans. Both READMEs (en/de) get the same\ncorrection plus a pointer to the rotate-key procedure in\ndocs/SECURITY.md.",
          "is_bot": false,
          "headline": "docs: point key-loss warnings at shellyctl rotate-key",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T18:21:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3bd5fbb26e88c3625f6231be8f701b6b53feaec",
          "body": "Hardening release — items 1–8 from the June 2026 architecture/security\nreview. Adds shellyctl rotate-key, template-section save-time validation,\nand the frontend coverage gate; hardens shellyclient (4 MiB response cap,\nJSON-RPC envelope validation); CI runs -race; internal/db split by domain;\nSECURITY.md refreshed (MCP token hygiene, encryption-at-rest rewrite, key\nrotation procedure). Full changelog in CHANGELOG.md.",
          "is_bot": false,
          "headline": "release: v0.5.3",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T18:12:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b52e3485c2522debc12c236e4f19970b6c83bf87",
          "body": "Review item 8, the last open item from the June 2026 architecture/\nsecurity review. Rotating SHELLYADMIN_ENCRYPTION_KEY used to require the\nmanual playbook documented in docs/SECURITY.md: export with secrets,\ndisable TOTP, clear the MCP token, delete every credential group while\nthe old key is still\n[…]\nleads\nwith the command; the manual playbook remains in git history as the\nfallback for older versions. CLAUDE.md notes the invariant: a new sealed\ncolumn anywhere must be added to RotateSealedColumns.",
          "is_bot": false,
          "headline": "feat(cli): shellyctl rotate-key — one-shot encryption-key rotation",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T18:12:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2b49aeec54645b7ed80deaa6b9fcadd24af05609",
          "body": "The Go side has had a 45% coverage floor since v0.3.0; the frontend\nunit tests ran without one (review item 7). vitest now runs with\n@vitest/coverage-v8 and a 30% statements/lines threshold\n(vitest.config.ts), measured 35.7%/37.1% at introduction — same\n~6-point regression-guard headroom as the Go g\n[…]\nets extracted into .ts\nmodules first (the navbar.ts / state.ts pattern).\n\nThe Frontend-build required check runs npm run test:coverage; the\ngenerated web/coverage/ output is git- and prettier-ignored.",
          "is_bot": false,
          "headline": "ci(web): add frontend unit-test coverage gate",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:49:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0325f4285c6c0a9d82afc91195a904b293ab29f9",
          "body": "db.go had grown to 1282 lines bundling connection lifecycle, schema\nmigration, and every query in the package — the single biggest\nchange-magnet in the backend (review item 6). It now keeps only\nOpen/Close, migrate, SnapshotTo, and the package-wide helpers\n(decryptCipher, now, boolToInt); the querie\n[…]\npersonal access token rows\n  runtimelock.go  single-instance lock rows\n\nPure move — no body changed, verified by the services.Store interface\ncompile assertion (108 methods) plus the full -race suite.",
          "is_bot": false,
          "headline": "refactor(db): split db.go into domain files",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:49:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ce8da5be2499e598517f5c876cf8a5cc2073d08b",
          "body": "Unknown top-level template keys used to fall through to the\n<Capitalized>.SetConfig catch-all and only fail at the device — a typo\nlike \"syss\" surfaced as a silent 'skipped' section on every device of\na fleet provision run. validation.Template now checks each key against\nthe canonical section list (\n[…]\nn unchanged; the gate is\nsave-time only (templates UI, API, backup import).\n\nThe credential_ref existence check flagged in the review already\nexists in templates.Service.Save — no change needed there.",
          "is_bot": false,
          "headline": "feat(provision): reject unknown template sections at save time",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:49:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "706e65be46d1947b0c33254d89bf9906eead1e16",
          "body": "Two gaps from the architecture/security review, plus stale content\nfixed in passing:\n\n- New 'MCP Listener Token Hygiene' section: the path-segment auth form\n  writes the token into anything that logs request paths (proxy access\n  logs, container stdout aggregation, browser/shell history). Prefer\n  t\n[…]\nhen re-imports.\n\n- Stale claims fixed: 'external API tokens' removed from the\n  intentionally-not-included list (PATs shipped in v0.3.0);\n  Authentication section now mentions TOTP 2FA and PAT scopes.",
          "is_bot": false,
          "headline": "docs(security): MCP token hygiene + key backup and rotation playbook",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:24:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "89aab879b6a4227bac4359afd884ae6b84295761",
          "body": "RPC() discarded unmarshal errors, so a 200 with a garbage body (captive\nportal, HTML error page from a misbehaving LAN endpoint) returned\n(nil, nil) — success with an empty result, indistinguishable from a\nlegitimate response. Success statuses now require a parseable envelope:\nempty bodies and inval\n[…]\nare 200 and no body,\nwhich no real Shelly does; it now returns a minimal valid envelope.\nA null result ({\"id\":1,\"result\":null}, Shelly.Reboot and friends)\nkeeps working — covered by a regression test.",
          "is_bot": false,
          "headline": "fix(shellyclient): validate JSON-RPC response envelopes",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:24:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5f684f262edf788e945b368447bf209afbd6da6c",
          "body": "AppService guards shared state with several mutexes (mu, authMu,\njobSpawnMu) plus a WaitGroup; lock-discipline regressions are\ninvisible to plain tests but trip the race detector. -covermode=atomic\nwas already in place, so -race slots in without changing the coverage\ngate. Full suite verified race-clean locally; internal/api runs\nnoticeably slower under -race (~164s) but well within job limits.",
          "is_bot": false,
          "headline": "ci(test): run the Go test suite with -race",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:24:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "47ce7bd88ed74fdf1cf9d3dd6d63c6242f167cd1",
          "body": "Probe() and RPC() read response bodies via io.ReadAll with no size\nlimit, so a single misbehaving or hostile LAN endpoint streaming a\nmulti-GB response could OOM the scan/refresh workers. Both paths now\ngo through readBodyLimited(), which reads at most 4 MiB and fails\nwith an explicit size error ins\n[…]\nnfusing JSON parse error downstream).\n\nReal Shelly payloads top out in the tens of KB, so 4 MiB is generous\nheadroom. Regression tests stream an oversized body against both the\n/shelly and /rpc paths.",
          "is_bot": false,
          "headline": "fix(shellyclient): cap device response bodies at 4 MiB",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-06-10T17:24:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "22cb59638c93359fb20767765a439992e620e972",
          "body": "…tes (#55)\n\nBumps the docker-dependencies group in /docker with 2 updates: node and golang.\n\n\nUpdates `node` from `e71ac5e` to `144769e`\n\nUpdates `golang` from `91eda97` to `f23e8b2`\n\n---\nupdated-dependencies:\n- dependency-name: node\n  dependency-version: 26-alpine\n  dependency-type: direct:producti\n[…]\n: direct:production\n  dependency-group: docker-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump the docker-dependencies group in /docker with 2 upda…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-09T07:50:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "48308d71c63fe3baadd35333318ef1930aca4afa",
          "body": "Bumps the npm-dev-dependencies group in /web with 1 update: [svelte-eslint-parser](https://github.com/sveltejs/svelte-eslint-parser).\n\n\nUpdates `svelte-eslint-parser` from 1.7.1 to 1.8.0\n- [Release notes](https://github.com/sveltejs/svelte-eslint-parser/releases)\n- [Changelog](https://github.com/sve\n[…]\npdate:semver-minor\n  dependency-group: npm-dev-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps-dev): bump svelte-eslint-parser (#61)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-08T17:48:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "95c280007c76884ab823db7262917cafe1e831c5",
          "body": "Bumps the npm-prod-dependencies group in /web with 1 update: [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte).\n\n\nUpdates `svelte` from 5.56.1 to 5.56.3\n- [Release notes](https://github.com/sveltejs/svelte/releases)\n- [Changelog](https://github.com/sveltejs/svelte/blob/main/pack\n[…]\ndate:semver-patch\n  dependency-group: npm-prod-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump svelte in /web in the npm-prod-dependencies group (#62)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-08T17:47:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "01848db8e5075edfae90546bc9b057e8b172c841",
          "body": "Bumps the go-dependencies group with 2 updates: [golang.org/x/crypto](https://github.com/golang/crypto) and [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).\n\n\nUpdates `golang.org/x/crypto` from 0.52.0 to 0.53.0\n- [Commits](https://github.com/golang/crypto/compare/v0.52.0...v0.53.0)\n\nUpdates `m\n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump the go-dependencies group with 2 updates (#60)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-08T17:47:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ad9bb26c74a4192e69cdf96c0e05b83e213b40b",
          "body": "Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.59.0 to 0.59.1.\n- [Release notes](https://github.com/quic-go/quic-go/releases)\n- [Commits](https://github.com/quic-go/quic-go/compare/v0.59.0...v0.59.1)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/quic-go/quic\n[…]\ngo\n  dependency-version: 0.59.1\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump github.com/quic-go/quic-go from 0.59.0 to 0.59.1 (#59)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-03T21:22:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db4baa43c432dc79803d70196f6da7e410907938",
          "body": "Bumps the npm-prod-dependencies group in /web with 1 update: [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte).\n\n\nUpdates `svelte` from 5.55.9 to 5.56.1\n- [Release notes](https://github.com/sveltejs/svelte/releases)\n- [Changelog](https://github.com/sveltejs/svelte/blob/main/pack\n[…]\ndate:semver-minor\n  dependency-group: npm-prod-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump svelte in /web in the npm-prod-dependencies group (#58)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-03T02:09:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "27ae0331f811dc8f0da08ee4d31de99224b319d6",
          "body": "Bumps the npm-dev-dependencies group in /web with 10 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.60.0` | `8.60.1` |\n| [@typescript-eslint/parser](https://githu\n[…]\npdate:semver-patch\n  dependency-group: npm-dev-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps-dev): bump the npm-dev-dependencies group (#57)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-03T02:09:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "28fa5e3f9adc7b76a78b94338670c7f06d9e5650",
          "body": "Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action).\n\n\nUpdates `actions/checkout` from 6.0.2 to 6.0.3\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Chan\n[…]\nsion-update:semver-minor\n  dependency-group: github-actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "ci(deps): bump the github-actions group with 2 updates (#56)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-03T02:08:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9ea5efdc713c56b132b2d6ee17fc0cb3d8624773",
          "body": "Bumps the go-dependencies group with 1 update: [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).\n\n\nUpdates `modernc.org/sqlite` from 1.50.1 to 1.51.0\n- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)\n- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.50.1...v1.51.0)\n\n-\n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump modernc.org/sqlite in the go-dependencies group (#54)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-03T02:07:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ac0524501401bee41d77aff3f1ab89c8fcd6ebf1",
          "body": "README Status line now states the current release (v0.5.2) while noting the\nUI/API baseline is unchanged since v0.4.0 (v0.5.x are launch/fix/refactor\nreleases). Roadmap \"Now\" bumped to v0.5.x and \"Recently shipped\" gains the\nv0.5.0–v0.5.2 entries.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "docs: refresh version baseline + roadmap for v0.5.2 (#53)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-29T10:48:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a6b322b031e5faf0ea97880ab47a10bd97e085d",
          "body": "….2 (#52)\n\nReplace the StartScan MCP-field-clearing special case with a focused\nvalidation.ScanParams that validates only scan parameters (subnets,\ntimeouts, concurrency) and returns the target count. This also removes\nthe duplicate CIDR expansion StartScan recomputed after the old\nValidateSettings \n[…]\nthe raw DB row no longer blocks a scan\n(validation_test.go + scan_test.go).\n\nBump VERSION / web package / CHANGELOG / SECURITY to 0.5.2.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "refactor(scan): extract ScanParams validator + regression tests; v0.5…",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-29T07:18:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1035b6afc837c6e55d13875572af7507f482ff89",
          "body": "…-dev-dependencies-0a68a61dc3\n\ndeps(deps-dev): bump the npm-dev-dependencies group in /web with 7 updates",
          "is_bot": false,
          "headline": "Merge pull request #50 from buliwyf42/dependabot/npm_and_yarn/web/npm…",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-26T04:31:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dbbf1709174bcb0cf9ea64fd2444bc1e34bcb980",
          "body": "Bumps the npm-prod-dependencies group in /web with 1 update: [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte).\n\n\nUpdates `svelte` from 5.55.8 to 5.55.9\n- [Release notes](https://github.com/sveltejs/svelte/releases)\n- [Changelog](https://github.com/sveltejs/svelte/blob/main/pack\n[…]\ndate:semver-patch\n  dependency-group: npm-prod-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump svelte in /web in the npm-prod-dependencies group (#51)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-25T23:42:54Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "24d0f9bbc5e1ce21b511b8e4319503a1f78bb52f",
          "body": "Bumps the go-dependencies group with 3 updates: [github.com/modelcontextprotocol/go-sdk](https://github.com/modelcontextprotocol/go-sdk), [golang.org/x/crypto](https://github.com/golang/crypto) and [golang.org/x/net](https://github.com/golang/net).\n\n\nUpdates `github.com/modelcontextprotocol/go-sdk` \n[…]\nion-update:semver-minor\n  dependency-group: go-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "deps(deps): bump the go-dependencies group with 3 updates (#48)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-25T23:42:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ec03e4910ed8ded37048111944c30e80402d8237",
          "body": "Bumps the github-actions group with 5 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.0.0` | `4.1.0` |\n| [docker/login-action](https://github.com/docker/login-action) | `4.1.0` | `4.2.0` |\n| [docker/metadata-act\n[…]\nsion-update:semver-patch\n  dependency-group: github-actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "ci(deps): bump the github-actions group with 5 updates (#49)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-25T23:41:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0fbac739edb6aff831ab185ffcb6f903c0796497",
          "body": "Bumps the npm-dev-dependencies group in /web with 7 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.59.4` | `8.60.0` |\n| [@typescript-eslint/parser](https://github\n[…]\nndency-version: 4.1.7\n  dependency-type: direct:development\n  update-type: version-update:semver-patch\n  dependency-group: npm-dev-dependencies\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>",
          "is_bot": true,
          "headline": "deps(deps-dev): bump the npm-dev-dependencies group",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-05-25T23:40:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8961fe2ad035c347b080e81704c0282e1f5acd00",
          "body": "StartScan reads the raw DB row whose MCPToken is secretbox-encrypted\nciphertext, not plaintext. ValidateSettings then failed the URL-safe\nalphabet check against the ciphertext, blocking every scan when MCP\nwas enabled. Strip MCPToken/MCPEnabled from the local copy before the\nformat check — the token was already validated at save time and is\nirrelevant to scan-parameter validation.\n\nBumps to v0.5.1.",
          "is_bot": false,
          "headline": "fix(scan): skip encrypted MCP token when validating settings before scan",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-24T19:09:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b142610a82327caae589fffb29dc0293d2db2de6",
          "body": "The session cookie key and server-side session row were written with\nthe operator-supplied req.Username rather than the verified canonical\nadminUser from adminCredential(). Not exploitable today (ConstantTimeCompare\nguarantees byte identity at that point), but using the resolved value is\nthe correct invariant and removes any future risk if username comparison\nis ever loosened.",
          "is_bot": false,
          "headline": "fix(auth): store canonical adminUser in session, not req.Username",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T18:39:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e5543a9ad77f1516aa7d87d6f86f3a2fcd5908bd",
          "body": "ChangeAdminCredential now reads the old username before overwriting\nadmin_credentials, then renames the totp_state row to the new key so\nactive 2FA enrollment is not silently dropped when the operator\nrenames their account. sql.ErrNoRows (TOTP not enrolled) is a no-op;\nany other DB error aborts the \n[…]\nation and the no-op path.\n\nvite.config.ts: replace ?? with a ternary for VITE_ALLOWED_HOSTS so\nan empty-string value falls back to ['localhost'] rather than the\nuseless [''] produced by ''.split(',').",
          "is_bot": false,
          "headline": "fix(auth): migrate TOTP row on username rename; guard vite allowedHosts",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T18:31:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "96e253f8d385fd431d02a39193b976e887380f76",
          "body": "bug_report.yml: expanded from 5 fields to 11, with project-specific\ncontext that actually helps triage —\n\n  - pre-flight checklist (searched issues, not a security report,\n    checked CHANGELOG) gates the form so duplicates and misdirected\n    security reports drop sharply\n  - explicit redaction rem\n[…]\n\nrepo: NOT a public template (which would expose the vulnerability\nin the act of filing it), but a config.yml deflection that catches\npeople at the 'New issue' chooser before they pick the wrong path.",
          "is_bot": false,
          "headline": "docs: deepen issue templates + add config.yml for security routing",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T09:20:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ed4b0abc7d4504a57dbc6dce4b6f366105fde44a",
          "body": "Adds a full German translation of the landing-page README alongside\nthe English one, with reciprocal language-switcher links at the top\nof each file ('English | **Deutsch**' and inversely).\n\nThe English README stays primary (default landing page, SEO, GitHub\nauto-detection). README.de.md mirrors its\n[…]\nands, and image URLs\nare preserved verbatim. Technical product terms (Docker, MCP, GHCR,\nSQLite, Compose, Vite, SemVer) stay in English as is conventional in\nGerman technical writing.\n\nPrettier-clean.",
          "is_bot": false,
          "headline": "docs: add German README (README.de.md) with language switcher",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T09:14:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f311e6ec53eb1ee957ddff7058282c8be4b95bca",
          "body": "When the repo flipped from private to public for v0.5.0, GitHub\nsilently reset default_workflow_permissions to 'read'. The\npublish-image workflow declares job-level contents: write, which\nshould override the default, but the gh release create step still\nreturned 401 Bad credentials at the end of an \n[…]\nin docs/DEVELOPMENT.md > CI Gates & Branch Protection,\nwith the one-line API fix and the manual-Release fallback. Saves the\nnext maintainer (or me, on a different repo) from the same debugging\ndetour.",
          "is_bot": false,
          "headline": "docs: note the post-public-flip workflow-permissions gotcha",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T09:11:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7f9b4a71f65a3c522eeff93f95b46f05579d492f",
          "body": "This release captures the going-public hygiene pass — no behavior\nchanges, every diff is docs, build, or test fixtures. See\nCHANGELOG.md [0.5.0] for the full surface.\n\nVERSION + web/package.json + lockfile bumped from 0.4.0 to 0.5.0\ntogether. Frontend rebundled so the embedded SPA shows v0.5.0 in\nthe navbar.",
          "is_bot": false,
          "headline": "release: v0.5.0 — first public release",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:52:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27fb33755dfac75c9613f917eb5e0746956a2e14",
          "body": "Devices view (the rich fleet inventory) becomes the hero shot directly\nunder the intro paragraph — single highest-impact 'this is real\nsoftware' signal for the public landing page. The other four (Scan,\nFirmware, Provision, Compliance) live in a collapsed <details> block\nbelow so they don't bloat th\n[…]\nfleet, so they show realistic\nscale without leaking infrastructure detail.\n\ndocs/screenshots/: new directory, 5 PNGs (~4.4 MB total).\nREADME.md: placeholder HTML comment replaced with the real images.",
          "is_bot": false,
          "headline": "docs: add product screenshots to the README",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:43:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9c2d538cfd86145fe50816e27e49c9809fa95beb",
          "body": "Now that the repo is public, the README is the front door. This pass\naddresses the gaps surfaced in review.\n\nAdded:\n- Five badges (CI status, MIT license, latest release, GHCR link,\n  Go Report Card) for credibility / quick-glance status\n- 'Why ShellyAdmin?' motivation paragraph explaining where the\n[…]\nks Today' section (duplicated Current Feature Set)\n- 'Not Production-Grade Yet' section (covered by Status > Intended\n  posture bullets)\n\nPrettier-clean.\n\nREADME: 300 -> 284 lines, content density up.",
          "is_bot": false,
          "headline": "docs: rewrite README for the public landing page",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:40:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b1225688d876621b38bb9389c72a11b3a308427c",
          "body": "Follow-up to commit 4d64f3d after a second pass surfaced six occurrences\nof mqtt.home.lan still in test fixtures and eleven historical references\nto /docker/shellyadmin, docker.home.lan, and 'Dockhand' in CHANGELOG.md.\n\nTest files: mqtt.home.lan -> mqtt.example.test (RFC 6761 reserved test\nTLD, obvi\n[…]\nainer manager' so the\nhistorical release notes stay accurate without leaking the maintainer's\nspecific tooling. Public readers no longer see references to a tool that\nappears nowhere else in the repo.",
          "is_bot": false,
          "headline": "chore: scrub residual personal hostnames and tool names",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:21:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dbf2570b5fba1bac0dc95143b9fd23c3702a4f10",
          "body": "…ENT.md\n\nCLAUDE.md is going public alongside the rest of the repo. Strip the\nthree ops-heavy sections that aren't code-adjacent and reattach them\nto docs/DEVELOPMENT.md, which is already the home for build/test/dev\ndocs.\n\nMoved:\n- Deployment Workflow (compose stack shape, release path, pre-deploy\n  \n[…]\nt branch\nprotection becomes free once the repo flips public; Pro is what made\nit enforceable while the repo was private.\n\nCLAUDE.md: 369 → 276 lines (~25% smaller)\ndocs/DEVELOPMENT.md: 183 → 273 lines",
          "is_bot": false,
          "headline": "docs: move deploy/release/CI sections from CLAUDE.md to docs/DEVELOPM…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:17:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7e769b459ed0cb51ed94ed5e70cc6fb1b9f967ca",
          "body": "The Dockerfile uses COPY . . in the backend stage, so without a\n.dockerignore a local 'docker build' from this repo ships the\nmaintainer's working-tree state (data/ live SQLite + encryption key\nfile, .devlogs/, .claude/, bin/, secrets/, web/node_modules, etc.)\ninto the build context. Published GHCR \n[…]\nrkdown (docs/, *.md, LICENSE, CHANGELOG)\n- test/coverage artifacts\n\nThe cmd/shellyctl/dist exclusion is safe because the Dockerfile\nalready overwrites it via COPY --from=frontend before go build runs.",
          "is_bot": false,
          "headline": "build: add .dockerignore to scope local rebuilds away from live state",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:14:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7334ade725234006a2f1f44883fba0e98c832164",
          "body": "…erated\n\ndocs/plans/README.md: move Phase-4b, Phase-4c, and v0.3.0 from Active to\nShipped (all landed in v0.3.x), remove pointer to the maintainer's local\nplan file, and reframe the folder as historical/archival reference.\n\n.gitattributes: mark cmd/shellyctl/dist/** as linguist-generated and\nsuppres\n[…]\niffs for it so the embedded SPA bundle (produced by the web\nbuild, checked in for //go:embed) doesn't dominate diffs or language\nstats on GitHub. Also pin LF endings for shell scripts and Dockerfiles.",
          "is_bot": false,
          "headline": "docs: archive shipped release plans + mark embedded SPA bundle as gen…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:04:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8715a456f6de919d5070c8fe2e8abee0be1dbf6a",
          "body": "Adds a short CODE_OF_CONDUCT.md pointing to the canonical Contributor\nCovenant v2.1 text, with a reporting channel (GitHub private security\nadvisory) and scope/enforcement notes. Closes the last gap in GitHub's\ncommunity profile checklist before flipping the repo public.",
          "is_bot": false,
          "headline": "docs: add Code of Conduct (Contributor Covenant v2.1)",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:03:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d64f3d0ee8aa55dc16f2dbc7d22d065e6389d05",
          "body": "Scrub personal/homelab specifics (docker.home.lan, devhost.home.lan,\n/docker/shellyadmin, mqtt.home.lan, \"buliwyf_iot\") and Dockhand-specific\nreferences from public-facing files. Replace with generic placeholders\n(`<data-dir>`, \"container manager\", env-driven config) so the repo\ndocumentation and sh\n[…]\nd v0.1.19) removed; docker/docker-compose.yml is the canonical example\n- web/vite.config.ts: allowedHosts now driven by VITE_ALLOWED_HOSTS env (defaults to localhost)\n- Rebundle of embedded SPA assets",
          "is_bot": false,
          "headline": "chore: generalize internal hostnames and paths for public release",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-23T08:00:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9342aa5731d2d8f55e6228818df156c134cc08ce",
          "body": "Sweep the remaining docs for the stale \"login is env-required, missing\nSHELLYADMIN_PASS_HASH panics at startup\" model:\n- SECURITY.md + docs/SECURITY.md: rewrite the admin-credential section for\n  first-run setup (DB-backed login, optional env import seed, reset-auth\n  recovery); fix the now-false pr\n[…]\nted, CLI writes optional);\n  add v0.4.0/v0.3.6/v0.3.5 to recently-shipped.\n- docs/adr/README.md: list ADR-0017.\n\nHistorical records (CHANGELOG, older ADRs, version-history rows) left as\npoint-in-time.",
          "is_bot": false,
          "headline": "docs: bring security/roadmap docs current with v0.4.0 first-run setup",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T18:45:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e6deb605f30d8da95eb8d2f41b0b6b8386842766",
          "body": "Record the same drop/skip reasoning applied to T2/T7:\n- T4 HSM/PKCS11 key provider — dropped (no value without HSM hardware; the\n  at-rest-key threat is already closed by S6/ADR-0013).\n- T9 external pen test — skip unless internet-exposed (self-run ZAP/nuclei is\n  the cheap substitute).\n- T12 standalone-binary signing — skip until binaries are distributed; the\n  Docker image is already cosign-signed in CI.\n\nLeaves the shellyctl write commands as the only live, genuinely-useful\nbacklog item.",
          "is_bot": false,
          "headline": "docs: triage T4/T9/T12 against the single-user/LAN/Docker reality",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T18:17:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f26043d22e48071048bf7095ce4f6cc338ca308e",
          "body": "Decided to defer the API version-prefix shim to the v1.0 cut rather than\nbuild it pre-1.0: it's pure plumbing with no payoff until a breaking\n/api/v2 exists, and a single-operator tool absorbs breaking changes by\nupdating the SPA + own scripts in lockstep. Record the rationale and the\nsizing (54 routes + ~51 client refs) next to the policy.",
          "is_bot": false,
          "headline": "docs: mark T7 (/api/v1 prefix) as explicitly v1.0-gated",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T18:02:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26ae1d6f20a39e0e878cb3a8e49726a0cd35f11c",
          "body": "WebAuthn needs a secure context (HTTPS); prod is trusted-LAN plain HTTP, so\npasskeys can't run without a TLS-proxy rebuild. For a single-operator internal\ntool the phishing-resistance payoff doesn't justify that — password (DB-backed\nsince v0.4.0) + TOTP + PATs already cover the threat model. Marked won't-do;\nrevisit only if the tool goes multi-user or internet-exposed.",
          "is_bot": false,
          "headline": "docs: drop T2 WebAuthn/passkeys from the roadmap",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T17:16:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e68c8d297c42043ecef2d7e0425805db21a6a54e",
          "body": "Bump VERSION, web/package.json, lockfile, and CHANGELOG for the v0.4.0\nfirst-run-setup release (operator login moves from env into the database;\nSHELLYADMIN_PASS_HASH is now an optional one-time import seed).",
          "is_bot": false,
          "headline": "release: v0.4.0 — first-run setup",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T16:16:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c44e8716c7cfa249f446677b40122542e5767ba",
          "body": "The operator login is no longer required via env (ADR-0017). Update the\nREADME quick-start, DEPLOYMENT env table, and both compose files to present\nSHELLYADMIN_PASS_HASH as an optional one-time import seed, point operators at\nthe first-run setup screen, and mention shellyctl reset-auth for recovery.\nThe root compose no longer hard-fails when the hash is unset.",
          "is_bot": false,
          "headline": "docs: reflect optional SHELLYADMIN_PASS_HASH + first-run setup",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T15:41:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2ccb0b4de6e6f950e32533151dc0f8ab09059ff2",
          "body": "Move the operator login (username + argon2id hash) out of the\nSHELLYADMIN_PASS_HASH / SHELLYADMIN_USER env vars and into a dedicated\nadmin_credentials table (migration 031), so a fresh instance boots into a\nsetup screen instead of panicking on a missing hash. Existing deployments\nupgrade seamlessly:\n[…]\n clears the credential for forgotten-password\n  recovery, mirroring shellyctl unlock.\n- SPA: first-run setup page + Settings account card, gated on setup status.\n\nSee docs/adr/0017-first-run-setup.md.",
          "is_bot": false,
          "headline": "feat(auth): first-run setup — operator login in the DB",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T15:33:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6b99310f10a5054ab5e518294b3213be830d0929",
          "body": "Extends the shellyctl CLI (ADR-0016) with two more read-only commands over\nthe existing /api surface:\n- `firmware`  -> GET /api/firmware/status: check state + per-device table\n  (current/stable/beta versions, which channel has an update, status/note).\n- `templates` -> GET /api/templates: provisionin\n[…]\n adding server surface.\n\nUnit tests for updateFlag + firmware-status decode; live-verified against a\nrunning instance with an admin PAT.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(cli): add read-only firmware + templates commands (#47)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T14:51:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d5c2554bdee3854fe136bdcff5361b5bb2cf65b2",
          "body": "…y (#46)\n\nThe encryption key became mandatory in v0.3.0 (S6/ADR-0013 — the binary\nrefuses to start without it), but the deploy docs and the shipped compose\nfile still described it as optional/auto-generated. As a result the\nquick-start `docker run` examples and `docker compose up` would panic at\nsta\n[…]\nthat wrote random bytes (not an argon2id hash) as the password\n  and claimed plaintext SHELLYADMIN_PASS still works (removed in v0.2.0).\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "docs: make deploy artifacts reflect the v0.3.0 required encryption ke…",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T14:47:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1112d4f389efed4135e8cc58f8aa5f47d6a55991",
          "body": null,
          "is_bot": false,
          "headline": "Release v0.3.6 — shellyctl CLI, E2E + unit tests, deploy/test tooling",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T12:14:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "981b075eda3d479142f7f7f66743008bdd531beb",
          "body": "Several docs linked with an absolute filesystem path\n(/Users/.../shellyadmin/...) that only resolved on one machine and leaked\na local home directory into the repo. Switch them to repo-relative links\nso they work for every reader and on GitHub.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "docs: use relative markdown links instead of absolute local paths (#45)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T11:08:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7bf91b2f2e81e1d44c51a5d4178aeace91482511",
          "body": "Stand up Playwright E2E (chromium) covering the flows verified by hand\nduring the responsive/a11y pass: login → shell, desktop horizontal nav\n(no hamburger), mobile hamburger drawer (open + link-click-closes), and\nthe single-leading-v version badge.\n\nAdds a non-required `E2E (Playwright)` CI job tha\n[…]\ncs against it. Kept off the required-checks list so an occasional E2E\nflake never blocks a merge while still surfacing real regressions.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "test(e2e): Playwright smoke tests for login + responsive nav (T8) (#44)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T11:04:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fe107299f8e1f66cf0518ace3e4900efe56e6765",
          "body": "Adds an operator CLI that queries a running instance over /api with a\nPersonal Access Token: `devices` (list), `device <mac|ip|name>` (detail),\n`logs` (audit tail). Human tables by default, --json for raw payloads;\n--url/--token (or SHELLYADMIN_URL/SHELLYADMIN_TOKEN). main.go routes a\nmatching verb \n[…]\ngainst a live\ninstance (login → mint PAT → devices/logs/auth-failure) plus unit tests\nfor the transport, decode, and arg/format helpers.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "feat(cli): read-only shellyctl CLI (HTTP + PAT) — ADR-0016 (#43)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T10:56:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ef3214541bc9e9b853e7053572842cadc10ee904",
          "body": "Mirror the SortHeader pattern: pull the navbar's pure logic out of the\n.svelte component into navbar.ts so it can be unit-tested without\nrendering. Covers the version-badge leading-v strip (the vv0.3.x fix) and\nthe active-link detection (incl. Devices \"/\" owning /devices/:id routes).\nAdds navbar.test.ts (9 cases); Navbar.svelte now delegates to the module.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "test(web): extract navbar logic to a unit-tested module (#42)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T10:46:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4cf55ec8776ee36b2953ae51f43fd847190d8e0f",
          "body": "Dockhand's exec_container can't write a snapshot file into the\nread-only-rootfs container, so the pre-deploy SQLite snapshot must run on\nthe host. Add scripts/snapshot-prod-db.sh (SSH-based, timestamped copy +\nrecent-snapshot listing) and document the pre-deploy step in\ndocs/DEPLOYMENT.md.\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "chore: add host-side pre-deploy DB snapshot script + docs (#41)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T10:42:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b3b7a44a19085785b84045f1f446a407c7ed4f1",
          "body": "…e-build gate",
          "is_bot": false,
          "headline": "Release v0.3.5 — Responsive nav + a11y, table-overflow fixes, CI imag…",
          "author_name": "buliwyf42",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T09:58:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d6e742e1d8cb90de0cccb36606ee08906fc7612f",
          "body": "Small badge labels (0.67rem bold) with white text on the old --danger\n(#e04b5b, 3.94:1) and --success (#27b36a, 2.71:1) fell below the 4.5:1\nAA threshold for small text. Both tokens are only consumed by the\n.bg-danger/.bg-success badge backgrounds, so darkening them is contained:\n--danger -> #c93544 (5.15:1), --success -> #18804a (4.97:1).\n\nCo-authored-by: buliwyf42 <buliwyf42@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix(web): darken --danger/--success so badge text meets WCAG AA (#40)",
          "author_name": "Dominik Sennfelder",
          "author_login": "buliwyf42",
          "committed_at": "2026-05-20T09:54:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 70,
      "commits_last_year": 325,
      "latest_release_at": "2026-07-23T06:21:10Z",
      "latest_release_tag": "v0.6.3",
      "releases_from_tags": false,
      "days_since_last_push": 1,
      "active_weeks_last_year": 16,
      "days_since_latest_release": 1,
      "mean_days_between_releases": 6.6
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 100,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 0,
      "stars": 3,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 3
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": true,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "web/tsconfig.json"
      ],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 52308,
      "source_files_sampled": 209,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 43430
    },
    "dependencies": {
      "manifests": [
        "go.mod",
        "web/package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [
          {
            "name": "brace-expansion",
            "direct": false,
            "version": "5.0.6",
            "severity": "high",
            "ecosystem": "npm",
            "cvss_score": 7.5,
            "advisory_ids": [
              "GHSA-3jxr-9vmj-r5cp"
            ],
            "fixed_version": "5.0.7",
            "advisory_count": 1,
            "oldest_advisory_days": 3
          },
          {
            "name": "golang.org/x/crypto",
            "direct": true,
            "version": "v0.54.0",
            "severity": "unknown",
            "ecosystem": "go",
            "cvss_score": null,
            "advisory_ids": [
              "GO-2026-5932"
            ],
            "fixed_version": null,
            "advisory_count": 1,
            "oldest_advisory_days": 16
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "high": 1,
          "unknown": 1
        },
        "advisory_count": 2,
        "affected_count": 2,
        "assessed_count": 334,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 1
      },
      "ecosystems": [
        "go",
        "npm"
      ],
      "dependencies": [
        {
          "name": "github.com/gin-contrib/sessions",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.1.0"
        },
        {
          "name": "github.com/gin-gonic/gin",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.12.0"
        },
        {
          "name": "github.com/modelcontextprotocol/go-sdk",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.6.1"
        },
        {
          "name": "golang.org/x/crypto",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.54.0"
        },
        {
          "name": "golang.org/x/mod",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.38.0"
        },
        {
          "name": "golang.org/x/net",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.57.0"
        },
        {
          "name": "gopkg.in/natefinch/lumberjack.v2",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.2.1"
        },
        {
          "name": "modernc.org/sqlite",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.54.0"
        },
        {
          "name": "qrcode",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.5.4"
        },
        {
          "name": "svelte",
          "manifest": "web/package.json",
          "ecosystem": "npm",
          "version_constraint": "^5.56.6"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "github.com/gin-contrib/sessions",
            "direct": true,
            "version": "v1.1.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gin-gonic/gin",
            "direct": true,
            "version": "v1.12.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/modelcontextprotocol/go-sdk",
            "direct": true,
            "version": "v1.6.1",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/crypto",
            "direct": true,
            "version": "v0.54.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/mod",
            "direct": true,
            "version": "v0.38.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/net",
            "direct": true,
            "version": "v0.57.0",
            "ecosystem": "go"
          },
          {
            "name": "gopkg.in/natefinch/lumberjack.v2",
            "direct": true,
            "version": "v2.2.1",
            "ecosystem": "go"
          },
          {
            "name": "modernc.org/sqlite",
            "direct": true,
            "version": "v1.54.0",
            "ecosystem": "go"
          },
          {
            "name": "qrcode",
            "direct": true,
            "version": "1.5.4",
            "ecosystem": "npm"
          },
          {
            "name": "svelte",
            "direct": true,
            "version": "5.56.6",
            "ecosystem": "npm"
          },
          {
            "name": "github.com/bytedance/gopkg",
            "direct": false,
            "version": "v0.1.3",
            "ecosystem": "go"
          },
          {
            "name": "github.com/bytedance/sonic",
            "direct": false,
            "version": "v1.15.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/bytedance/sonic/loader",
            "direct": false,
            "version": "v0.5.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/cloudwego/base64x",
            "direct": false,
            "version": "v0.1.6",
            "ecosystem": "go"
          },
          {
            "name": "github.com/dustin/go-humanize",
            "direct": false,
            "version": "v1.0.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gabriel-vasile/mimetype",
            "direct": false,
            "version": "v1.4.12",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gin-contrib/sse",
            "direct": false,
            "version": "v1.1.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/go-playground/locales",
            "direct": false,
            "version": "v0.14.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/go-playground/universal-translator",
            "direct": false,
            "version": "v0.18.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/go-playground/validator/v10",
            "direct": false,
            "version": "v10.30.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/goccy/go-json",
            "direct": false,
            "version": "v0.10.5",
            "ecosystem": "go"
          },
          {
            "name": "github.com/goccy/go-yaml",
            "direct": false,
            "version": "v1.19.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/google/jsonschema-go",
            "direct": false,
            "version": "v0.4.3",
            "ecosystem": "go"
          },
          {
            "name": "github.com/google/uuid",
            "direct": false,
            "version": "v1.6.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gorilla/context",
            "direct": false,
            "version": "v1.1.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gorilla/securecookie",
            "direct": false,
            "version": "v1.1.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gorilla/sessions",
            "direct": false,
            "version": "v1.4.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/json-iterator/go",
            "direct": false,
            "version": "v1.1.12",
            "ecosystem": "go"
          },
          {
            "name": "github.com/klauspost/cpuid/v2",
            "direct": false,
            "version": "v2.3.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/leodido/go-urn",
            "direct": false,
            "version": "v1.4.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/mattn/go-isatty",
            "direct": false,
            "version": "v0.0.20",
            "ecosystem": "go"
          },
          {
            "name": "github.com/modern-go/concurrent",
            "direct": false,
            "version": "v0.0.0-20180306012644-bacd9c7ef1dd",
            "ecosystem": "go"
          },
          {
            "name": "github.com/modern-go/reflect2",
            "direct": false,
            "version": "v1.0.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/ncruces/go-strftime",
            "direct": false,
            "version": "v1.0.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/pelletier/go-toml/v2",
            "direct": false,
            "version": "v2.2.4",
            "ecosystem": "go"
          },
          {
            "name": "github.com/quic-go/qpack",
            "direct": false,
            "version": "v0.6.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/quic-go/quic-go",
            "direct": false,
            "version": "v0.59.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/remyoudompheng/bigfft",
            "direct": false,
            "version": "v0.0.0-20230129092748-24d4a6f8daec",
            "ecosystem": "go"
          },
          {
            "name": "github.com/segmentio/asm",
            "direct": false,
            "version": "v1.1.3",
            "ecosystem": "go"
          },
          {
            "name": "github.com/segmentio/encoding",
            "direct": false,
            "version": "v0.5.4",
            "ecosystem": "go"
          },
          {
            "name": "github.com/twitchyliquid64/golang-asm",
            "direct": false,
            "version": "v0.15.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/ugorji/go/codec",
            "direct": false,
            "version": "v1.3.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/yosida95/uritemplate/v3",
            "direct": false,
            "version": "v3.0.2",
            "ecosystem": "go"
          },
          {
            "name": "go.mongodb.org/mongo-driver/v2",
            "direct": false,
            "version": "v2.5.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/arch",
            "direct": false,
            "version": "v0.22.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/oauth2",
            "direct": false,
            "version": "v0.35.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/sys",
            "direct": false,
            "version": "v0.47.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/text",
            "direct": false,
            "version": "v0.40.0",
            "ecosystem": "go"
          },
          {
            "name": "google.golang.org/protobuf",
            "direct": false,
            "version": "v1.36.10",
            "ecosystem": "go"
          },
          {
            "name": "modernc.org/libc",
            "direct": false,
            "version": "v1.74.1",
            "ecosystem": "go"
          },
          {
            "name": "modernc.org/mathutil",
            "direct": false,
            "version": "v1.7.1",
            "ecosystem": "go"
          },
          {
            "name": "modernc.org/memory",
            "direct": false,
            "version": "v1.11.0",
            "ecosystem": "go"
          },
          {
            "name": "@asamuzakjp/css-color",
            "direct": false,
            "version": "5.1.11",
            "ecosystem": "npm"
          },
          {
            "name": "@asamuzakjp/dom-selector",
            "direct": false,
            "version": "7.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "@asamuzakjp/generational-cache",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "@asamuzakjp/nwsapi",
            "direct": false,
            "version": "2.3.9",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/helper-string-parser",
            "direct": false,
            "version": "7.29.7",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/helper-validator-identifier",
            "direct": false,
            "version": "7.29.7",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/parser",
            "direct": false,
            "version": "7.29.7",
            "ecosystem": "npm"
          },
          {
            "name": "@babel/types",
            "direct": false,
            "version": "7.29.7",
            "ecosystem": "npm"
          },
          {
            "name": "@bcoe/v8-coverage",
            "direct": false,
            "version": "1.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@bramus/specificity",
            "direct": false,
            "version": "2.4.2",
            "ecosystem": "npm"
          },
          {
            "name": "@csstools/color-helpers",
            "direct": false,
            "version": "6.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@csstools/css-calc",
            "direct": false,
            "version": "3.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "@csstools/css-color-parser",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "@csstools/css-parser-algorithms",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@csstools/css-syntax-patches-for-csstree",
            "direct": false,
            "version": "1.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "@csstools/css-tokenizer",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "@emnapi/core",
            "direct": false,
            "version": "1.11.1",
            "ecosystem": "npm"
          },
          {
            "name": "@emnapi/runtime",
            "direct": false,
            "version": "1.11.1",
            "ecosystem": "npm"
          },
          {
            "name": "@emnapi/wasi-threads",
            "direct": false,
            "version": "1.2.2",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint-community/eslint-utils",
            "direct": false,
            "version": "4.9.1",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint-community/regexpp",
            "direct": false,
            "version": "4.12.2",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint/config-array",
            "direct": false,
            "version": "0.23.5",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint/config-helpers",
            "direct": false,
            "version": "0.6.0",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint/core",
            "direct": false,
            "version": "1.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint/js",
            "direct": false,
            "version": "10.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint/object-schema",
            "direct": false,
            "version": "3.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "@eslint/plugin-kit",
            "direct": false,
            "version": "0.7.2",
            "ecosystem": "npm"
          },
          {
            "name": "@exodus/bytes",
            "direct": false,
            "version": "1.15.0",
            "ecosystem": "npm"
          },
          {
            "name": "@humanfs/core",
            "direct": false,
            "version": "0.19.2",
            "ecosystem": "npm"
          },
          {
            "name": "@humanfs/node",
            "direct": false,
            "version": "0.16.8",
            "ecosystem": "npm"
          },
          {
            "name": "@humanfs/types",
            "direct": false,
            "version": "0.15.0",
            "ecosystem": "npm"
          },
          {
            "name": "@humanwhocodes/module-importer",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "@humanwhocodes/retry",
            "direct": false,
            "version": "0.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "@jridgewell/gen-mapping",
            "direct": false,
            "version": "0.3.13",
            "ecosystem": "npm"
          },
          {
            "name": "@jridgewell/remapping",
            "direct": false,
            "version": "2.3.5",
            "ecosystem": "npm"
          },
          {
            "name": "@jridgewell/resolve-uri",
            "direct": false,
            "version": "3.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "@jridgewell/sourcemap-codec",
            "direct": false,
            "version": "1.5.5",
            "ecosystem": "npm"
          },
          {
            "name": "@jridgewell/trace-mapping",
            "direct": false,
            "version": "0.3.31",
            "ecosystem": "npm"
          },
          {
            "name": "@napi-rs/wasm-runtime",
            "direct": false,
            "version": "1.1.6",
            "ecosystem": "npm"
          },
          {
            "name": "@oxc-project/types",
            "direct": false,
            "version": "0.138.0",
            "ecosystem": "npm"
          },
          {
            "name": "@playwright/test",
            "direct": false,
            "version": "1.61.1",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-android-arm64",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-darwin-arm64",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-darwin-x64",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-freebsd-x64",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-arm-gnueabihf",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-arm64-gnu",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-arm64-musl",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-ppc64-gnu",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-s390x-gnu",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-x64-gnu",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-linux-x64-musl",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-openharmony-arm64",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-wasm32-wasi",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-win32-arm64-msvc",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/binding-win32-x64-msvc",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "@rolldown/pluginutils",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "@standard-schema/spec",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "@sveltejs/acorn-typescript",
            "direct": false,
            "version": "1.0.10",
            "ecosystem": "npm"
          },
          {
            "name": "@sveltejs/vite-plugin-svelte",
            "direct": false,
            "version": "7.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "@tybys/wasm-util",
            "direct": false,
            "version": "0.10.3",
            "ecosystem": "npm"
          },
          {
            "name": "@types/chai",
            "direct": false,
            "version": "5.2.3",
            "ecosystem": "npm"
          },
          {
            "name": "@types/deep-eql",
            "direct": false,
            "version": "4.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "@types/esrecurse",
            "direct": false,
            "version": "4.3.1",
            "ecosystem": "npm"
          },
          {
            "name": "@types/estree",
            "direct": false,
            "version": "1.0.9",
            "ecosystem": "npm"
          },
          {
            "name": "@types/json-schema",
            "direct": false,
            "version": "7.0.15",
            "ecosystem": "npm"
          },
          {
            "name": "@types/node",
            "direct": false,
            "version": "25.7.0",
            "ecosystem": "npm"
          },
          {
            "name": "@types/qrcode",
            "direct": false,
            "version": "1.5.6",
            "ecosystem": "npm"
          },
          {
            "name": "@types/trusted-types",
            "direct": false,
            "version": "2.0.7",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/eslint-plugin",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/parser",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/project-service",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/scope-manager",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/tsconfig-utils",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/type-utils",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/types",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/typescript-estree",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/utils",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@typescript-eslint/visitor-keys",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/coverage-v8",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/expect",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/mocker",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/pretty-format",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/runner",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/snapshot",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/spy",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "@vitest/utils",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "acorn",
            "direct": false,
            "version": "8.16.0",
            "ecosystem": "npm"
          },
          {
            "name": "acorn-jsx",
            "direct": false,
            "version": "5.3.2",
            "ecosystem": "npm"
          },
          {
            "name": "ajv",
            "direct": false,
            "version": "6.15.0",
            "ecosystem": "npm"
          },
          {
            "name": "ansi-regex",
            "direct": false,
            "version": "5.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "ansi-styles",
            "direct": false,
            "version": "4.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "aria-query",
            "direct": false,
            "version": "5.3.1",
            "ecosystem": "npm"
          },
          {
            "name": "assertion-error",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "ast-v8-to-istanbul",
            "direct": false,
            "version": "1.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "axobject-query",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "balanced-match",
            "direct": false,
            "version": "4.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "bidi-js",
            "direct": false,
            "version": "1.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "brace-expansion",
            "direct": false,
            "version": "5.0.6",
            "ecosystem": "npm"
          },
          {
            "name": "camelcase",
            "direct": false,
            "version": "5.3.1",
            "ecosystem": "npm"
          },
          {
            "name": "chai",
            "direct": false,
            "version": "6.2.2",
            "ecosystem": "npm"
          },
          {
            "name": "cliui",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "clsx",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "color-convert",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "color-name",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "convert-source-map",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "cross-spawn",
            "direct": false,
            "version": "7.0.6",
            "ecosystem": "npm"
          },
          {
            "name": "css-tree",
            "direct": false,
            "version": "3.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "cssesc",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "data-urls",
            "direct": false,
            "version": "7.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "debug",
            "direct": false,
            "version": "4.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "decamelize",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "decimal.js",
            "direct": false,
            "version": "10.6.0",
            "ecosystem": "npm"
          },
          {
            "name": "deep-is",
            "direct": false,
            "version": "0.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "deepmerge",
            "direct": false,
            "version": "4.3.1",
            "ecosystem": "npm"
          },
          {
            "name": "detect-libc",
            "direct": false,
            "version": "2.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "devalue",
            "direct": false,
            "version": "5.8.1",
            "ecosystem": "npm"
          },
          {
            "name": "dijkstrajs",
            "direct": false,
            "version": "1.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "emoji-regex",
            "direct": false,
            "version": "8.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "entities",
            "direct": false,
            "version": "8.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "es-module-lexer",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "escape-string-regexp",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "eslint",
            "direct": false,
            "version": "10.6.0",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-config-prettier",
            "direct": false,
            "version": "10.1.8",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-plugin-svelte",
            "direct": false,
            "version": "3.20.0",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-scope",
            "direct": false,
            "version": "8.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-scope",
            "direct": false,
            "version": "9.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-visitor-keys",
            "direct": false,
            "version": "3.4.3",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-visitor-keys",
            "direct": false,
            "version": "4.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "eslint-visitor-keys",
            "direct": false,
            "version": "5.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "esm-env",
            "direct": false,
            "version": "1.2.2",
            "ecosystem": "npm"
          },
          {
            "name": "espree",
            "direct": false,
            "version": "10.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "espree",
            "direct": false,
            "version": "11.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "esquery",
            "direct": false,
            "version": "1.7.0",
            "ecosystem": "npm"
          },
          {
            "name": "esrap",
            "direct": false,
            "version": "2.2.13",
            "ecosystem": "npm"
          },
          {
            "name": "esrecurse",
            "direct": false,
            "version": "4.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "estraverse",
            "direct": false,
            "version": "5.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "estree-walker",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "esutils",
            "direct": false,
            "version": "2.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "expect-type",
            "direct": false,
            "version": "1.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "fast-deep-equal",
            "direct": false,
            "version": "3.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "fast-json-stable-stringify",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "fast-levenshtein",
            "direct": false,
            "version": "2.0.6",
            "ecosystem": "npm"
          },
          {
            "name": "fdir",
            "direct": false,
            "version": "6.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "file-entry-cache",
            "direct": false,
            "version": "8.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "find-up",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "find-up",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "flat-cache",
            "direct": false,
            "version": "4.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "flatted",
            "direct": false,
            "version": "3.4.2",
            "ecosystem": "npm"
          },
          {
            "name": "fsevents",
            "direct": false,
            "version": "2.3.2",
            "ecosystem": "npm"
          },
          {
            "name": "fsevents",
            "direct": false,
            "version": "2.3.3",
            "ecosystem": "npm"
          },
          {
            "name": "get-caller-file",
            "direct": false,
            "version": "2.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "glob-parent",
            "direct": false,
            "version": "6.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "globals",
            "direct": false,
            "version": "16.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "has-flag",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "html-encoding-sniffer",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "html-escaper",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "ignore",
            "direct": false,
            "version": "5.3.2",
            "ecosystem": "npm"
          },
          {
            "name": "ignore",
            "direct": false,
            "version": "7.0.5",
            "ecosystem": "npm"
          },
          {
            "name": "imurmurhash",
            "direct": false,
            "version": "0.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "is-extglob",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "is-fullwidth-code-point",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "is-glob",
            "direct": false,
            "version": "4.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "is-potential-custom-element-name",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "is-reference",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "isexe",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "istanbul-lib-coverage",
            "direct": false,
            "version": "3.2.2",
            "ecosystem": "npm"
          },
          {
            "name": "istanbul-lib-report",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "istanbul-reports",
            "direct": false,
            "version": "3.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "js-tokens",
            "direct": false,
            "version": "10.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "jsdom",
            "direct": false,
            "version": "29.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "json-buffer",
            "direct": false,
            "version": "3.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "json-schema-traverse",
            "direct": false,
            "version": "0.4.1",
            "ecosystem": "npm"
          },
          {
            "name": "json-stable-stringify-without-jsonify",
            "direct": false,
            "version": "1.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "keyv",
            "direct": false,
            "version": "4.5.4",
            "ecosystem": "npm"
          },
          {
            "name": "known-css-properties",
            "direct": false,
            "version": "0.37.0",
            "ecosystem": "npm"
          },
          {
            "name": "levn",
            "direct": false,
            "version": "0.4.1",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-android-arm64",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-darwin-arm64",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-darwin-x64",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-freebsd-x64",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-linux-arm-gnueabihf",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-linux-arm64-gnu",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-linux-arm64-musl",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-linux-x64-gnu",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-linux-x64-musl",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-win32-arm64-msvc",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lightningcss-win32-x64-msvc",
            "direct": false,
            "version": "1.32.0",
            "ecosystem": "npm"
          },
          {
            "name": "lilconfig",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "locate-character",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "locate-path",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "locate-path",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "lru-cache",
            "direct": false,
            "version": "11.3.6",
            "ecosystem": "npm"
          },
          {
            "name": "magic-string",
            "direct": false,
            "version": "0.30.21",
            "ecosystem": "npm"
          },
          {
            "name": "magicast",
            "direct": false,
            "version": "0.5.3",
            "ecosystem": "npm"
          },
          {
            "name": "make-dir",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "mdn-data",
            "direct": false,
            "version": "2.27.1",
            "ecosystem": "npm"
          },
          {
            "name": "minimatch",
            "direct": false,
            "version": "10.2.5",
            "ecosystem": "npm"
          },
          {
            "name": "ms",
            "direct": false,
            "version": "2.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "nanoid",
            "direct": false,
            "version": "3.3.12",
            "ecosystem": "npm"
          },
          {
            "name": "natural-compare",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "obug",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "optionator",
            "direct": false,
            "version": "0.9.4",
            "ecosystem": "npm"
          },
          {
            "name": "p-limit",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "p-limit",
            "direct": false,
            "version": "3.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "p-locate",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "p-locate",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "p-try",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "parse5",
            "direct": false,
            "version": "8.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "path-exists",
            "direct": false,
            "version": "4.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "path-key",
            "direct": false,
            "version": "3.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "pathe",
            "direct": false,
            "version": "2.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "picocolors",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "picomatch",
            "direct": false,
            "version": "4.0.4",
            "ecosystem": "npm"
          },
          {
            "name": "playwright",
            "direct": false,
            "version": "1.61.1",
            "ecosystem": "npm"
          },
          {
            "name": "playwright-core",
            "direct": false,
            "version": "1.61.1",
            "ecosystem": "npm"
          },
          {
            "name": "pngjs",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "postcss",
            "direct": false,
            "version": "8.5.16",
            "ecosystem": "npm"
          },
          {
            "name": "postcss-load-config",
            "direct": false,
            "version": "3.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "postcss-safe-parser",
            "direct": false,
            "version": "7.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "postcss-scss",
            "direct": false,
            "version": "4.0.9",
            "ecosystem": "npm"
          },
          {
            "name": "postcss-selector-parser",
            "direct": false,
            "version": "7.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "prelude-ls",
            "direct": false,
            "version": "1.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "prettier",
            "direct": false,
            "version": "3.9.4",
            "ecosystem": "npm"
          },
          {
            "name": "prettier-plugin-svelte",
            "direct": false,
            "version": "4.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "punycode",
            "direct": false,
            "version": "2.3.1",
            "ecosystem": "npm"
          },
          {
            "name": "require-directory",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "npm"
          },
          {
            "name": "require-from-string",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "require-main-filename",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "rolldown",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          },
          {
            "name": "saxes",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "semver",
            "direct": false,
            "version": "7.8.0",
            "ecosystem": "npm"
          },
          {
            "name": "set-blocking",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "shebang-command",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "shebang-regex",
            "direct": false,
            "version": "3.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "siginfo",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "source-map-js",
            "direct": false,
            "version": "1.2.1",
            "ecosystem": "npm"
          },
          {
            "name": "stackback",
            "direct": false,
            "version": "0.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "std-env",
            "direct": false,
            "version": "4.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "string-width",
            "direct": false,
            "version": "4.2.3",
            "ecosystem": "npm"
          },
          {
            "name": "strip-ansi",
            "direct": false,
            "version": "6.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "supports-color",
            "direct": false,
            "version": "7.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "svelte-eslint-parser",
            "direct": false,
            "version": "1.8.0",
            "ecosystem": "npm"
          },
          {
            "name": "symbol-tree",
            "direct": false,
            "version": "3.2.4",
            "ecosystem": "npm"
          },
          {
            "name": "tinybench",
            "direct": false,
            "version": "2.9.0",
            "ecosystem": "npm"
          },
          {
            "name": "tinyexec",
            "direct": false,
            "version": "1.1.2",
            "ecosystem": "npm"
          },
          {
            "name": "tinyglobby",
            "direct": false,
            "version": "0.2.17",
            "ecosystem": "npm"
          },
          {
            "name": "tinyrainbow",
            "direct": false,
            "version": "3.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "tldts",
            "direct": false,
            "version": "7.0.30",
            "ecosystem": "npm"
          },
          {
            "name": "tldts-core",
            "direct": false,
            "version": "7.0.30",
            "ecosystem": "npm"
          },
          {
            "name": "tough-cookie",
            "direct": false,
            "version": "6.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "tr46",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "ts-api-utils",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "npm"
          },
          {
            "name": "tslib",
            "direct": false,
            "version": "2.8.1",
            "ecosystem": "npm"
          },
          {
            "name": "type-check",
            "direct": false,
            "version": "0.4.0",
            "ecosystem": "npm"
          },
          {
            "name": "typescript",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "typescript-eslint",
            "direct": false,
            "version": "8.62.1",
            "ecosystem": "npm"
          },
          {
            "name": "undici",
            "direct": false,
            "version": "7.28.0",
            "ecosystem": "npm"
          },
          {
            "name": "undici-types",
            "direct": false,
            "version": "7.21.0",
            "ecosystem": "npm"
          },
          {
            "name": "uri-js",
            "direct": false,
            "version": "4.4.1",
            "ecosystem": "npm"
          },
          {
            "name": "util-deprecate",
            "direct": false,
            "version": "1.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "vite",
            "direct": false,
            "version": "8.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "vitefu",
            "direct": false,
            "version": "1.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "vitest",
            "direct": false,
            "version": "4.1.10",
            "ecosystem": "npm"
          },
          {
            "name": "w3c-xmlserializer",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "webidl-conversions",
            "direct": false,
            "version": "8.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "whatwg-mimetype",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "whatwg-url",
            "direct": false,
            "version": "16.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "which",
            "direct": false,
            "version": "2.0.2",
            "ecosystem": "npm"
          },
          {
            "name": "which-module",
            "direct": false,
            "version": "2.0.1",
            "ecosystem": "npm"
          },
          {
            "name": "why-is-node-running",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "npm"
          },
          {
            "name": "word-wrap",
            "direct": false,
            "version": "1.2.5",
            "ecosystem": "npm"
          },
          {
            "name": "wrap-ansi",
            "direct": false,
            "version": "6.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "xml-name-validator",
            "direct": false,
            "version": "5.0.0",
            "ecosystem": "npm"
          },
          {
            "name": "xmlchars",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "npm"
          },
          {
            "name": "y18n",
            "direct": false,
            "version": "4.0.3",
            "ecosystem": "npm"
          },
          {
            "name": "yaml",
            "direct": false,
            "version": "1.10.3",
            "ecosystem": "npm"
          },
          {
            "name": "yargs",
            "direct": false,
            "version": "15.4.1",
            "ecosystem": "npm"
          },
          {
            "name": "yargs-parser",
            "direct": false,
            "version": "18.1.3",
            "ecosystem": "npm"
          },
          {
            "name": "yocto-queue",
            "direct": false,
            "version": "0.1.0",
            "ecosystem": "npm"
          },
          {
            "name": "zimmerframe",
            "direct": false,
            "version": "1.1.4",
            "ecosystem": "npm"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 334,
        "direct_count": 10,
        "indirect_count": 324
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 60,
        "open_issues": 1,
        "closed_ratio": 0,
        "closed_issues": 0,
        "closed_unmerged_prs": 23
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "buliwyf42",
          "commits": 292,
          "avatar_url": "https://avatars.githubusercontent.com/u/4658822?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "dependabot-auto-merge.yml",
        "publish-image.yml",
        "test.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".golangci.yml",
        "eslint.config.js"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum",
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": null,
            "reason": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
            "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/25 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 9,
            "reason": "dependency not pinned by hash detected -- score normalized to 9",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 4,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 8,
            "reason": "2 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "c580f1054f27a87e07bb176023a7aa42294cbd58",
        "ran_at": "2026-07-24T13:17:54Z",
        "aggregate_score": 6.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-23T06:11:24Z",
      "oldest_open_prs": [
        {
          "number": 84,
          "created_at": "2026-07-20T17:45:37Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 86,
          "created_at": "2026-07-20T17:46:46Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-20T17:49:19Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 13,
          "created_at": "2026-05-11T13:16:14Z",
          "last_comment_at": "2026-05-23T08:53:43Z",
          "last_comment_author": "buliwyf42"
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/buliwyf42/shellyadmin",
    "host": "github.com",
    "name": "shellyadmin",
    "owner": "buliwyf42"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 60,
      "inputs": {
        "security": 67,
        "vitality": 85,
        "community": 46,
        "governance": 24,
        "engineering": 84
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 85,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "commits_last_year": 325,
              "human_commit_share": 0.75,
              "days_since_last_push": 1,
              "active_weeks_last_year": 16
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "16/52 weeks with commits",
                "points": 11.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 16
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "325 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 325
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 70,
              "latest_release_tag": "v0.6.3",
              "releases_from_tags": false,
              "days_since_latest_release": 1,
              "mean_days_between_releases": 6.6
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "70 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 70
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 1 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 1
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~6.6 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 6.6
                    }
                  }
                ],
                "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": 46,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 5,
            "inputs": {
              "forks": 0,
              "stars": 3,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "3 stars",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "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": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 92,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (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": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "critical",
        "name": "Sustainability & Governance",
        "value": 24,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "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 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 28,
            "inputs": {
              "merged_prs": 60,
              "open_issues": 1,
              "closed_issues": 0,
              "issue_closed_ratio": 0,
              "closed_unmerged_prs": 23
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "0% of issues closed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 0
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "60/83 decided PRs merged",
                "points": 27.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 60,
                      "decided": 83
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/25 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 38,
            "inputs": {
              "followers": 2,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "buliwyf42",
              "public_repos": 4,
              "account_age_days": 4792
            },
            "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": "2 followers of buliwyf42",
                "points": 3.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 2,
                      "login": "buliwyf42"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "4 public repos, account ~13 yr old",
                "points": 17.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 4
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 13
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 84,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "3 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": ".golangci.yml, eslint.config.js",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml, eslint.config.js"
                    }
                  }
                ],
                "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": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "topics": [
                "docker",
                "firmware-management",
                "golang",
                "home-automation",
                "iot",
                "mcp",
                "self-hosted",
                "shelly",
                "smart-home",
                "svelte"
              ],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "10 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 67,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Branch-Protection, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "branch_protection",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 61,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 6.1
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/25 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 9",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 2,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "2 existing vulnerabilities detected",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories. Remaining weights renormalized. Matched 334 resolved dependencies against OSV. This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 334
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 89,
            "inputs": {
              "source": "osv",
              "advisories": 2,
              "affected_packages": 2,
              "assessed_packages": 334,
              "unassessed_packages": 0,
              "affected_by_severity": "high 1, unknown 1",
              "direct_affected_packages": 1
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "1 affected: golang.org/x/crypto v0.54.0 (unknown)",
                "points": 26.6,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "golang.org/x/crypto v0.54.0 (unknown)"
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 334,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 83,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.96,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 43430
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "72 of 75 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 72,
                      "sampled": 75
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "excellent",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 99,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum",
                "package-lock.json"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "web/tsconfig.json"
              ],
              "agent_commit_share": 0.2,
              "toolchain_manifests": [
                "go.mod"
              ],
              "dependency_bot_commit_share": 0.25
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "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": ".golangci.yml, eslint.config.js",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".golangci.yml, eslint.config.js"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "web/tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "web/tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "20 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 20,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "25 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 25,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 9",
                "points": 9,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 52308,
              "source_files_sampled": 209,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/209 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 209,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-24T13:18:04.092083Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/b/buliwyf42/shellyadmin.svg",
  "full_name": "buliwyf42/shellyadmin",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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