has a greedy `Name` capture\nthat walks to the *last* `:` in a line. For TypeScript property\ndeclarations whose type is an arrow function -- e.g.\n`UnderlyingSource` in lib.dom.d.ts:\n\n pull?: (controller: ReadableStreamDefaultControll\n[…]\n the\n`ToObject` (dependent-DTO) and `ToTopLevelObject` paths.\n\nAdds three regression tests in ArrowFunctionPropertyFilterTests.cs.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Filter arrow-function-typed property lines in IsProperty", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T03:18:07Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "8d40daf7b2b03259b851fc577a985daf59b4ac7e", "body": "`lib.dom.d.ts` declares many trivial aliases that point at a primitive\nTS type, e.g.\n\n type DOMHighResTimeStamp = number;\n type GLuint = number;\n type GLboolean = boolean;\n type EpochTimeStamp = number;\n\nPreviously `TryGetPrimitiveType` only resolved string-literal-union\naliases (`type D\n[…]\nthe property, method-return, and parameter surfaces across\nthe three common alias shapes. Full suite: 279 -> 289 tests, all green.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Resolve single-primitive TypeScript aliases (DOMHighResTimeStamp, GL*)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T03:11:38Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "8f897c190b0f7cb0b621d74c1ac0100173251265", "body": "Three code paths produced uncompilable output when a method accepted\na TS callback with zero parameters (e.g. `VoidFunction`, `(): void;`,\nused by `WindowOrWorkerGlobalScope.queueMicrotask`):\n\n* `CSharpType.ToActionString` joined `ActionDeclaration.DependentTypes`\n keys into the generic argument li\n[…]\nross `CSharpTypeCallbackActionStringTests`\nand `SourceBuilderZeroParameterCallbackTests`. Full suite:\n274 -> 279 tests, all green.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Emit valid C# for zero-parameter TS callbacks (VoidFunction)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T03:03:50Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "41beab2bbf813f3e1515d9b8373ff618f4630ea5", "body": "When a method parameter or return type was an array of a user-defined\nTypeScript interface (e.g. `MutationRecord[]`), the generator looked\nthe literal type string up in the declaration map without stripping\nthe array suffix. Because the map keys the element type only, no\nmatch occurred, the element \n[…]\nntDependentTypeTests` covering\nparameter and return positions for all three array shapes. Full\nsuite: 268 -> 274 tests, all green.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Emit dependent DTOs for array-of-custom-type parameters and return types", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:58:05Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "466e854da35b911eac5d5c58e35b444c1f99092a", "body": "…positions\n\n`CSharpType.ToParameterString` and `CSharpMethodExtensions.GetMethodTypes`\nboth relied on `TypeMap.PrimitiveTypes.IsPrimitiveType(RawTypeName)`\nreturning `true` for the full type spelling. That works for scalar\nTS primitives (`number` -> `double`), but it returns `false` for the\narray fo\n[…]\nsts` (8 cases) and\n`CSharpMethodReturnTypeArrayTests` (11 cases) covering scalar +\nnullable + non-primitive forms. 268 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Map TypeScript primitive arrays to C# arrays in parameter and return …", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:55:51Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "1adaca3077d526200440fe20d0de46fde8e6f408", "body": "…nostic and polish messages\n\n`Descriptors.PathFromWindowRequiredDiagnostic` carried a stale name\nfrom an earlier iteration of `JSAutoInteropAttribute` (when the\nproperty was called `PathFromWindow`). It now flags a missing\n`Implementation` value, so the field name was misleading - any future\ncontrib\n[…]\ne\n controls\n\nThe diagnostics are still tracked as `Unshipped`, so the message\npolish is in-scope. All 249 tests continue to pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Rename PathFromWindowRequiredDiagnostic to ImplementationRequiredDiag…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:50:29Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "3458ec5e679371260a614b6585d7739687302f28", "body": "ToObject and ToTopLevelObject classified a property as nullable when\nits raw type string `Contains(\"| null\")`. That returns false positives\nfor shapes where `| null` appears only inside a generic argument or\narray element (e.g. `(number | null)[]`, `Map\u003cstring, string | null>`).\nThe reference itself\n[…]\nameterized cases covering the new boundary (including the two\nnested-`| null` regressions that previously failed). 249 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Tighten property-level nullable detection to top-level | null only", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:46:33Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "4d8702001e7db546f6dd06eb68d0b95722db6235", "body": "CSharpObject.IsActionParameter used to OR shape-based IsCallback with\na name-suffix fallback `TypeName.EndsWith(\"Callback\")`. The latter\nmisclassified any normal DTO whose name happens to end with the\nsubstring, silently dropping it from the generated output (the\npredicate gates AddDependentTypesSou\n[…]\nests with five regression cases\ncovering the previous false-positive and confirming the new\nshape-driven behavior. 242 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "Remove brittle Callback suffix fallback in IsActionParameter", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:44:03Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "42a066be5e76c6252ab1bc198262b1484153dca8", "body": "…lable arrays\n\n`CSharpProperty.IsArray` and `TryGetArrayElementTypeName` matched on\n`EndsWith(\"[]\")` (and the `Array\u003c...>` / `ReadonlyArray\u003c...>` generic\nprefixes) against the raw TypeScript type. For nullable arrays the\ntype ends with `null`, not `]` or `>`, so the array shape was never\nrecognized.\n[…]\ndouble[]\"\n\nAdds 13 parameterized regression cases across `IsArray`,\n`MappedTypeName`, and `GetPropertyTypes`.\n\nAll 234 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: recognize `T[] | null` (and Array/ReadonlyArray variants) as nul…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:40:32Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "47e68bddc64aa0d8f38104b17d8fc6abae2b809e", "body": "…le shapes\n\n`CSharpMethod.IsReturnTypeNullable` checked\n`RawReturnTypeName.Contains(\"null\")`, which returns `true` for any\nidentifier whose name happens to contain the substring \"null\" --\nincluding the bundled DOM types `OnBeforeUnloadEventHandlerNonNull`\nand `OnErrorEventHandlerNonNull`, plus any u\n[…]\nssion cases covering both true positives\n(real `| null` clauses) and false positives (identifier substrings).\n\nAll 221 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: tighten `IsReturnTypeNullable` to recognize only TS-level nullab…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:36:51Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "94fb3f0376c84d91fe81bd71226fc8425b7777a6", "body": "`ParseParameters` previously detected nullability only from the\nparameter name's trailing `?`. When a `.d.ts` parameter was instead\nwritten as `x: T | null` (without a `?` on the name), the parser\nkept the literal \"| null\" in the C# type token. For primitives like\n`string | null` this happened to wo\n[…]\ns the parameter's `IsNullable` flag flips and that\n`ToParameterString()` no longer contains the literal `| null`.\n\n210 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: normalize type-level `| null` parameter annotations to nullable C#", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:35:15Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "a37b986430b786027758326e7fbde5a38792f3bc", "body": "…ions\n\n`GenericMethodDescriptors`, `PureJavaScriptOverrides`, and\n`TypeDeclarationSources` accept `string[]?`. With C# 12 collection\nexpressions, consumers can write:\n\n [JSAutoGenericInterop(\n GenericMethodDescriptors = [\"getItem\", \"setItem:value\"])]\n\n`ReadStringArray` recognized `new[] { \n[…]\ner\n - [...] collection expression with literal strings\n - [...] collection expression with const references\n\nAll 207 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "feat: parse string-array attribute args from C# 12 collection express…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:31:33Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "59131477061f7b7b7aa470e503ed4a5d14017ed9", "body": "`ResolveParsers` constructed a fresh `TypeDeclarationParser` (and the\nunderlying `TypeDeclarationReader`) for every matched `.d.ts`\nreference in every target. When multiple `[JSAutoInterop]` targets\nin the same compilation point at the same `AdditionalFile` (the\ncommon case once `TypeDeclarationSour\n[…]\nis GC'd with the parsers\nthemselves; we do not extend their lifetime beyond the source-output\nboundary.\n\nAll 203 tests still pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "perf: share TypeDeclarationParser across targets within an Execute pass", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:29:39Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "df5dbb76d6942ef3fcf55162f8038815ad1c9ad1", "body": "The `Indentation` value type held a `Level` field that was never\nclamped. `Decrease()` computed `Level - 1 - extra`, and `ResetTo(int)`\ncopied the caller's value verbatim. Both could leave `Level` negative.\n`ToString()` then evaluates `new string(' ', Spaces * Level)` which\nthrows `ArgumentOutOfRang\n[…]\n regression tests covering Decrease-from-zero,\nDecrease-with-extra, ResetTo-negative, and the positive paths.\n\nAll 203 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: clamp Indentation Decrease/ResetTo to non-negative levels", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:26:35Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "685cdd3ed6ae2d523f4a392a2207d64626fb95d7", "body": "…ually shrinks\n\nThe previous test only asserted that *some* output was produced when\n'OnlyGeneratePureJS = true' was set, which any non-trivial code path\nwould satisfy. The flag's documented purpose is to *exclude* methods\nthat need JS-callback wiring (e.g. 'Geolocation.watchPosition'/\n'getCurrentPo\n[…]\ned out).\n\nThis catches regressions where the flag silently stops gating output,\nwhich the prior test did not.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "test: strengthen OnlyGeneratePureJS coverage to verify method-set act…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:25:11Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "8ce5d2ab50722d9d80064b8780364125e10a3233", "body": "…ehavior\n\nTwo internal comments still described TypeDeclarationSources as\n'reserved for future use' even though T5.1 fully wired the property\ninto the generator pipeline. Update both to describe the actual\nbehavior:\n\n* GeneratorOptions.BuildParsers — clarify that this is the fallback\n path used whe\n[…]\nReader(content) directly,\n which is what the generator already does for AdditionalFiles.\n\nNo behavior change. All 198 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "docs: refresh stale TypeDeclarationSources comments to reflect T5.1 b…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:23:58Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "7e5ff5b39f17a2b8b10ec2b7b8b5122ed27cd49a", "body": "….1 behavior\n\nThe emitted attribute's XML doc for `TypeDeclarationSources` still\nclaimed the property was \"reserved for future use\" and that \"setting\nit has no effect\". The audit's T5.1 work wired this property into the\ngenerator pipeline so the generator now reads matched `.d.ts` files\nfrom `Additi\n[…]\nle doc with the actual behavior, including the\n`AdditionalFiles` MSBuild snippet a consumer needs to wire up.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "docs: align JSAutoInteropAttribute.TypeDeclarationSources doc with T5…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:23:01Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "2a12791de33190827d119fee9c69926287b2c8de", "body": "Mark every regex in `SharedRegex` as `RegexOptions.Compiled |\nRegexOptions.CultureInvariant`. The parser evaluates these patterns\nmany times per generator run - once per matched interface, method,\nproperty, and array literal across ~800KB of lib.dom.d.ts plus any\nconsumer-supplied `.d.ts` files in `\n[…]\n removes culture-sensitive case-folding\nfrom the matcher even though none of these patterns use `IgnoreCase`.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "perf: compile shared parser regexes", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:21:19Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "63f31ff1ba80511890840f9ed14c707f5f31fe15", "body": "… interface\n\n`CSharpProperty.MappedTypeName` deliberately returns the *element* type\nfor array-shaped TypeScript types so that primitive-type lookups and\ndependency-graph walks can ignore the array wrapper. `CSharpObject.AppendProperty`\nalready re-attaches `[]` via a separate `IsArray` check, but th\n[…]\ng\nall three TypeScript array forms (`T[]`, `Array\u003cT>`, `ReadonlyArray\u003cT>`)\nagainst both `IsWebAssembly` arms.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: preserve `[]` suffix when emitting array properties on top-level…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:18:28Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "af4f9eabc7f78beda830d21c12826adeb02474eb", "body": "… lookups\n\nTwo small but correct improvements to the generator hot path:\n\n1. `JavaScriptInteropGenerator.Execute` now reads\n `context.CancellationToken` once and calls\n `ThrowIfCancellationRequested()` at the top of every outer-target\n iteration and inside the inner parser loop. Previously the\n[…]\ne across ~800KB of lib.dom.d.ts, so this O(1) lookup\n replaces what was effectively an O(n) per-check scan.\n\nAll 192 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "perf: thread CancellationToken through Execute and speed up primitive…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:16:00Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "8fd9a5e78231085adcce6ebe7c58f99e63f294c7", "body": "`SourceBuilder.AppendConditionalDelegateCallbackMethods` only called\n`ResetIndentationTo(level)` after the entire loop. Each iteration\ncalls `AppendRaw(..., postIncreaseIndentation: true)` (twice through\n`AppendParameters`), so successive callback methods were emitted at\never-deeper indentation. The\n[…]\nInvokable] block starts at the outer indentation level\nregardless of what the previous iteration left behind.\n\nAll 192 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: reset indentation per [JSInvokable] block in callback emit", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:13:47Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "58fa3cf5c470bf779d1e9ab14d966b123256e88d", "body": "Adds five additional [InlineData] cases to GeneratorOutputValidityTests\nthat exercise less-trodden code paths through the generator:\n\n* LocalStorage on Server (generic + non-generic)\n* LocalStorage on WASM (non-generic)\n* Geolocation with OnlyGeneratePureJS = true\n* SessionStorage on WASM (generic)\n\n[…]\nttribute parsing, hosting-model branches,\nand the OnlyGeneratePureJS flag without requiring snapshot updates.\n\nAll 192 tests pass.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "test: expand generator output validity sweep with 5 new scenarios", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-16T02:13:47Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "838a48e900a4e0cee1df345d7d0d3144626bcbbb", "body": "Until now `JSAutoInteropAttribute.TypeDeclarationSources` was a\ndocumented option that did nothing - the generator always parsed the\nembedded `lib.dom.d.ts` regardless. Consumers wanting to wire a\nnon-DOM TypeScript declaration file (their own ambient module, a\nthird-party `.d.ts`, or a polyfill typ\n[…]\nes_IsBenignNoOp` E2E test that pinned the old\nno-op behavior. Adds README documentation of the new option.\n\n187/187 tests passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "feat: wire TypeDeclarationSources into AdditionalTexts (T5.1)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T19:12:00Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "3c57b258b0b70b80e34fda60443c16035020edbc", "body": "The pre-audit attribute argument parser worked entirely on\n`AttributeArgumentSyntax.Expression.ToString()` and string-replaced\nquotes. That approach failed for:\n\n - String literals containing escape sequences. The naive\n `Replace(\"\\\"\", \"\")` mangled escaped quotes (`\"foo\\\"bar\"` became\n `foo\\ba\n[…]\ns) covering\nescape sequences, const references, nameof, verbatim strings,\nenum members, and bool literals.\n\n184/184 tests passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: parse attribute arguments via SemanticModel (T1.11)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T19:02:22Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "5fcce88ff9ed0ab72f489d17f598fb311a20dad3", "body": "Correctness fixes:\n\n - The \"Note\" about packaging incorrectly claimed Server packages\n expose a synchronous API. They expose `ValueTask`-based async\n methods through `IJSRuntime`; the WebAssembly variant uses\n `IJSInProcessRuntime` which is itself synchronous JS dispatch\n but still surf\n[…]\ndditions from the audit\n (previously the generator was silent on missing `partial`,\n unknown `TypeName`, or parse failures).\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "docs: README accuracy pass (post-audit)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T18:58:12Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "1f4e5c23ff5d55a943b5e2a4f7cb77d4af7da54c", "body": "`ToClassString` was a single ~65-line method building DTO source by\nhand with raw interpolated `\\n`-terminated strings inside one giant\n`foreach` over properties. The shape made it hard to spot anything\ndistinct - the special-case DOMTimeStamp / EpochTimeStamp UTC accessor\nwas buried inside the prop\n[…]\nng mode.\n - Two new snapshot tests pin the DTO output specifically, so any\n future change to `ToClassString` will fail loudly.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "refactor: split CSharpObject.ToClassString into named helpers (T3.9)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T18:56:02Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "217b870cee43e0da70f6c594f8796637b4a17bac", "body": "The implementation builder was a 286-line method with three structurally\ndistinct branches nested inside a `foreach (method)` loop:\n\n 1. Pure / non-bi-directional / JS-override invocations\n 2. Generic `TComponent` overload (bi-directional callback shape)\n 3. `Action\u003cT>` callback overload (same ca\n[…]\nweep (`GeneratorOutputValidityTests`) confirms\n every generated tree still parses without syntax errors.\n\nSnapshot diff: empty.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "refactor: split CSharpTopLevelObject.ToImplementationString (T3.8)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T18:53:14Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "687cacbc6e331ffc4504feec10263acfd397a9b9", "body": "T5.2 added `void -> void` to `TypeMap.PrimitiveTypes` so the parser\ncan short-circuit on void-returning methods instead of trying to\nrecurse into a non-existent `void` declaration. This (correctly)\nmade `IsPrimitiveType(\"void\")` return true for the first time.\n\nThat flipped a latent ordering bug in\n\n[…]\normalizeWhitespace removal, T3.8\n `ToImplementationString` refactor) producing malformed C#.\n\nTests: 176/176 (was 173 + 3 new).\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "fix: emit `ValueTask` (not `ValueTask\u003cvoid>`) for void Server methods", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T18:48:29Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "3b80dc675c58ee775c21bbcb36553d4a83e50e5e", "body": "Adds a lightweight string-snapshot helper plus 5 baseline snapshots\ncovering the most-exercised interop scenarios:\n\n - Geolocation_Wasm: interface, implementation, DI extension\n - Geolocation_Server: implementation (proves async ValueTask shape)\n - LocalStorage_Wasm_Generic: interface (proves JS\n[…]\nanother reference\nasset and disk layout convention isn't worth it for ~50 lines of\nhelper code.\n\nTests: 173/173 (was 168 + 5 new).\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "test: add hand-rolled snapshot harness for generator output", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T18:45:25Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "5572a36f5d0b85a195a0551905cc81fb5709b9d0", "body": "Adds primitive mappings for the TypeScript tokens that flow through\n`lib.dom.d.ts` but were previously unhandled by `TypeMap.PrimitiveTypes`.\nAnything not in the map falls through `IsPrimitiveType` to the\ndeclaration-recursion branch, which either emits an empty placeholder\nDTO (for declared interfa\n[…]\nrough a translated parameter type).\n - Negative cases - real DOM interface names still report `false`.\n\nTotal tests: 168 passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "feat: expand TypeMap to cover void/any/bigint/typed-arrays (T5.2)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-15T18:43:31Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "b4356a1ba8ecf0c8ff74e0c40c53ef8b2ce3b2f9", "body": "…T1.4)\n\nThe `TypeDeclarationSources` attribute parameter was documented as\naccepting \"URLs or file paths\" but the implementation is a no-op:\n`TypeDeclarationReader.Factory(string)` ignores its argument and\nreturns the default embedded-resource reader, with the URI handling\ncommented out.\n\nThis commi\n[…]\n the no-op contract so any future implementation has to\n actively change behavior, not just compile.\n\nTotal tests: 120 passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "refactor: clarify TypeDeclarationSources as reserved-for-future-use (…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-14T22:35:07Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "165ef6e8d907f9de2f677043b2a41ba8a229ca22", "body": "…T3.10)\n\nPreviously the parser identified TypeScript callback interfaces using a\nbrittle `typeName.EndsWith(\"Callback\")` heuristic in two places:\n\n - `TypeDeclarationParser.ParseParameters` - to decide whether to call\n `ToAction(...)` and emit an `Action\u003cT>` parameter, or `ToObject(...)`\n and\n[…]\negative cases (regular interfaces, properties-only, empty bodies,\n whitespace, non-interface input).\n\nTotal tests: 119 passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "refactor: replace `EndsWith(\"Callback\")` with shape-based detection (…", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-14T22:32:34Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "4aacf1c24785fcf3684f461904420839e94da6d4", "body": "Six end-to-end tests covering the actual shape of the generated\noutput across all four artifact kinds the generator emits per\n`[JSAutoInterop]` hit:\n\n- `Geolocation_InterfaceFile_DeclaresExpectedMembers` - the\n `IGeolocationService` interface file declares `ClearWatch`,\n `GetCurrentPosition`, `Wat\n[…]\ntic and hosting-model tests added earlier,\nthis closes the Tier 4 \"end-to-end generation\" coverage gap.\n\nTotal tests: 105 passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "test: add end-to-end snapshot-style generation tests (T4)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-14T22:29:04Z", "body_truncated": true, "is_coding_agent": true }, { "oid": "279e214545947929f4fad5f44f297d3351ed93a6", "body": "Four tests verifying that the `HostingModel = BlazorHostingModel.X`\nattribute argument correctly switches the generator between\nWebAssembly (synchronous, `IJSInProcessRuntime`) and Server\n(asynchronous, `IJSRuntime`) output shapes.\n\n- `Default_GeneratesWebAssemblyExtensions` - default mode emits\n `\n[…]\nse the interface filename also ends with that\nsuffix - exact filename match is the only safe comparison.\n\nTotal tests: 99 passing.\n\nCo-authored-by: Copilot \u003c223556219+Copilot@users.noreply.github.com>", "is_bot": false, "headline": "test: add WebAssembly vs Server hosting-model regression tests (T4)", "author_name": "David Pine", "author_login": "IEvangelist", "committed_at": "2026-05-14T22:28:06Z", "body_truncated": true, "is_coding_agent": true } ], "releases_count": 43, "commits_last_year": 124, "latest_release_at": "2026-07-24T18:48:52Z", "latest_release_tag": "10.1.0", "releases_from_tags": false, "days_since_last_push": 0, "active_weeks_last_year": 5, "days_since_latest_release": 0, "mean_days_between_releases": 142 }, "community": { "has_readme": true, "has_license": true, "has_description": true, "has_contributing": false, "health_percentage": 71, "has_issue_template": false, "has_code_of_conduct": true, "has_pull_request_template": false }, "ecosystem": { "packages": [ { "name": "Blazor.DOM", "exists": true, "license": null, "keywords": [ "dotnet", "dotnetcore", "csharp", "blazor", "server", "dom", "interop", "jsinterop" ], "ecosystem": "nuget", "matches_repo": true, "registry_url": "https://www.nuget.org/packages/Blazor.DOM", "is_deprecated": false, "latest_version": "10.1.0", "repository_url": "https://github.com/IEvangelist/blazorators", "versions_count": 1, "total_downloads": 0, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2026-07-24T18:52:39.883000Z", "latest_version_yanked": null, "days_since_latest_publish": 0 }, { "name": "Blazor.Clipboard", "exists": true, "license": null, "keywords": [ "dotnet", "blazor", "server", "dom", "interop", "clipboard" ], "ecosystem": "nuget", "matches_repo": true, "registry_url": "https://www.nuget.org/packages/Blazor.Clipboard", "is_deprecated": false, "latest_version": "10.1.0", "repository_url": "https://github.com/IEvangelist/blazorators", "versions_count": 1, "total_downloads": 0, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2026-07-24T18:52:38.400000Z", "latest_version_yanked": null, "days_since_latest_publish": 0 }, { "name": "Blazor.Credentials", "exists": true, "license": null, "keywords": [ "dotnet", "blazor", "server", "dom", "interop", "credentials", "webauthn" ], "ecosystem": "nuget", "matches_repo": true, "registry_url": "https://www.nuget.org/packages/Blazor.Credentials", "is_deprecated": false, "latest_version": "10.1.0", "repository_url": "https://github.com/IEvangelist/blazorators", "versions_count": 1, "total_downloads": 0, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2026-07-24T18:52:39Z", "latest_version_yanked": null, "days_since_latest_publish": 0 }, { "name": "Blazor.Geolocation", "exists": true, "license": null, "keywords": [ "dotnet", "dotnetcore", "csharp", "blazor", "server", "wasm", "generators", "sourcegen", "roslyn" ], "ecosystem": "nuget", "matches_repo": true, "registry_url": "https://www.nuget.org/packages/Blazor.Geolocation", "is_deprecated": false, "latest_version": "10.1.0", "repository_url": "https://github.com/IEvangelist/blazorators", "versions_count": 19, "total_downloads": 94337, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2026-07-24T18:52:40.950000Z", "latest_version_yanked": null, "days_since_latest_publish": 0 }, { "name": "Blazor.LocalStorage", "exists": true, "license": null, "keywords": [ "dotnet", "dotnetcore", "csharp", "blazor", "generators", "sourcegen", "roslyn" ], "ecosystem": "nuget", "matches_repo": true, "registry_url": "https://www.nuget.org/packages/Blazor.LocalStorage", "is_deprecated": false, "latest_version": "10.1.0", "repository_url": "https://github.com/IEvangelist/blazorators", "versions_count": 19, "total_downloads": 84532, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2026-07-24T18:52:41.440000Z", "latest_version_yanked": null, "days_since_latest_publish": 0 }, { "name": "Blazor.MediaDevices", "exists": true, "license": null, "keywords": [ "dotnet", "blazor", "server", "dom", "interop", "media-devices", "get-user-media", "display-capture" ], "ecosystem": "nuget", "matches_repo": true, "registry_url": "https://www.nuget.org/packages/Blazor.MediaDevices", "is_deprecated": false, "latest_version": "10.1.0", "repository_url": "https://github.com/IEvangelist/blazorators", "versions_count": 1, "total_downloads": 0, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2026-07-24T18:52:41.963000Z", "latest_version_yanked": null, "days_since_latest_publish": 0 }, { "name": "Blazor.Notifications", "exists": true, "license": null, "keywords": [ "Blazor", "Notifications", "C#", ".NET", "Standard", ".NET", "Core" ], "ecosystem": "nuget", "matches_repo": false, "registry_url": "https://www.nuget.org/packages/Blazor.Notifications", "is_deprecated": false, "latest_version": "0.2.0", "repository_url": "https://github.com/vertonghenb/Blazor.Notifications", "versions_count": 2, "total_downloads": 3360, "dependents_count": null, "deprecation_note": null, "maintainers_count": null, "monthly_downloads": null, "first_published_at": null, "latest_published_at": "2018-06-19T23:35:33.853000Z", "latest_version_yanked": null, "days_since_latest_publish": 2956 } ] }, "popularity": { "forks": 32, "stars": 392, "watchers": 13, "fork_history": { "days": [ { "date": "2021-10-12", "count": 1 }, { "date": "2022-03-08", "count": 1 }, { "date": "2022-03-25", "count": 1 }, { "date": "2022-04-04", "count": 1 }, { "date": "2022-04-08", "count": 1 }, { "date": "2022-04-12", "count": 3 }, { "date": "2022-04-14", "count": 1 }, { "date": "2022-04-21", "count": 1 }, { "date": "2022-05-11", "count": 1 }, { "date": "2022-10-07", "count": 1 }, { "date": "2022-10-23", "count": 1 }, { "date": "2022-11-04", "count": 1 }, { "date": "2022-12-01", "count": 1 }, { "date": "2023-01-24", "count": 1 }, { "date": "2023-02-02", "count": 1 }, { "date": "2023-02-10", "count": 1 }, { "date": "2023-02-15", "count": 1 }, { "date": "2023-02-16", "count": 1 }, { "date": "2023-02-17", "count": 1 }, { "date": "2023-04-20", "count": 1 }, { "date": "2023-04-22", "count": 1 }, { "date": "2023-06-09", "count": 1 }, { "date": "2023-11-18", "count": 1 }, { "date": "2024-01-01", "count": 1 }, { "date": "2024-01-08", "count": 1 }, { "date": "2024-01-14", "count": 1 }, { "date": "2024-03-19", "count": 1 }, { "date": "2024-07-02", "count": 1 }, { "date": "2025-04-04", "count": 1 }, { "date": "2025-05-17", "count": 1 } ], "complete": true, "collected": 32, "total_forks": 32 }, "star_history": null, "open_issues_and_prs": 0 }, "ai_readiness": { "has_nix": false, "example_dirs": [ "samples" ], "has_llms_txt": false, "has_dockerfile": false, "has_mcp_signal": false, "bootstrap_files": [], "api_schema_files": [], "has_devcontainer": false, "typecheck_configs": [ "tools/Blazor.DOM.TypeScriptModel/tsconfig.json" ], "toolchain_manifests": [ "samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj", "samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj", "src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj", "src/Blazor.BrowserCoordination/Blazor.BrowserCoordination.csproj", "src/Blazor.Clipboard.WebAssembly/Blazor.Clipboard.WebAssembly.csproj", "src/Blazor.Clipboard/Blazor.Clipboard.csproj", "src/Blazor.Credentials.WebAssembly/Blazor.Credentials.WebAssembly.csproj", "src/Blazor.Credentials/Blazor.Credentials.csproj", "src/Blazor.DOM.Generation/Blazor.DOM.Generation.csproj", "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj", "src/Blazor.DOM/Blazor.DOM.csproj", "src/Blazor.FileSystemAccess.WebAssembly/Blazor.FileSystemAccess.WebAssembly.csproj", "src/Blazor.FileSystemAccess/Blazor.FileSystemAccess.csproj", "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj", "src/Blazor.Geolocation/Blazor.Geolocation.csproj", "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "src/Blazor.MediaDevices.WebAssembly/Blazor.MediaDevices.WebAssembly.csproj", "src/Blazor.MediaDevices/Blazor.MediaDevices.csproj", "src/Blazor.Notifications.WebAssembly/Blazor.Notifications.WebAssembly.csproj", "src/Blazor.Notifications/Blazor.Notifications.csproj", "src/Blazor.OfflineStorage.WebAssembly/Blazor.OfflineStorage.WebAssembly.csproj", "src/Blazor.OfflineStorage/Blazor.OfflineStorage.csproj", "src/Blazor.Performance.WebAssembly/Blazor.Performance.WebAssembly.csproj", "src/Blazor.Performance/Blazor.Performance.csproj", "src/Blazor.Permissions.WebAssembly/Blazor.Permissions.WebAssembly.csproj", "src/Blazor.Permissions/Blazor.Permissions.csproj", "src/Blazor.Screen.WebAssembly/Blazor.Screen.WebAssembly.csproj", "src/Blazor.Screen/Blazor.Screen.csproj", "src/Blazor.Serialization/Blazor.Serialization.csproj", "src/Blazor.SessionStorage.WebAssembly/Blazor.SessionStorage.WebAssembly.csproj", "src/Blazor.SessionStorage/Blazor.SessionStorage.csproj", "src/Blazor.Share.WebAssembly/Blazor.Share.WebAssembly.csproj", "src/Blazor.Share/Blazor.Share.csproj", "src/Blazor.SourceGenerators/Blazor.SourceGenerators.csproj", "src/Blazor.SpeechRecognition.WebAssembly/Blazor.SpeechRecognition.WebAssembly.csproj", "src/Blazor.SpeechRecognition/Blazor.SpeechRecognition.csproj", "src/Blazor.SpeechSynthesis.WebAssembly/Blazor.SpeechSynthesis.WebAssembly.csproj", "src/Blazor.SpeechSynthesis/Blazor.SpeechSynthesis.csproj", "src/Blazor.StorageManagement.WebAssembly/Blazor.StorageManagement.WebAssembly.csproj", "src/Blazor.StorageManagement/Blazor.StorageManagement.csproj", "src/Blazor.WakeLock.WebAssembly/Blazor.WakeLock.WebAssembly.csproj", "src/Blazor.WakeLock/Blazor.WakeLock.csproj", "src/Blazor.WebCrypto.WebAssembly/Blazor.WebCrypto.WebAssembly.csproj", "src/Blazor.WebCrypto/Blazor.WebCrypto.csproj", "tests/Blazor.BrowserCoordination.Tests/Blazor.BrowserCoordination.Tests.csproj", "tests/Blazor.Clipboard.Tests/Blazor.Clipboard.Tests.csproj", "tests/Blazor.Credentials.Tests/Blazor.Credentials.Tests.csproj", "tests/Blazor.DOM.Accessors.CompilationTests/Blazor.DOM.Accessors.CompilationTests.csproj", "tests/Blazor.DOM.AdvancedTypes.CompilationTests/Blazor.DOM.AdvancedTypes.CompilationTests.csproj", "tests/Blazor.DOM.CSharpGenerator.Tests/Blazor.DOM.CSharpGenerator.Tests.csproj", "tests/Blazor.DOM.Generic.CompilationTests/Blazor.DOM.Generic.CompilationTests.csproj", "tests/Blazor.DOM.GlobalNamespace.CompilationTests/Blazor.DOM.GlobalNamespace.CompilationTests.csproj", "tests/Blazor.DOM.NonEventDeferrals.CompilationTests/Blazor.DOM.NonEventDeferrals.CompilationTests.csproj", "tests/Blazor.DOM.ProfileRuntime/Blazor.DOM.ProfileRuntime.csproj", "tests/Blazor.DOM.ResolvedFailures.CompilationTests/Blazor.DOM.ResolvedFailures.CompilationTests.csproj", "tests/Blazor.DOM.Server.CompilationTests/Blazor.DOM.Server.CompilationTests.csproj", "tests/Blazor.DOM.SupplementalBrowserApis.CompilationTests/Blazor.DOM.SupplementalBrowserApis.CompilationTests.csproj", "tests/Blazor.DOM.Tests/Blazor.DOM.Tests.csproj", "tests/Blazor.DOM.TypedEvents.CompilationTests/Blazor.DOM.TypedEvents.CompilationTests.csproj", "tests/Blazor.DOM.TypedUnions.CompilationTests/Blazor.DOM.TypedUnions.CompilationTests.csproj", "tests/Blazor.DOM.WakeLock.CompilationTests/Blazor.DOM.WakeLock.CompilationTests.csproj", "tests/Blazor.DOM.WebAssembly.CompilationTests/Blazor.DOM.WebAssembly.CompilationTests.csproj", "tests/Blazor.ExampleConsumer.EndToEndTests/Blazor.ExampleConsumer.EndToEndTests.csproj", "tests/Blazor.FileSystemAccess.Tests/Blazor.FileSystemAccess.Tests.csproj", "tests/Blazor.OfflineStorage.Tests/Blazor.OfflineStorage.Tests.csproj", "tests/Blazor.Performance.Tests/Blazor.Performance.Tests.csproj", "tests/Blazor.Screen.Tests/Blazor.Screen.Tests.csproj", "tests/Blazor.Share.Tests/Blazor.Share.Tests.csproj", "tests/Blazor.SourceGenerators.Tests/Blazor.SourceGenerators.Tests.csproj", "tests/Blazor.StorageManagement.Tests/Blazor.StorageManagement.Tests.csproj", "tests/Blazor.WakeLock.Tests/Blazor.WakeLock.Tests.csproj", "tests/Blazor.WebCrypto.Tests/Blazor.WebCrypto.Tests.csproj", "tools/Blazor.DOM.CSharpGenerator/Blazor.DOM.CSharpGenerator.csproj" ], "largest_source_bytes": 816786, "source_files_sampled": 429, "oversized_source_files": 7, "agent_instruction_files": [], "agent_instruction_max_bytes": null }, "dependencies": { "manifests": [], "advisories": { "error": null, "scope": "repository_graph", "source": "osv", "findings": [ { "name": "fast-uri", "direct": false, "version": "3.1.3", "severity": "high", "ecosystem": "npm", "cvss_score": 7.5, "advisory_ids": [ "GHSA-v2hh-gcrm-f6hx" ], "fixed_version": "4.1.1", "advisory_count": 1, "oldest_advisory_days": 2 }, { "name": "ajv", "direct": false, "version": "8.17.1", "severity": "moderate", "ecosystem": "npm", "cvss_score": 5.3, "advisory_ids": [ "GHSA-2g4f-4pwh-qvx6" ], "fixed_version": "8.18.0", "advisory_count": 1, "oldest_advisory_days": 162 } ], "collected": true, "malicious": [], "truncated": false, "by_severity": { "high": 1, "moderate": 1 }, "advisory_count": 2, "affected_count": 2, "assessed_count": 19, "malicious_count": 0, "assessed_package": null, "unassessed_count": 19, "direct_affected_count": 0 }, "ecosystems": [], "dependencies": [ { "name": "Microsoft.SourceLink.GitHub", "manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "MinVer", "manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.AspNetCore.Components.WebAssembly", "manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.Extensions.DependencyInjection", "manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.SourceLink.GitHub", "manifest": "src/Blazor.DOM/Blazor.DOM.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "MinVer", "manifest": "src/Blazor.DOM/Blazor.DOM.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.AspNetCore.Components.Web", "manifest": "src/Blazor.DOM/Blazor.DOM.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.Extensions.DependencyInjection", "manifest": "src/Blazor.DOM/Blazor.DOM.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.JSInterop", "manifest": "src/Blazor.DOM/Blazor.DOM.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.SourceLink.GitHub", "manifest": "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "MinVer", "manifest": "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.AspNetCore.Components.Web", "manifest": "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.SourceLink.GitHub", "manifest": "src/Blazor.Geolocation/Blazor.Geolocation.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "MinVer", "manifest": "src/Blazor.Geolocation/Blazor.Geolocation.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.AspNetCore.Components.Web", "manifest": "src/Blazor.Geolocation/Blazor.Geolocation.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.SourceLink.GitHub", "manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "MinVer", "manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.Extensions.DependencyInjection", "manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.Extensions.Primitives", "manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.JSInterop", "manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.SourceLink.GitHub", "manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "MinVer", "manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.Extensions.DependencyInjection", "manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.Extensions.Primitives", "manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "ecosystem": "nuget", "version_constraint": null }, { "name": "Microsoft.JSInterop", "manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "ecosystem": "nuget", "version_constraint": null } ], "all_dependencies": { "error": null, "source": "github-sbom", "packages": [ { "name": "Microsoft.AspNetCore.Components.Web", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.AspNetCore.Components.WebAssembly", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.Extensions.DependencyInjection", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.Extensions.Primitives", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.JSInterop", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.SourceLink.GitHub", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "MinVer", "direct": true, "version": null, "ecosystem": "nuget" }, { "name": "@pagefind/darwin-arm64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@pagefind/darwin-x64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@pagefind/freebsd-x64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@pagefind/linux-arm64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@pagefind/linux-x64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@pagefind/windows-arm64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@pagefind/windows-x64", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "@types/node", "direct": false, "version": "26.1.1", "ecosystem": "npm" }, { "name": "@webgpu/types", "direct": false, "version": "0.1.71", "ecosystem": "npm" }, { "name": "@webref/idl", "direct": false, "version": "3.81.3", "ecosystem": "npm" }, { "name": "ajv", "direct": false, "version": "8.17.1", "ecosystem": "npm" }, { "name": "fast-deep-equal", "direct": false, "version": "3.1.3", "ecosystem": "npm" }, { "name": "fast-uri", "direct": false, "version": "3.1.3", "ecosystem": "npm" }, { "name": "json-schema-traverse", "direct": false, "version": "1.0.0", "ecosystem": "npm" }, { "name": "pagefind", "direct": false, "version": "1.5.0", "ecosystem": "npm" }, { "name": "require-from-string", "direct": false, "version": "2.0.2", "ecosystem": "npm" }, { "name": "typescript", "direct": false, "version": "5.9.3", "ecosystem": "npm" }, { "name": "undici-types", "direct": false, "version": "8.3.0", "ecosystem": "npm" }, { "name": "webidl2", "direct": false, "version": "24.5.0", "ecosystem": "npm" }, { "name": "Basic.Reference.Assemblies", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "coverlet.collector", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Deque.AxeCore.Playwright", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Humanizer.Core", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.AspNetCore.Components.WebAssembly.DevServer", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.CodeAnalysis.Analyzers", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.CodeAnalysis.CSharp", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.NET.Test.Sdk", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "Microsoft.Playwright", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "System.Reactive.Linq", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "xunit", "direct": false, "version": null, "ecosystem": "nuget" }, { "name": "xunit.runner.visualstudio", "direct": false, "version": null, "ecosystem": "nuget" } ], "collected": true, "truncated": false, "total_count": 38, "direct_count": 7, "indirect_count": 31 } }, "maintainership": { "issues": { "open_prs": 0, "merged_prs": 28, "open_issues": 0, "closed_ratio": 1, "closed_issues": 32, "closed_unmerged_prs": 3 }, "bus_factor": 1, "bot_contributors": 2, "top_contributors": [ { "type": "User", "login": "IEvangelist", "commits": 300, "avatar_url": "https://avatars.githubusercontent.com/u/7679720?v=4" }, { "type": "User", "login": "WeihanLi", "commits": 3, "avatar_url": "https://avatars.githubusercontent.com/u/7604648?v=4" }, { "type": "User", "login": "colindembovsky", "commits": 2, "avatar_url": "https://avatars.githubusercontent.com/u/1932561?v=4" }, { "type": "User", "login": "taori", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/5545184?v=4" }, { "type": "User", "login": "robertmclaws", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/1657085?v=4" }, { "type": "User", "login": "TanayParikh", "commits": 1, "avatar_url": "https://avatars.githubusercontent.com/u/14852843?v=4" } ], "contributors_sampled": 6, "top_contributor_share": 0.974 }, "quality_signals": { "has_ci": true, "has_tests": true, "ci_workflows": [ "build-validation.yml", "pr-validation.yml", "publish-nuget.yml", "publish-to-gh-pages.yml" ], "has_docs_dir": false, "linter_configs": [], "has_editorconfig": true, "has_linter_config": false, "has_precommit_config": false }, "security_signals": { "lockfiles": [ "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": 7, "reason": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7", "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/28 approved changesets -- score normalized to 0", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review" }, { "name": "Contributors", "score": 10, "reason": "project has 6 contributing companies or organizations", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors" }, { "name": "Dangerous-Workflow", "score": 10, "reason": "no dangerous workflow patterns detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow" }, { "name": "Dependency-Update-Tool", "score": 0, "reason": "no update tool detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool" }, { "name": "Fuzzing", "score": 0, "reason": "project is not fuzzed", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing" }, { "name": "License", "score": 10, "reason": "license file detected", "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license" }, { "name": "Maintained", "score": 10, "reason": "30 commit(s) and 0 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": 1, "reason": "dependency not pinned by hash detected -- score normalized to 1", "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": 10, "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": "abe9091425dc6bd6126011894642fc370bc2876d", "ran_at": "2026-07-24T19:01:55Z", "aggregate_score": 5.4, "scorecard_version": "v5.5.0" }, "has_codeql_workflow": false, "has_security_policy": false, "has_dependabot_config": false }, "contribution_flow": { "collected": true, "ci_last_run_at": "2026-07-24T19:01:34Z", "oldest_open_prs": [], "last_merged_pr_at": "2026-07-23T20:57:01Z", "ci_last_conclusion": "SUCCESS", "oldest_open_issues": [] } }, "config": { "disabled_metrics": [], "disabled_categories": [], "disabled_components": {} }, "source": { "url": "https://github.com/IEvangelist/blazorators", "host": "github.com", "name": "blazorators", "owner": "IEvangelist" }, "metrics": { "overall": { "key": "overall", "band": "moderate", "name": "Overall health", "note": null, "notes": [], "value": 68, "inputs": { "security": 63, "vitality": 74, "community": 64, "governance": 66, "engineering": 71 }, "components": [] }, "categories": [ { "key": "vitality", "band": "good", "name": "Vitality", "value": 74, "weight": 0.22, "metrics": [ { "key": "development_activity", "band": "moderate", "name": "Development activity", "note": null, "notes": [], "value": 68, "inputs": { "commits_last_year": 124, "human_commit_share": 1, "days_since_last_push": 0, "active_weeks_last_year": 5 }, "components": [ { "key": "push_recency", "name": "Push recency", "detail": "last push 0 days ago", "points": 36, "status": "met", "details": [ { "code": "push_recency", "params": { "days": 0 } } ], "max_points": 36 }, { "key": "commit_cadence", "name": "Commit cadence", "detail": "5/52 weeks with commits", "points": 3.5, "status": "partial", "details": [ { "code": "commit_cadence_weeks", "params": { "weeks": 5 } } ], "max_points": 36 }, { "key": "commit_volume", "name": "Commit volume", "detail": "124 commits in the last year", "points": 18, "status": "met", "details": [ { "code": "commits_last_year", "params": { "count": 124 } } ], "max_points": 18 }, { "key": "openssf_scorecard_maintained", "name": "OpenSSF Scorecard: Maintained", "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "release_discipline", "band": "good", "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": 84, "inputs": { "releases_count": 43, "latest_release_tag": "10.1.0", "releases_from_tags": false, "days_since_latest_release": 0, "mean_days_between_releases": 142 }, "components": [ { "key": "ships_releases", "name": "Ships releases", "detail": "43 releases published", "points": 27, "status": "met", "details": [ { "code": "releases_published", "params": { "count": 43 } } ], "max_points": 27 }, { "key": "release_recency", "name": "Release recency", "detail": "latest release 0 days ago", "points": 36, "status": "met", "details": [ { "code": "release_recency", "params": { "days": 0 } } ], "max_points": 36 }, { "key": "release_cadence", "name": "Release cadence", "detail": "a release every ~142 days", "points": 12.6, "status": "partial", "details": [ { "code": "release_cadence", "params": { "gap": 142 } } ], "max_points": 27 }, { "key": "openssf_scorecard_signed_releases", "name": "OpenSSF Scorecard: Signed-Releases", "detail": "no releases found", "points": 0, "status": "excluded", "details": [ { "code": "no_data", "params": {} } ], "max_points": 10 } ] }, { "key": "abandonment", "band": "excellent", "name": "Abandonment", "note": null, "notes": [], "value": 100, "inputs": { "cap": null, "state": "maintained", "guards": [], "signals": [], "red_flag": false, "multiplier_pct": 100, "declared_reason": null, "unverified_reason": null, "unanswered_open_prs": null, "unanswered_open_issues": null, "days_since_last_merged_pr": null, "days_since_last_human_commit": 0, "days_since_last_human_commit_is_floor": false }, "components": [ { "key": "project_is_still_maintained", "name": "Project is still maintained", "detail": "last human commit 0 days ago", "points": 100, "status": "met", "details": [ { "code": "abandonment_maintained", "params": { "days": 0 } } ], "max_points": 100 } ] } ], "description": "Is the project alive — is code being written and are releases shipping?" }, { "key": "community", "band": "moderate", "name": "Community & Adoption", "value": 64, "weight": 0.18, "metrics": [ { "key": "popularity", "band": "moderate", "name": "Popularity & adoption", "note": null, "notes": [], "value": 60, "inputs": { "forks": 32, "stars": 392, "watchers": 13, "growth_state": "unverified", "growth_factor_pct": 100, "growth_unverified_reason": "no_history" }, "components": [ { "key": "stars", "name": "Stars", "detail": "392 stars", "points": 42, "status": "partial", "details": [ { "code": "stars", "params": { "count": 392 } } ], "max_points": 60 }, { "key": "forks", "name": "Forks", "detail": "32 forks", "points": 12.4, "status": "partial", "details": [ { "code": "forks", "params": { "count": 32 } } ], "max_points": 25 }, { "key": "watchers", "name": "Watchers", "detail": "13 watchers", "points": 6, "status": "partial", "details": [ { "code": "watchers", "params": { "count": 13 } } ], "max_points": 15 } ] }, { "key": "community_health", "band": "moderate", "name": "Community health", "note": null, "notes": [], "value": 65, "inputs": { "has_readme": true, "has_license": true, "has_contributing": false, "has_issue_template": false, "has_code_of_conduct": true, "has_pull_request_template": false }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 22.5, "status": "met", "details": [], "max_points": 22.5 }, { "key": "license", "name": "License", "detail": "recognized license (MIT)", "points": 22.5, "status": "met", "details": [ { "code": "license_standard", "params": {} }, { "code": "license_spdx", "params": { "spdx": "MIT" } } ], "max_points": 22.5 }, { "key": "contributing_guide", "name": "CONTRIBUTING guide", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 18 }, { "key": "code_of_conduct", "name": "Code of conduct", "detail": null, "points": 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": 0, "status": "missed", "details": [], "max_points": 6.3 } ] }, { "key": "ecosystem_adoption", "band": "moderate", "name": "Ecosystem adoption (downloads)", "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.", "notes": [ { "code": "excluded_no_data", "params": { "components": [ "registry_dependents" ] } }, { "code": "weights_renormalized", "params": {} } ], "value": 68, "inputs": { "packages": [ "Blazor.DOM", "Blazor.Clipboard", "Blazor.Credentials", "Blazor.Geolocation", "Blazor.LocalStorage", "Blazor.MediaDevices" ], "dependents": null, "ecosystems": "nuget", "total_downloads": 178869, "monthly_downloads": null }, "components": [ { "key": "total_downloads", "name": "Total downloads", "detail": "178,869 downloads all-time across nuget", "points": 54.6, "status": "partial", "details": [ { "code": "downloads_total", "params": { "count": 178869, "ecosystems": "nuget" } } ], "max_points": 80 }, { "key": "registry_dependents", "name": "Registry dependents", "detail": "not reported by this ecosystem", "points": 0, "status": "excluded", "details": [ { "code": "not_reported_by_this_ecosystem", "params": {} } ], "max_points": 20 } ] } ], "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?" }, { "key": "governance", "band": "moderate", "name": "Sustainability & Governance", "value": 66, "weight": 0.24, "metrics": [ { "key": "maintainer_resilience", "band": "critical", "name": "Maintainer resilience (bus factor)", "note": null, "notes": [], "value": 28, "inputs": { "bus_factor": 1, "contributors_sampled": 6, "top_contributor_share": 0.974 }, "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 97% of commits", "points": 0.6, "status": "partial", "details": [ { "code": "top_contributor_share", "params": { "share": 97 } } ], "max_points": 22.5 }, { "key": "contributor_breadth", "name": "Contributor breadth", "detail": "6 contributors", "points": 8.1, "status": "partial", "details": [ { "code": "contributors_sampled", "params": { "count": 6 } } ], "max_points": 13.5 }, { "key": "openssf_scorecard_contributors", "name": "OpenSSF Scorecard: Contributors", "detail": "project has 6 contributing companies or organizations", "points": 10, "status": "met", "details": [], "max_points": 10 } ] }, { "key": "responsiveness", "band": "good", "name": "Issue & PR responsiveness", "note": null, "notes": [], "value": 81, "inputs": { "merged_prs": 28, "open_issues": 0, "closed_issues": 32, "issue_closed_ratio": 1, "closed_unmerged_prs": 3 }, "components": [ { "key": "issue_resolution", "name": "Issue resolution", "detail": "100% of issues closed", "points": 46.8, "status": "met", "details": [ { "code": "issues_closed_share", "params": { "share": 100 } } ], "max_points": 46.75 }, { "key": "pr_acceptance", "name": "PR acceptance", "detail": "28/31 decided PRs merged", "points": 34.5, "status": "partial", "details": [ { "code": "decided_prs_merged", "params": { "merged": 28, "decided": 31 } } ], "max_points": 38.25 }, { "key": "openssf_scorecard_code_review", "name": "OpenSSF Scorecard: Code-Review", "detail": "Found 0/28 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 15 } ] }, { "key": "stewardship", "band": "good", "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": 71, "inputs": { "followers": 1017, "owner_type": "User", "is_verified": null, "owner_login": "IEvangelist", "public_repos": 336, "account_age_days": 4445 }, "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": "1,017 followers of IEvangelist", "points": 21.6, "status": "partial", "details": [ { "code": "owner_followers", "params": { "count": 1017, "login": "IEvangelist" } } ], "max_points": 25 }, { "key": "track_record", "name": "Track record", "detail": "336 public repos, account ~12 yr old", "points": 25, "status": "met", "details": [ { "code": "public_repos", "params": { "count": 336 } }, { "code": "account_age_years", "params": { "years": 12 } } ], "max_points": 25 } ] }, { "key": "package_maintenance", "band": "excellent", "name": "Package maintenance", "note": null, "notes": [], "value": 100, "inputs": { "packages": [ "Blazor.DOM", "Blazor.Clipboard", "Blazor.Credentials", "Blazor.Geolocation", "Blazor.LocalStorage", "Blazor.MediaDevices" ], "ecosystems": "nuget", "any_deprecated": false, "min_days_since_publish": 0 }, "components": [ { "key": "published_resolvable", "name": "Published & resolvable", "detail": "6 package(s) on nuget", "points": 25, "status": "met", "details": [ { "code": "packages_published", "params": { "count": 6, "ecosystems": "nuget" } } ], "max_points": 25 }, { "key": "publish_recency", "name": "Publish recency", "detail": "latest publish 0 days ago", "points": 35, "status": "met", "details": [ { "code": "publish_recency", "params": { "days": 0 } } ], "max_points": 35 }, { "key": "version_history", "name": "Version history", "detail": "19 published versions", "points": 20, "status": "met", "details": [ { "code": "published_versions", "params": { "count": 19 } } ], "max_points": 20 }, { "key": "not_deprecated", "name": "Not deprecated", "detail": "active, not deprecated or yanked", "points": 20, "status": "met", "details": [ { "code": "package_not_deprecated", "params": {} } ], "max_points": 20 } ] } ], "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?" }, { "key": "engineering", "band": "good", "name": "Engineering Quality", "value": 71, "weight": 0.2, "metrics": [ { "key": "engineering_practices", "band": "moderate", "name": "Engineering practices", "note": null, "notes": [], "value": 68, "inputs": { "has_ci": true, "has_tests": true, "has_editorconfig": true, "has_linter_config": false, "has_precommit_config": false }, "components": [ { "key": "ci_workflows", "name": "CI workflows", "detail": "4 workflow(s)", "points": 24, "status": "met", "details": [ { "code": "ci_workflows", "params": { "count": 4 } } ], "max_points": 24 }, { "key": "tests_present", "name": "Tests present", "detail": null, "points": 24, "status": "met", "details": [], "max_points": 24 }, { "key": "linter_config", "name": "Linter config", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 16 }, { "key": "pre_commit_hooks", "name": "Pre-commit hooks", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 9.6 }, { "key": "editorconfig", "name": ".editorconfig", "detail": null, "points": 6.4, "status": "met", "details": [], "max_points": 6.4 }, { "key": "openssf_scorecard_ci_tests", "name": "OpenSSF Scorecard: CI-Tests", "detail": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7", "points": 14, "status": "partial", "details": [], "max_points": 20 } ] }, { "key": "documentation", "band": "good", "name": "Documentation", "note": null, "notes": [], "value": 75, "inputs": { "topics": [ "blazor", "blazor-webassembly", "javascript", "typescript", "javascript-interop", "source-generators", "hacktoberfest" ], "has_wiki": true, "homepage": "https://ievangelist.github.io/blazorators/", "has_readme": true, "has_docs_dir": false, "has_description": true }, "components": [ { "key": "readme", "name": "README", "detail": null, "points": 30, "status": "met", "details": [], "max_points": 30 }, { "key": "documentation_directory", "name": "Documentation directory", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 25 }, { "key": "documentation_homepage_site", "name": "Documentation / homepage site", "detail": "https://ievangelist.github.io/blazorators/", "points": 15, "status": "met", "details": [], "max_points": 15 }, { "key": "repository_description", "name": "Repository description", "detail": null, "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "topics", "name": "Topics", "detail": "7 topics", "points": 10, "status": "met", "details": [ { "code": "topics_count", "params": { "count": 7 } } ], "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": 63, "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": 54, "inputs": { "source": "openssf_scorecard", "checks_evaluated": 16, "scorecard_version": "v5.5.0", "checks_inconclusive": 2, "scorecard_aggregate": 5.4 }, "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": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7", "points": 1.8, "status": "partial", "details": [], "max_points": 2.5 }, { "key": "cii_best_practices", "name": "CII-Best-Practices", "detail": "no effort to earn an OpenSSF best practices badge detected", "points": 0, "status": "missed", "details": [], "max_points": 2.5 }, { "key": "code_review", "name": "Code-Review", "detail": "Found 0/28 approved changesets -- score normalized to 0", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "contributors", "name": "Contributors", "detail": "project has 6 contributing companies or organizations", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "dangerous_workflow", "name": "Dangerous-Workflow", "detail": "no dangerous workflow patterns detected", "points": 10, "status": "met", "details": [], "max_points": 10 }, { "key": "dependency_update_tool", "name": "Dependency-Update-Tool", "detail": "no update tool detected", "points": 0, "status": "missed", "details": [], "max_points": 7.5 }, { "key": "fuzzing", "name": "Fuzzing", "detail": "project is not fuzzed", "points": 0, "status": "missed", "details": [], "max_points": 5 }, { "key": "license", "name": "License", "detail": "license file detected", "points": 2.5, "status": "met", "details": [], "max_points": 2.5 }, { "key": "maintained", "name": "Maintained", "detail": "30 commit(s) and 0 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 1", "points": 0.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": 5, "status": "met", "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, No advisories left outstanding. Remaining weights renormalized. Matched 19 resolved dependencies against OSV; 19 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). 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", "no_advisories_left_outstanding" ] } }, { "code": "weights_renormalized", "params": {} }, { "code": "advisories_scope_repository", "params": { "assessed": 19 } }, { "code": "advisories_unassessed", "params": { "count": 19 } }, { "code": "advisories_repo_graph_caveat", "params": {} }, { "code": "advisories_reachability", "params": {} } ], "value": 100, "inputs": { "source": "osv", "advisories": 2, "affected_packages": 2, "assessed_packages": 19, "unassessed_packages": 19, "affected_by_severity": "high 1, moderate 1", "direct_affected_packages": 0 }, "components": [ { "key": "direct_dependencies_free_of_known_advisories", "name": "Direct dependencies free of known advisories", "detail": "no direct dependency carries a known advisory", "points": 35, "status": "met", "details": [ { "code": "no_direct_advisories", "params": {} } ], "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 carries a publication date", "points": 0, "status": "excluded", "details": [ { "code": "advisories_no_publication_date", "params": {} } ], "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": 19, "malicious_packages": 0, "direct_malicious_packages": 0, "withdrawn_malicious_packages": 0, "installable_malicious_packages": 0 }, "components": [ { "key": "no_dependency_reported_as_a_malicious_package", "name": "No dependency reported as a malicious package", "detail": "no dependency is reported as a malicious package", "points": 100, "status": "met", "details": [ { "code": "no_malicious_dependencies", "params": {} } ], "max_points": 100 } ] }, { "key": "high_risk_jurisdiction_exposure", "band": "excellent", "name": "High-Risk Jurisdiction Exposure", "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.", "notes": [ { "code": "jurisdiction_evidence_limits", "params": {} } ], "value": 100, "inputs": { "meaning": "self-published location evidence; not nationality or citizenship", "red_flag": false, "exposures": [], "policy_countries": [ "Russia", "Iran", "North Korea" ], "review_only_matches": 0, "assessed_self_published_locations": 14 }, "components": [ { "key": "policy_exposure_multiplier", "name": "Policy exposure multiplier", "detail": "no confirmed policy-scope location match", "points": 100, "status": "met", "details": [ { "code": "jurisdiction_no_match", "params": {} } ], "max_points": 100 } ] } ], "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?" }, { "key": "ai_readiness", "band": "moderate", "name": "AI Readiness", "value": 60, "weight": 0, "metrics": [ { "key": "ai_agent_context", "band": "at_risk", "name": "Agent context & guidance", "note": null, "notes": [], "value": 40, "inputs": { "has_llms_txt": false, "legible_history_share": 0.92, "agent_instruction_files": [], "agent_instruction_max_bytes": null }, "components": [ { "key": "agent_instructions", "name": "Agent instructions", "detail": "no CLAUDE.md / AGENTS.md / editor rules", "points": 0, "status": "missed", "details": [ { "code": "no_agent_instructions", "params": {} } ], "max_points": 45 }, { "key": "machine_readable_docs_llms_txt", "name": "Machine-readable docs (llms.txt)", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 15 }, { "key": "legible_commit_history", "name": "Legible commit history", "detail": "92 of 100 human commits state their intent (structured subject or explanatory body)", "points": 40, "status": "met", "details": [ { "code": "legible_history", "params": { "legible": 92, "sampled": 100 } } ], "max_points": 40 } ] }, { "key": "ai_verify_loop", "band": "moderate", "name": "Verify loop (build / test / typecheck)", "note": null, "notes": [], "value": 67, "inputs": { "has_nix": false, "has_tests": true, "lockfiles": [ "package-lock.json" ], "has_dockerfile": false, "typed_language": true, "bootstrap_files": [], "has_devcontainer": false, "has_linter_config": false, "typecheck_configs": [ "tools/Blazor.DOM.TypeScriptModel/tsconfig.json" ], "agent_commit_share": 0.98, "toolchain_manifests": [ "samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj", "samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj", "src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj", "src/Blazor.BrowserCoordination/Blazor.BrowserCoordination.csproj", "src/Blazor.Clipboard.WebAssembly/Blazor.Clipboard.WebAssembly.csproj", "src/Blazor.Clipboard/Blazor.Clipboard.csproj", "src/Blazor.Credentials.WebAssembly/Blazor.Credentials.WebAssembly.csproj", "src/Blazor.Credentials/Blazor.Credentials.csproj", "src/Blazor.DOM.Generation/Blazor.DOM.Generation.csproj", "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj", "src/Blazor.DOM/Blazor.DOM.csproj", "src/Blazor.FileSystemAccess.WebAssembly/Blazor.FileSystemAccess.WebAssembly.csproj", "src/Blazor.FileSystemAccess/Blazor.FileSystemAccess.csproj", "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj", "src/Blazor.Geolocation/Blazor.Geolocation.csproj", "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj", "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj", "src/Blazor.MediaDevices.WebAssembly/Blazor.MediaDevices.WebAssembly.csproj", "src/Blazor.MediaDevices/Blazor.MediaDevices.csproj", "src/Blazor.Notifications.WebAssembly/Blazor.Notifications.WebAssembly.csproj", "src/Blazor.Notifications/Blazor.Notifications.csproj", "src/Blazor.OfflineStorage.WebAssembly/Blazor.OfflineStorage.WebAssembly.csproj", "src/Blazor.OfflineStorage/Blazor.OfflineStorage.csproj", "src/Blazor.Performance.WebAssembly/Blazor.Performance.WebAssembly.csproj", "src/Blazor.Performance/Blazor.Performance.csproj", "src/Blazor.Permissions.WebAssembly/Blazor.Permissions.WebAssembly.csproj", "src/Blazor.Permissions/Blazor.Permissions.csproj", "src/Blazor.Screen.WebAssembly/Blazor.Screen.WebAssembly.csproj", "src/Blazor.Screen/Blazor.Screen.csproj", "src/Blazor.Serialization/Blazor.Serialization.csproj", "src/Blazor.SessionStorage.WebAssembly/Blazor.SessionStorage.WebAssembly.csproj", "src/Blazor.SessionStorage/Blazor.SessionStorage.csproj", "src/Blazor.Share.WebAssembly/Blazor.Share.WebAssembly.csproj", "src/Blazor.Share/Blazor.Share.csproj", "src/Blazor.SourceGenerators/Blazor.SourceGenerators.csproj", "src/Blazor.SpeechRecognition.WebAssembly/Blazor.SpeechRecognition.WebAssembly.csproj", "src/Blazor.SpeechRecognition/Blazor.SpeechRecognition.csproj", "src/Blazor.SpeechSynthesis.WebAssembly/Blazor.SpeechSynthesis.WebAssembly.csproj", "src/Blazor.SpeechSynthesis/Blazor.SpeechSynthesis.csproj", "src/Blazor.StorageManagement.WebAssembly/Blazor.StorageManagement.WebAssembly.csproj", "src/Blazor.StorageManagement/Blazor.StorageManagement.csproj", "src/Blazor.WakeLock.WebAssembly/Blazor.WakeLock.WebAssembly.csproj", "src/Blazor.WakeLock/Blazor.WakeLock.csproj", "src/Blazor.WebCrypto.WebAssembly/Blazor.WebCrypto.WebAssembly.csproj", "src/Blazor.WebCrypto/Blazor.WebCrypto.csproj", "tests/Blazor.BrowserCoordination.Tests/Blazor.BrowserCoordination.Tests.csproj", "tests/Blazor.Clipboard.Tests/Blazor.Clipboard.Tests.csproj", "tests/Blazor.Credentials.Tests/Blazor.Credentials.Tests.csproj", "tests/Blazor.DOM.Accessors.CompilationTests/Blazor.DOM.Accessors.CompilationTests.csproj", "tests/Blazor.DOM.AdvancedTypes.CompilationTests/Blazor.DOM.AdvancedTypes.CompilationTests.csproj", "tests/Blazor.DOM.CSharpGenerator.Tests/Blazor.DOM.CSharpGenerator.Tests.csproj", "tests/Blazor.DOM.Generic.CompilationTests/Blazor.DOM.Generic.CompilationTests.csproj", "tests/Blazor.DOM.GlobalNamespace.CompilationTests/Blazor.DOM.GlobalNamespace.CompilationTests.csproj", "tests/Blazor.DOM.NonEventDeferrals.CompilationTests/Blazor.DOM.NonEventDeferrals.CompilationTests.csproj", "tests/Blazor.DOM.ProfileRuntime/Blazor.DOM.ProfileRuntime.csproj", "tests/Blazor.DOM.ResolvedFailures.CompilationTests/Blazor.DOM.ResolvedFailures.CompilationTests.csproj", "tests/Blazor.DOM.Server.CompilationTests/Blazor.DOM.Server.CompilationTests.csproj", "tests/Blazor.DOM.SupplementalBrowserApis.CompilationTests/Blazor.DOM.SupplementalBrowserApis.CompilationTests.csproj", "tests/Blazor.DOM.Tests/Blazor.DOM.Tests.csproj", "tests/Blazor.DOM.TypedEvents.CompilationTests/Blazor.DOM.TypedEvents.CompilationTests.csproj", "tests/Blazor.DOM.TypedUnions.CompilationTests/Blazor.DOM.TypedUnions.CompilationTests.csproj", "tests/Blazor.DOM.WakeLock.CompilationTests/Blazor.DOM.WakeLock.CompilationTests.csproj", "tests/Blazor.DOM.WebAssembly.CompilationTests/Blazor.DOM.WebAssembly.CompilationTests.csproj", "tests/Blazor.ExampleConsumer.EndToEndTests/Blazor.ExampleConsumer.EndToEndTests.csproj", "tests/Blazor.FileSystemAccess.Tests/Blazor.FileSystemAccess.Tests.csproj", "tests/Blazor.OfflineStorage.Tests/Blazor.OfflineStorage.Tests.csproj", "tests/Blazor.Performance.Tests/Blazor.Performance.Tests.csproj", "tests/Blazor.Screen.Tests/Blazor.Screen.Tests.csproj", "tests/Blazor.Share.Tests/Blazor.Share.Tests.csproj", "tests/Blazor.SourceGenerators.Tests/Blazor.SourceGenerators.Tests.csproj", "tests/Blazor.StorageManagement.Tests/Blazor.StorageManagement.Tests.csproj", "tests/Blazor.WakeLock.Tests/Blazor.WakeLock.Tests.csproj", "tests/Blazor.WebCrypto.Tests/Blazor.WebCrypto.Tests.csproj", "tools/Blazor.DOM.CSharpGenerator/Blazor.DOM.CSharpGenerator.csproj" ], "dependency_bot_commit_share": 0 }, "components": [ { "key": "one_command_bootstrap", "name": "One-command bootstrap", "detail": "samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj, samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj, src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj (toolchain convention, no task runner)", "points": 12.6, "status": "partial", "details": [ { "code": "toolchain_convention", "params": { "files": "samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj, samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj, src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj" } } ], "max_points": 18 }, { "key": "automated_tests", "name": "Automated tests", "detail": null, "points": 22, "status": "met", "details": [], "max_points": 22 }, { "key": "lint_format_config", "name": "Lint / format config", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 11 }, { "key": "static_type_checking", "name": "Static type checking", "detail": "tools/Blazor.DOM.TypeScriptModel/tsconfig.json", "points": 11, "status": "met", "details": [ { "code": "file_list", "params": { "files": "tools/Blazor.DOM.TypeScriptModel/tsconfig.json" } } ], "max_points": 11 }, { "key": "reproducible_environment", "name": "Reproducible environment", "detail": "lockfile", "points": 10, "status": "met", "details": [ { "code": "file_list", "params": { "files": "lockfile" } } ], "max_points": 10 }, { "key": "demonstrated_agent_practice", "name": "Demonstrated agent practice", "detail": "98 of the last 100 commits agent-authored or agent-credited", "points": 10, "status": "met", "details": [ { "code": "agent_authored_commits", "params": { "count": 98, "sampled": 100 } } ], "max_points": 10 }, { "key": "automated_maintenance", "name": "Automated maintenance", "detail": "no automated dependency updates observed", "points": 0, "status": "missed", "details": [ { "code": "no_dependency_automation", "params": {} } ], "max_points": 8 }, { "key": "openssf_scorecard_pinned_dependencies", "name": "OpenSSF Scorecard: Pinned-Dependencies", "detail": "dependency not pinned by hash detected -- score normalized to 1", "points": 1, "status": "partial", "details": [], "max_points": 10 } ] }, { "key": "ai_code_legibility", "band": "excellent", "name": "Code legibility for models", "note": null, "notes": [], "value": 99, "inputs": { "primary_language": "C#", "largest_source_bytes": 816786, "source_files_sampled": 429, "oversized_source_files": 7 }, "components": [ { "key": "type_checkable_code", "name": "Type-checkable code", "detail": "C# (statically typed)", "points": 45, "status": "met", "details": [ { "code": "statically_typed_language", "params": { "language": "C#" } } ], "max_points": 45 }, { "key": "manageable_file_sizes", "name": "Manageable file sizes", "detail": "7/429 source files over 60KB", "points": 54.1, "status": "partial", "details": [ { "code": "oversized_source_files", "params": { "kb": 60, "sampled": 429, "oversized": 7 } } ], "max_points": 55 } ] }, { "key": "ai_interfaces", "band": "at_risk", "name": "Machine-readable interfaces", "note": null, "notes": [], "value": 40, "inputs": { "example_dirs": [ "samples" ], "has_mcp_signal": false, "api_schema_files": [] }, "components": [ { "key": "api_schema_openapi_graphql_proto", "name": "API schema (OpenAPI/GraphQL/proto)", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 40 }, { "key": "mcp_server", "name": "MCP server", "detail": null, "points": 0, "status": "missed", "details": [], "max_points": 20 }, { "key": "runnable_examples", "name": "Runnable examples", "detail": "samples", "points": 40, "status": "met", "details": [ { "code": "file_list", "params": { "files": "samples" } } ], "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", "nuget package 'Blazor.Notifications' points at a different repository (https://github.com/vertonghenb/Blazor.Notifications); excluded from ecosystem scoring", "Could not fetch nuget package 'Blazor.DOM.WebAssembly' from its registry" ], "report_type": "repository", "generated_at": "2026-07-24T19:02:09.211042Z", "schema_version": "0.27.0", "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/IEvangelist/blazorators.svg", "full_name": "IEvangelist/blazorators", "license_state": "standard", "license_spdx": "MIT" }, "repoMeta": null, "notFound": false, "related": [ { "id": 18382, "full_name": "unoplatform/uno", "url": "https://github.com/unoplatform/uno", "description": "Open-source platform for building cross-platform native Mobile, Web, Desktop, and Embedded apps from a single C#/XAML codebase. Work from any IDE/CLI with Hot Reload, Visual Designer, MCPs, and Skills built for modern .NET workflows. 200M+ NuGet downloads.", "ecosystem": "npm", "ecosystems": [ "npm", "nuget" ], "primary_language": "C#", "languages": [ "C#" ], "topics": [ "uno", "uwp", "android", "uno-platform", "roslyn", "xamarin", "webassembly", "windows", "mvvm", "wasm", "mono", "xaml", "cross-platform", "csharp", "macos", "c-sharp", "winui", "linux", "dotnet", "hacktoberfest" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 9982, "forks": 868, "watchers": 188, "monthly_downloads": null, "latest_score": 84, "latest_band": "good", "latest_scanned_at": "2026-07-17T20:26:20.591766Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 8520, "full_name": "pulumi/coconut", "url": "https://github.com/pulumi/coconut", "description": "Pulumi - Infrastructure as Code in any programming language 🚀", "ecosystem": "go", "ecosystems": [ "go", "npm", "pypi" ], "primary_language": "Go", "languages": [ "Go" ], "topics": [ "infrastructure-as-code", "serverless", "containers", "aws", "azure", "gcp", "kubernetes", "cloud", "cloud-computing", "iac", "csharp", "typescript", "javascript", "golang", "go", "dotnet", "fsharp", "python" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 25446, "forks": 1400, "watchers": 190, "monthly_downloads": null, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-16T00:04:24.854453Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 8526, "full_name": "pulumi/pulumi-fabric", "url": "https://github.com/pulumi/pulumi-fabric", "description": "Pulumi - Infrastructure as Code in any programming language 🚀", "ecosystem": "go", "ecosystems": [ "go", "npm", "pypi" ], "primary_language": "Go", "languages": [ "Go" ], "topics": [ "infrastructure-as-code", "serverless", "containers", "aws", "azure", "gcp", "kubernetes", "cloud", "cloud-computing", "iac", "csharp", "typescript", "javascript", "golang", "go", "dotnet", "fsharp", "python" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 25446, "forks": 1400, "watchers": 190, "monthly_downloads": null, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-16T00:05:04.618338Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 8521, "full_name": "pulumi/lumi", "url": "https://github.com/pulumi/lumi", "description": "Pulumi - Infrastructure as Code in any programming language 🚀", "ecosystem": "go", "ecosystems": [ "go", "npm", "pypi" ], "primary_language": "Go", "languages": [ "Go" ], "topics": [ "infrastructure-as-code", "serverless", "containers", "aws", "azure", "gcp", "kubernetes", "cloud", "cloud-computing", "iac", "csharp", "typescript", "javascript", "golang", "go", "dotnet", "fsharp", "python" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 25446, "forks": 1400, "watchers": 190, "monthly_downloads": null, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-16T00:04:26.631408Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 8508, "full_name": "marapongo/mu", "url": "https://github.com/marapongo/mu", "description": "Pulumi - Infrastructure as Code in any programming language 🚀", "ecosystem": "go", "ecosystems": [ "go", "npm", "pypi" ], "primary_language": "Go", "languages": [ "Go" ], "topics": [ "infrastructure-as-code", "serverless", "containers", "aws", "azure", "gcp", "kubernetes", "cloud", "cloud-computing", "iac", "csharp", "typescript", "javascript", "golang", "go", "dotnet", "fsharp", "python" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 25446, "forks": 1400, "watchers": 190, "monthly_downloads": null, "latest_score": 88, "latest_band": "excellent", "latest_scanned_at": "2026-07-16T00:03:47.348908Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" }, { "id": 13240, "full_name": "Pulumi/pulumi", "url": "https://github.com/Pulumi/pulumi", "description": "Pulumi - Infrastructure as Code in any programming language 🚀", "ecosystem": "npm", "ecosystems": [ "npm", "go", "pypi" ], "primary_language": "Go", "languages": [ "Go" ], "topics": [ "infrastructure-as-code", "serverless", "containers", "aws", "azure", "gcp", "kubernetes", "cloud", "cloud-computing", "iac", "csharp", "typescript", "javascript", "golang", "go", "dotnet", "fsharp", "python" ], "license_spdx": "Apache-2.0", "license_state": "standard", "stars": 25448, "forks": 1402, "watchers": 190, "monthly_downloads": 22181, "latest_score": 87, "latest_band": "excellent", "latest_scanned_at": "2026-07-17T06:52:58.753694Z", "has_high_risk_jurisdiction_exposure": false, "has_malicious_dependency": false, "growth_authenticity": "unverified", "abandonment_state": "unverified", "red_flags": [], "badge_url": "" } ] } }
This project converts TypeScript type declarations into C# representations, and use C# source generators to expose automatic JavaScript interop functionality.
IEvangelist/blazorators erreicht einen Gesundheitsindex von 68 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Vitality (74/100) ab, am schwächsten bei AI Readiness (60/100). Zuletzt heute aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.
Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.
Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.
Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.
| Registry | Paket | Version | Downloads / Monat | Versionen | Zuletzt veröffentlicht | Tags |
|---|---|---|---|---|---|---|
| NuGet | Blazor.DOM | 10.1.0 | - | 1 | vor 0 Tagen | dotnetdotnetcorecsharpblazorserverdominteropjsinterop |
| NuGet | Blazor.Clipboard | 10.1.0 | - | 1 | vor 0 Tagen | dotnetblazorserverdominteropclipboard |
| NuGet | Blazor.Credentials | 10.1.0 | - | 1 | vor 0 Tagen | dotnetblazorserverdominteropcredentialswebauthn |
| NuGet | Blazor.Geolocation | 10.1.0 | - | 19 | vor 0 Tagen | dotnetdotnetcorecsharpblazorserverwasmgeneratorssourcegenroslyn |
| NuGet | Blazor.LocalStorage | 10.1.0 | - | 19 | vor 0 Tagen | dotnetdotnetcorecsharpblazorgeneratorssourcegenroslyn |
| NuGet | Blazor.MediaDevices | 10.1.0 | - | 1 | vor 0 Tagen | dotnetblazorserverdominteropmedia-devicesget-user-mediadisplay-capture |
| NuGet | Blazor.Notificationsverweist auf ein anderes Repo — nicht bewertet | 0.2.0 | - | 2 | vor 2956 Tagen | blazornotificationsc#standardcore |
Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?
| 36/36 | Push-Aktualität — letzter Push vor 0 Tagen |
| 3.5/36 | Commit-Rhythmus — 5/52 Wochen mit Commits |
| 18/18 | Commit-Volumen — 124 Commits im letzten Jahr |
| 10/10 | OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10 |
| commits_last_year | 124 |
| human_commit_share | 1 |
| days_since_last_push | 0 |
| active_weeks_last_year | 5 |
| 27/27 | Liefert Releases aus — 43 Releases veröffentlicht |
| 36/36 | Release-Aktualität — letztes Release vor 0 Tagen |
| 12.6/27 | Release-Rhythmus — ein Release etwa alle 142 Tage |
| 0/10 | OpenSSF Scorecard: Signed-Releases — keine Daten |
| releases_count | 43 |
| latest_release_tag | 10.1.0 |
| releases_from_tags | nein |
| days_since_latest_release | 0 |
| mean_days_between_releases | 142 |
Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?
| 42/60 | Stars — 392 Stars |
| 12.4/25 | Forks — 32 Forks |
| 6/15 | Watcher — 13 Watcher |
| forks | 32 |
| stars | 392 |
| watchers | 13 |
| growth_state | unverified |
| growth_factor_pct | 100 |
| growth_unverified_reason | no_history |
| 22.5/22.5 | README |
| 22.5/22.5 | Lizenz — anerkannte Lizenz (MIT) |
| 0/18 | CONTRIBUTING-Leitfaden |
| 13.5/13.5 | Verhaltenskodex |
| 0/7.2 | Issue-Vorlage |
| 0/6.3 | PR-Vorlage |
| has_readme | ja |
| has_license | ja |
| has_contributing | nein |
| has_issue_template | nein |
| has_code_of_conduct | ja |
| has_pull_request_template | nein |
| 54.6/80 | Downloads gesamt — 178.869 Downloads insgesamt über nuget |
| 0/20 | Abhängige in der Registry — von diesem Ökosystem nicht ausgewiesen |
| packages | Blazor.DOM, Blazor.Clipboard, Blazor.Credentials, Blazor.Geolocation, Blazor.LocalStorage, Blazor.MediaDevices |
| dependents | — |
| ecosystems | nuget |
| total_downloads | 178.869 |
| monthly_downloads | — |
Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?
| 9/54 | Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab |
| 0.6/22.5 | Commit-Verteilung — wichtigste beitragende Person verfasste 97 % der Commits |
| 8.1/13.5 | Breite der Beitragenden — 6 Beitragende |
| 10/10 | OpenSSF Scorecard: Contributors — project has 6 contributing companies or organizations |
| bus_factor | 1 |
| contributors_sampled | 6 |
| top_contributor_share | 0,974 |
| 46.8/46.8 | Issue-Lösungsquote — 100 % der Issues geschlossen |
| 34.5/38.3 | PR-Annahme — 28/31 entschiedene PRs gemergt |
| 0/15 | OpenSSF Scorecard: Code-Review — Found 0/28 approved changesets -- score normalized to 0 |
| merged_prs | 28 |
| open_issues | 0 |
| closed_issues | 32 |
| issue_closed_ratio | 1 |
| closed_unmerged_prs | 3 |
| 10/30 | Organisatorische Trägerschaft — persönliches (Nutzer-)Konto |
| 0/20 | Verifizierte Domain — für Nutzerkonten nicht anwendbar |
| 21.6/25 | Reichweite des Inhabers — 1.017 Follower von IEvangelist |
| 25/25 | Kontohistorie — 336 öffentliche Repos, Kontoalter ca. 12 Jahre |
| followers | 1.017 |
| owner_type | User |
| is_verified | — |
| owner_login | IEvangelist |
| public_repos | 336 |
| account_age_days | 4.445 |
| 25/25 | Veröffentlicht & auflösbar — 6 Paket(e) auf nuget |
| 35/35 | Veröffentlichungsaktualität — letzte Veröffentlichung vor 0 Tagen |
| 20/20 | Versionshistorie — 19 veröffentlichte Versionen |
| 20/20 | Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen |
| packages | Blazor.DOM, Blazor.Clipboard, Blazor.Credentials, Blazor.Geolocation, Blazor.LocalStorage, Blazor.MediaDevices |
| ecosystems | nuget |
| any_deprecated | nein |
| min_days_since_publish | 0 |
Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?
| 24/24 | CI-Workflows — 4 Workflow(s) |
| 24/24 | Tests vorhanden |
| 0/16 | Linter-Konfiguration |
| 0/9.6 | Pre-Commit-Hooks |
| 6.4/6.4 | .editorconfig |
| 14/20 | OpenSSF Scorecard: CI-Tests — 3 out of 4 merged PRs checked by a CI test -- score normalized to 7 |
| has_ci | ja |
| has_tests | ja |
| has_editorconfig | ja |
| has_linter_config | nein |
| has_precommit_config | nein |
| 30/30 | README |
| 0/25 | Dokumentationsverzeichnis |
| 15/15 | Dokumentations-/Homepage-Site — https://ievangelist.github.io/blazorators/ |
| 10/10 | Repository-Beschreibung |
| 10/10 | Topics — 7 Topics |
| 10/10 | Wiki |
| topics | blazor, blazor-webassembly, javascript, typescript, javascript-interop, source-generators, hacktoberfest |
| has_wiki | ja |
| homepage | https://ievangelist.github.io/blazorators/ |
| has_readme | ja |
| has_docs_dir | nein |
| has_description | ja |
Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?
| 7.5/7.5 | Binary-Artifacts — no binaries found in the repo |
| 0/7.5 | Branch-Protection — keine Daten |
| 1.8/2.5 | CI-Tests — 3 out of 4 merged PRs checked by a CI test -- score normalized to 7 |
| 0/2.5 | CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected |
| 0/7.5 | Code-Review — Found 0/28 approved changesets -- score normalized to 0 |
| 2.5/2.5 | Contributors — project has 6 contributing companies or organizations |
| 10/10 | Dangerous-Workflow — no dangerous workflow patterns detected |
| 0/7.5 | Dependency-Update-Tool — no update tool detected |
| 0/5 | Fuzzing — project is not fuzzed |
| 2.5/2.5 | Lizenz — license file detected |
| 7.5/7.5 | Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10 |
| 5/5 | Packaging — packaging workflow detected |
| 0.5/5 | Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1 |
| 0/5 | SAST — SAST tool is not run on all commits -- score normalized to 0 |
| 5/5 | Security-Policy — security policy file detected |
| 0/7.5 | Signed-Releases — keine Daten |
| 0/7.5 | Token-Permissions — detected GitHub workflow tokens with excessive permissions |
| 6/7.5 | Vulnerabilities — 2 existing vulnerabilities detected |
| source | openssf_scorecard |
| checks_evaluated | 16 |
| scorecard_version | v5.5.0 |
| checks_inconclusive | 2 |
| scorecard_aggregate | 5,4 |
| 35/35 | Direkte Abhängigkeiten ohne bekannte Advisories — keine direkte Abhängigkeit trägt ein bekanntes Advisory |
| 0/25 | Indirekte Abhängigkeiten ohne bekannte Advisories — transitive Menge in diesem Bereich nicht von Entwicklungs- und Test-Abhängigkeiten trennbar |
| 0/40 | Keine offenen Advisories — kein Advisory trägt ein Veröffentlichungsdatum |
| source | osv |
| advisories | 2 |
| affected_packages | 2 |
| assessed_packages | 19 |
| unassessed_packages | 19 |
| affected_by_severity | high 1, moderate 1 |
| direct_affected_packages | 0 |
Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.
| 0/45 | Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln |
| 0/15 | Maschinenlesbare Doku (llms.txt) |
| 40/40 | Lesbare Commit-Historie — 92 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text) |
| has_llms_txt | nein |
| legible_history_share | 0,92 |
| agent_instruction_files | — |
| agent_instruction_max_bytes | — |
| 12.6/18 | Bootstrap mit einem Befehl — samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj, samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj, src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj (Toolchain-Konvention, kein Task-Runner) |
| 22/22 | Automatisierte Tests |
| 0/11 | Lint-/Format-Konfiguration |
| 11/11 | Statische Typprüfung — tools/Blazor.DOM.TypeScriptModel/tsconfig.json |
| 10/10 | Reproduzierbare Umgebung — lockfile |
| 10/10 | Belegte Agentenpraxis — 98 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben |
| 0/8 | Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet |
| 1/10 | OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 1 |
| has_nix | nein |
| has_tests | ja |
| lockfiles | package-lock.json |
| has_dockerfile | nein |
| typed_language | ja |
| bootstrap_files | — |
| has_devcontainer | nein |
| has_linter_config | nein |
| typecheck_configs | tools/Blazor.DOM.TypeScriptModel/tsconfig.json |
| agent_commit_share | 0,98 |
| toolchain_manifests | samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj, samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj, src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj, src/Blazor.BrowserCoordination/Blazor.BrowserCoordination.csproj, src/Blazor.Clipboard.WebAssembly/Blazor.Clipboard.WebAssembly.csproj, src/Blazor.Clipboard/Blazor.Clipboard.csproj, src/Blazor.Credentials.WebAssembly/Blazor.Credentials.WebAssembly.csproj, src/Blazor.Credentials/Blazor.Credentials.csproj, src/Blazor.DOM.Generation/Blazor.DOM.Generation.csproj, src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj, src/Blazor.DOM/Blazor.DOM.csproj, src/Blazor.FileSystemAccess.WebAssembly/Blazor.FileSystemAccess.WebAssembly.csproj, src/Blazor.FileSystemAccess/Blazor.FileSystemAccess.csproj, src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj, src/Blazor.Geolocation/Blazor.Geolocation.csproj, src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj, src/Blazor.LocalStorage/Blazor.LocalStorage.csproj, src/Blazor.MediaDevices.WebAssembly/Blazor.MediaDevices.WebAssembly.csproj, src/Blazor.MediaDevices/Blazor.MediaDevices.csproj, src/Blazor.Notifications.WebAssembly/Blazor.Notifications.WebAssembly.csproj, src/Blazor.Notifications/Blazor.Notifications.csproj, src/Blazor.OfflineStorage.WebAssembly/Blazor.OfflineStorage.WebAssembly.csproj, src/Blazor.OfflineStorage/Blazor.OfflineStorage.csproj, src/Blazor.Performance.WebAssembly/Blazor.Performance.WebAssembly.csproj, src/Blazor.Performance/Blazor.Performance.csproj, src/Blazor.Permissions.WebAssembly/Blazor.Permissions.WebAssembly.csproj, src/Blazor.Permissions/Blazor.Permissions.csproj, src/Blazor.Screen.WebAssembly/Blazor.Screen.WebAssembly.csproj, src/Blazor.Screen/Blazor.Screen.csproj, src/Blazor.Serialization/Blazor.Serialization.csproj, src/Blazor.SessionStorage.WebAssembly/Blazor.SessionStorage.WebAssembly.csproj, src/Blazor.SessionStorage/Blazor.SessionStorage.csproj, src/Blazor.Share.WebAssembly/Blazor.Share.WebAssembly.csproj, src/Blazor.Share/Blazor.Share.csproj, src/Blazor.SourceGenerators/Blazor.SourceGenerators.csproj, src/Blazor.SpeechRecognition.WebAssembly/Blazor.SpeechRecognition.WebAssembly.csproj, src/Blazor.SpeechRecognition/Blazor.SpeechRecognition.csproj, src/Blazor.SpeechSynthesis.WebAssembly/Blazor.SpeechSynthesis.WebAssembly.csproj, src/Blazor.SpeechSynthesis/Blazor.SpeechSynthesis.csproj, src/Blazor.StorageManagement.WebAssembly/Blazor.StorageManagement.WebAssembly.csproj, src/Blazor.StorageManagement/Blazor.StorageManagement.csproj, src/Blazor.WakeLock.WebAssembly/Blazor.WakeLock.WebAssembly.csproj, src/Blazor.WakeLock/Blazor.WakeLock.csproj, src/Blazor.WebCrypto.WebAssembly/Blazor.WebCrypto.WebAssembly.csproj, src/Blazor.WebCrypto/Blazor.WebCrypto.csproj, tests/Blazor.BrowserCoordination.Tests/Blazor.BrowserCoordination.Tests.csproj, tests/Blazor.Clipboard.Tests/Blazor.Clipboard.Tests.csproj, tests/Blazor.Credentials.Tests/Blazor.Credentials.Tests.csproj, tests/Blazor.DOM.Accessors.CompilationTests/Blazor.DOM.Accessors.CompilationTests.csproj, tests/Blazor.DOM.AdvancedTypes.CompilationTests/Blazor.DOM.AdvancedTypes.CompilationTests.csproj, tests/Blazor.DOM.CSharpGenerator.Tests/Blazor.DOM.CSharpGenerator.Tests.csproj, tests/Blazor.DOM.Generic.CompilationTests/Blazor.DOM.Generic.CompilationTests.csproj, tests/Blazor.DOM.GlobalNamespace.CompilationTests/Blazor.DOM.GlobalNamespace.CompilationTests.csproj, tests/Blazor.DOM.NonEventDeferrals.CompilationTests/Blazor.DOM.NonEventDeferrals.CompilationTests.csproj, tests/Blazor.DOM.ProfileRuntime/Blazor.DOM.ProfileRuntime.csproj, tests/Blazor.DOM.ResolvedFailures.CompilationTests/Blazor.DOM.ResolvedFailures.CompilationTests.csproj, tests/Blazor.DOM.Server.CompilationTests/Blazor.DOM.Server.CompilationTests.csproj, tests/Blazor.DOM.SupplementalBrowserApis.CompilationTests/Blazor.DOM.SupplementalBrowserApis.CompilationTests.csproj, tests/Blazor.DOM.Tests/Blazor.DOM.Tests.csproj, tests/Blazor.DOM.TypedEvents.CompilationTests/Blazor.DOM.TypedEvents.CompilationTests.csproj, tests/Blazor.DOM.TypedUnions.CompilationTests/Blazor.DOM.TypedUnions.CompilationTests.csproj, tests/Blazor.DOM.WakeLock.CompilationTests/Blazor.DOM.WakeLock.CompilationTests.csproj, tests/Blazor.DOM.WebAssembly.CompilationTests/Blazor.DOM.WebAssembly.CompilationTests.csproj, tests/Blazor.ExampleConsumer.EndToEndTests/Blazor.ExampleConsumer.EndToEndTests.csproj, tests/Blazor.FileSystemAccess.Tests/Blazor.FileSystemAccess.Tests.csproj, tests/Blazor.OfflineStorage.Tests/Blazor.OfflineStorage.Tests.csproj, tests/Blazor.Performance.Tests/Blazor.Performance.Tests.csproj, tests/Blazor.Screen.Tests/Blazor.Screen.Tests.csproj, tests/Blazor.Share.Tests/Blazor.Share.Tests.csproj, tests/Blazor.SourceGenerators.Tests/Blazor.SourceGenerators.Tests.csproj, tests/Blazor.StorageManagement.Tests/Blazor.StorageManagement.Tests.csproj, tests/Blazor.WakeLock.Tests/Blazor.WakeLock.Tests.csproj, tests/Blazor.WebCrypto.Tests/Blazor.WebCrypto.Tests.csproj, tools/Blazor.DOM.CSharpGenerator/Blazor.DOM.CSharpGenerator.csproj |
| dependency_bot_commit_share | 0 |
| 45/45 | Typprüfbarer Code — C# (statisch typisiert) |
| 54.1/55 | Handhabbare Dateigrößen — 7/429 Quelldateien über 60 KB |
| primary_language | C# |
| largest_source_bytes | 816.786 |
| source_files_sampled | 429 |
| oversized_source_files | 7 |
| 0/40 | API-Schema (OpenAPI/GraphQL/proto) |
| 0/20 | MCP-Server |
| 40/40 | Lauffähige Beispiele — samples |
| example_dirs | samples |
| has_mcp_signal | nein |
| api_schema_files | — |
Wann jeder Stern und Fork hinzugefügt wurde, von GitHub erfasst und nach Tagen gruppiert. Das kumulierte Wachstum steht direkt über den täglichen Zugängen, aus denen es besteht, sodass beide gegeneinander lesbar sind: stetiger organischer Zuwachs sieht ganz anders aus als ein abrupter, kurzlebiger Ausschlag. Wo dieser Unterschied messbar ist, wird er als Wachstumsauthentizität ausgewiesen.
Jeder Punkt umfasst 4 Tage.
Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).
| 10 | Binary-Artifacts | no binaries found in the repo |
| k. A. | Branch-Protection | 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 |
| 7 | CI-Tests | 3 out of 4 merged PRs checked by a CI test -- score normalized to 7 |
| 0 | CII-Best-Practices | no effort to earn an OpenSSF best practices badge detected |
| 0 | Code-Review | Found 0/28 approved changesets -- score normalized to 0 |
| 10 | Contributors | project has 6 contributing companies or organizations |
| 10 | Dangerous-Workflow | no dangerous workflow patterns detected |
| 0 | Dependency-Update-Tool | no update tool detected |
| 0 | Fuzzing | project is not fuzzed |
| 10 | License | license file detected |
| 10 | Maintained | 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10 |
| 10 | Packaging | packaging workflow detected |
| 1 | Pinned-Dependencies | dependency not pinned by hash detected -- score normalized to 1 |
| 0 | SAST | SAST tool is not run on all commits -- score normalized to 0 |
| 10 | Security-Policy | security policy file detected |
| k. A. | Signed-Releases | no releases found |
| 0 | Token-Permissions | detected GitHub workflow tokens with excessive permissions |
| 8 | Vulnerabilities | 2 existing vulnerabilities detected |
| Registry | Paket | Versionsvorgabe | Manifest |
|---|---|---|---|
| NuGet | Microsoft.SourceLink.GitHub | — | src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj |
| NuGet | MinVer | — | src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj |
| NuGet | Microsoft.AspNetCore.Components.WebAssembly | — | src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj |
| NuGet | Microsoft.Extensions.DependencyInjection | — | src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj |
| NuGet | Microsoft.SourceLink.GitHub | — | src/Blazor.DOM/Blazor.DOM.csproj |
| NuGet | MinVer | — | src/Blazor.DOM/Blazor.DOM.csproj |
| NuGet | Microsoft.AspNetCore.Components.Web | — | src/Blazor.DOM/Blazor.DOM.csproj |
| NuGet | Microsoft.Extensions.DependencyInjection | — | src/Blazor.DOM/Blazor.DOM.csproj |
| NuGet | Microsoft.JSInterop | — | src/Blazor.DOM/Blazor.DOM.csproj |
| NuGet | Microsoft.SourceLink.GitHub | — | src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj |
| NuGet | MinVer | — | src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj |
| NuGet | Microsoft.AspNetCore.Components.Web | — | src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj |
| NuGet | Microsoft.SourceLink.GitHub | — | src/Blazor.Geolocation/Blazor.Geolocation.csproj |
| NuGet | MinVer | — | src/Blazor.Geolocation/Blazor.Geolocation.csproj |
| NuGet | Microsoft.AspNetCore.Components.Web | — | src/Blazor.Geolocation/Blazor.Geolocation.csproj |
| NuGet | Microsoft.SourceLink.GitHub | — | src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj |
| NuGet | MinVer | — | src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj |
| NuGet | Microsoft.Extensions.DependencyInjection | — | src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj |
| NuGet | Microsoft.Extensions.Primitives | — | src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj |
| NuGet | Microsoft.JSInterop | — | src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj |
| NuGet | Microsoft.SourceLink.GitHub | — | src/Blazor.LocalStorage/Blazor.LocalStorage.csproj |
| NuGet | MinVer | — | src/Blazor.LocalStorage/Blazor.LocalStorage.csproj |
| NuGet | Microsoft.Extensions.DependencyInjection | — | src/Blazor.LocalStorage/Blazor.LocalStorage.csproj |
| NuGet | Microsoft.Extensions.Primitives | — | src/Blazor.LocalStorage/Blazor.LocalStorage.csproj |
| NuGet | Microsoft.JSInterop | — | src/Blazor.LocalStorage/Blazor.LocalStorage.csproj |
Vollständig aufgelöster Abhängigkeitssatz aus dem GitHub-Abhängigkeitsgraphen: 7 direkte und 31 indirekte (transitive) Pakete. Die transitive Hülle ist vollständig, wenn das Repository eine Lockfile eincheckt.
| Registry | Paket | Version | Beziehung |
|---|---|---|---|
| NuGet | Microsoft.AspNetCore.Components.Web | — | direkt |
| NuGet | Microsoft.AspNetCore.Components.WebAssembly | — | direkt |
| NuGet | Microsoft.Extensions.DependencyInjection | — | direkt |
| NuGet | Microsoft.Extensions.Primitives | — | direkt |
| NuGet | Microsoft.JSInterop | — | direkt |
| NuGet | Microsoft.SourceLink.GitHub | — | direkt |
| NuGet | MinVer | — | direkt |
| npm | @pagefind/darwin-arm64 | 1.5.0 | indirekt |
| npm | @pagefind/darwin-x64 | 1.5.0 | indirekt |
| npm | @pagefind/freebsd-x64 | 1.5.0 | indirekt |
| npm | @pagefind/linux-arm64 | 1.5.0 | indirekt |
| npm | @pagefind/linux-x64 | 1.5.0 | indirekt |
| npm | @pagefind/windows-arm64 | 1.5.0 | indirekt |
| npm | @pagefind/windows-x64 | 1.5.0 | indirekt |
| npm | @types/node | 26.1.1 | indirekt |
| npm | @webgpu/types | 0.1.71 | indirekt |
| npm | @webref/idl | 3.81.3 | indirekt |
| npm | ajv | 8.17.1 | indirekt |
| npm | fast-deep-equal | 3.1.3 | indirekt |
| npm | fast-uri | 3.1.3 | indirekt |
| npm | json-schema-traverse | 1.0.0 | indirekt |
| npm | pagefind | 1.5.0 | indirekt |
| npm | require-from-string | 2.0.2 | indirekt |
| npm | typescript | 5.9.3 | indirekt |
| npm | undici-types | 8.3.0 | indirekt |
| npm | webidl2 | 24.5.0 | indirekt |
| NuGet | Basic.Reference.Assemblies | — | indirekt |
| NuGet | coverlet.collector | — | indirekt |
| NuGet | Deque.AxeCore.Playwright | — | indirekt |
| NuGet | Humanizer.Core | — | indirekt |
| NuGet | Microsoft.AspNetCore.Components.WebAssembly.DevServer | — | indirekt |
| NuGet | Microsoft.CodeAnalysis.Analyzers | — | indirekt |
| NuGet | Microsoft.CodeAnalysis.CSharp | — | indirekt |
| NuGet | Microsoft.NET.Test.Sdk | — | indirekt |
| NuGet | Microsoft.Playwright | — | indirekt |
| NuGet | System.Reactive.Linq | — | indirekt |
| NuGet | xunit | — | indirekt |
| NuGet | xunit.runner.visualstudio | — | indirekt |
Dieses Repository veröffentlicht kein vom Index auflösbares Paket, daher wurde sein eigener Abhängigkeitsgraph bewertet – 19 Pakete, darunter auch Entwicklungs- und Test-Pins, die nie ausgeliefert werden: 2 tragen bekannte Advisories, davon 0 direkte. 19 konnten nicht bewertet werden – keine aufgelöste Version, ein nicht unterstütztes Ökosystem, oder außerhalb der ausgewiesenen Paketliste.
| Paket | Version | Beziehung | Schweregrad | Advisories | Behoben in |
|---|---|---|---|---|---|
| fast-uri | 3.1.3 | indirekt | hoch | 1 | 4.1.1 |
| ajv | 8.17.1 | indirekt | mittel | 1 | 8.18.0 |
Ein Advisory bedeutet, dass die im Abhängigkeitsgraphen erfasste Version in den betroffenen Bereich eines Advisories fällt. Erreichbarkeit wird nicht analysiert, und der Graph enthält Entwicklungs- und Test-Pins — ein Fund kann das Werkzeug betreffen und nicht die ausgelieferte Software.
{
"data": {
"repo": {
"topics": [
"blazor",
"blazor-webassembly",
"javascript",
"typescript",
"javascript-interop",
"source-generators",
"hacktoberfest"
],
"is_fork": false,
"size_kb": 211371,
"has_wiki": true,
"homepage": "https://ievangelist.github.io/blazorators/",
"languages": {
"C#": 2701130,
"JavaScript": 45237,
"TypeScript": 192143
},
"pushed_at": "2026-07-24T18:56:46Z",
"created_at": "2021-10-12T15:02:44Z",
"owner_type": "User",
"updated_at": "2026-07-24T18:56:50Z",
"description": "This project converts TypeScript type declarations into C# representations, and use C# source generators to expose automatic JavaScript interop functionality.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "main",
"license_spdx_raw": "MIT",
"primary_language": "C#",
"significant_languages": [
"C#"
]
},
"owner": {
"blog": "https://davidpine.dev/",
"name": "David Pine",
"type": "User",
"login": "IEvangelist",
"company": "@microsoft",
"location": "Pewaukee, WI",
"followers": 1017,
"avatar_url": "https://avatars.githubusercontent.com/u/7679720?v=4",
"created_at": "2014-05-23T11:18:56Z",
"is_verified": null,
"public_repos": 336,
"account_age_days": 4445
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "10.1.0",
"kind": "minor",
"published_at": "2026-07-24T18:48:52Z"
},
{
"tag": "10.0.0",
"kind": "major",
"published_at": "2026-05-14T20:49:04Z"
},
{
"tag": "9.0.2",
"kind": "patch",
"published_at": "2025-04-29T04:53:45Z"
},
{
"tag": "9.0.1",
"kind": "patch",
"published_at": "2024-12-01T02:39:23Z"
},
{
"tag": "9.0.0",
"kind": "major",
"published_at": "2024-11-22T15:21:41Z"
},
{
"tag": "8.0.0",
"kind": "major",
"published_at": "2023-11-17T19:22:21Z"
},
{
"tag": "8.0.0-rc.2.23480.2",
"kind": "prerelease",
"published_at": "2023-10-13T20:44:16Z"
},
{
"tag": "7.0.3",
"kind": "patch",
"published_at": "2023-02-15T19:42:16Z"
},
{
"tag": "7.0.2",
"kind": "patch",
"published_at": "2023-02-07T20:59:21Z"
},
{
"tag": "7.0.1",
"kind": "patch",
"published_at": "2023-01-24T04:05:45Z"
},
{
"tag": "7.0.0",
"kind": "major",
"published_at": "2023-01-11T00:35:08Z"
},
{
"tag": "2.0.11",
"kind": "patch",
"published_at": "2022-10-10T14:57:16Z"
},
{
"tag": "2.0.10",
"kind": "patch",
"published_at": "2022-05-19T13:50:01Z"
},
{
"tag": "2.0.9",
"kind": "patch",
"published_at": "2022-04-18T16:13:40Z"
},
{
"tag": "2.0.8",
"kind": "patch",
"published_at": "2022-04-14T20:29:27Z"
},
{
"tag": "2.0.7",
"kind": "patch",
"published_at": "2022-04-14T20:16:04Z"
},
{
"tag": "2.0.6",
"kind": "patch",
"published_at": "2022-04-07T16:16:31Z"
},
{
"tag": "2.0.5",
"kind": "patch",
"published_at": "2022-04-05T23:51:23Z"
},
{
"tag": "2.0.4",
"kind": "patch",
"published_at": "2022-04-05T23:47:44Z"
},
{
"tag": "2.0.3",
"kind": "patch",
"published_at": "2022-04-05T23:40:49Z"
},
{
"tag": "2.0.2",
"kind": "patch",
"published_at": "2022-04-04T18:09:07Z"
},
{
"tag": "2.0.1",
"kind": "patch",
"published_at": "2022-04-04T17:48:05Z"
},
{
"tag": "2.0.0",
"kind": "major",
"published_at": "2022-04-04T17:26:16Z"
},
{
"tag": "1.5.0",
"kind": "minor",
"published_at": "2022-03-29T15:21:33Z"
},
{
"tag": "1.4.5",
"kind": "patch",
"published_at": "2022-03-26T14:50:10Z"
},
{
"tag": "1.4.4",
"kind": "patch",
"published_at": "2022-03-26T01:38:06Z"
},
{
"tag": "1.4.3",
"kind": "patch",
"published_at": "2022-03-25T02:28:12Z"
},
{
"tag": "1.4.2",
"kind": "patch",
"published_at": "2022-03-23T15:48:27Z"
},
{
"tag": "1.4.1",
"kind": "patch",
"published_at": "2022-03-23T15:40:36Z"
},
{
"tag": "1.4.0",
"kind": "minor",
"published_at": "2022-03-22T14:31:38Z"
},
{
"tag": "1.3.3",
"kind": "patch",
"published_at": "2022-03-18T03:39:04Z"
},
{
"tag": "1.3.2",
"kind": "patch",
"published_at": "2022-03-18T03:34:15Z"
},
{
"tag": "1.3.1",
"kind": "patch",
"published_at": "2022-03-16T12:44:06Z"
},
{
"tag": "1.3.0",
"kind": "minor",
"published_at": "2022-03-16T04:01:16Z"
},
{
"tag": "1.2.0",
"kind": "minor",
"published_at": "2022-03-13T21:20:48Z"
},
{
"tag": "1.1.1",
"kind": "patch",
"published_at": "2022-03-08T02:44:22Z"
},
{
"tag": "1.1.0",
"kind": "minor",
"published_at": "2022-03-05T20:25:13Z"
},
{
"tag": "1.0.5",
"kind": "patch",
"published_at": "2022-03-04T21:34:08Z"
},
{
"tag": "1.0.4",
"kind": "patch",
"published_at": "2022-03-03T14:33:59Z"
},
{
"tag": "1.0.3",
"kind": "patch",
"published_at": "2022-02-24T02:18:39Z"
},
{
"tag": "1.0.2",
"kind": "patch",
"published_at": "2022-02-22T21:16:36Z"
},
{
"tag": "1.0.1",
"kind": "patch",
"published_at": "2022-02-22T05:06:56Z"
},
{
"tag": "1.0.0",
"kind": "major",
"published_at": "2022-02-22T04:35:23Z"
}
],
"recent_commits": [
{
"oid": "abe9091425dc6bd6126011894642fc370bc2876d",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 23daf7e5-e07e-4c52-a278-a7bfbffc0ffb",
"is_bot": false,
"headline": "Resume trusted NuGet publishing",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-24T18:56:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "e98ca363727d0822bbd459813a4735a7c7b8886c",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 23daf7e5-e07e-4c52-a278-a7bfbffc0ffb",
"is_bot": false,
"headline": "Add rich file previews and site search",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-24T18:36:00Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "88e901f4b12904351e049bf63e8101c6f1534b42",
"body": "* Build semantic DOM model\n\nAdd the pinned TypeScript and Web IDL extraction pipeline, strict schemas, deterministic JSONL artifacts, exact reconciliation accounting, provenance, and regression coverage for the Window DOM profile.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.\n[…]\n: 92c2c670-2273-4668-8c4a-17d93d697fbe\nCopilot-Session: cd6af8e4-1463-4f41-83cd-ef1f047d6ae6\nCopilot-Session: 317df431-f8e4-4b29-ae31-1f05ed91ba9d\nCopilot-Session: b1e23c54-4ce6-4df2-a413-08cfa975fab2",
"is_bot": false,
"headline": "Generate exhaustive Blazor DOM interop packages (#73)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-23T20:57:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "eb9ca1efea44740481e29d4a17657d0b43a121a9",
"body": "Smooth demo background transitions",
"is_bot": false,
"headline": "Merge pull request #72 from IEvangelist/ievangelist-neon-tattoo-restyle",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-20T02:19:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "139c4fcdba44674b7954cdc70b7715585d6aa0a9",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 6df4716c-f65a-42de-9816-7d5c9b8ebe7c",
"is_bot": false,
"headline": "Smooth demo background transitions",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-07-20T02:19:31Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "723b1a3eff8cbeac9946c746f6a2646f00504db8",
"body": "Restyle demo with neon tattoo theme",
"is_bot": false,
"headline": "Merge pull request #71 from IEvangelist/ievangelist-neon-tattoo-restyle",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-19T15:58:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "395f330d6c4526b8b3e382b59ae6688d125af263",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 6df4716c-f65a-42de-9816-7d5c9b8ebe7c",
"is_bot": false,
"headline": "Restyle demo with neon tattoo theme",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-07-19T15:57:13Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a9829e4f79395e45345aa1ff57e23cf14a5688d4",
"body": "* Fix resilient docs startup and CI\n\nRetry transient Pages boot-resource failures without weakening SRI, respect reduced-motion preferences, and align the browser regressions with the typewriter implementation.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\n\nCopilot-Sessio\n[…]\nnsure sample-site and workflow changes trigger pull-request validation.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\n\nCopilot-Session: cad5f07b-0de7-4065-8dbb-8bc3166fecb0",
"is_bot": false,
"headline": "Fix resilient docs startup and CI (#70)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-17T18:41:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9f639a55a8542ab6c2394410c78dd85cb9b03e4c",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Update GitHub logo mark",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-14T11:40:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1f6f0ca129461cb72175f16a8550920ada9dbc63",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Add typewriter suffix spacing",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:52:23Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7e0df5bfa48db352c841c59dc391a894d199689d",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Use typewriter hero phrase transition",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:47:25Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9312510f0f9f0e3d8ac385361c64f4af131c961b",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Render hero phrase suffix",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:27:37Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a23cb72abd3b3bfd6a6a40f1415f87ff5f665930",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Animate full hero phrase",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:24:15Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "567e26d29272bdd659e96f0e3db12e6765a1e84e",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Fix delayed hero rotator visibility",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:14:41Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "245f07b5650712fb56f25fc6495991ab94eab0fd",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Make hero rotator swap discretely",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:10:57Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "43df647f97751c820d62216d26a68a2938f30140",
"body": "Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Fix hero word rotator overlay",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-07-11T18:06:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "5ec733ba29ecd4f4781062dc64e158913b7eba00",
"body": "The W3C watchPosition contract only fires the callback when the browser\ndetects meaningful device motion, so stationary desktops never re-fire\nafter the first fix. This adds an opt-in polling cadence (5/15/30/60s)\nand a manual \"Refresh now\" trigger alongside the live watch mode.\n\nImplementation note\n[…]\node.\n- New E2E test asserts the ARIA contract, aria-pressed toggling, and\n status-badge transitions between WATCHING and POLLING.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Add refresh-interval toggle to /track demo",
"author_name": "David Pine",
"author_login": null,
"committed_at": "2026-06-02T04:48:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5ee6f22d48804838001e6473d560b49cbcd945a3",
"body": "Live axe sweep across all 8 routes flagged two serious color-contrast violations on /geolocation, /sandbox, /track:\n\n- .codeblock.is-error .codeblock-filename rendered #EF4343 on a near-white tint (~3.5:1, fails AA 4.5:1 for normal text).\n\n- .hljs-string rendered #1A9948 on the same tinted body bg (\n[…]\n routes x light+dark (16 page-states). Local E2E still 21/21 (one Firefox playwright-protocol teardown flake re-passed on re-run).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Bump destructive/warning/hljs colors to meet WCAG AA contrast",
"author_name": "David Pine",
"author_login": null,
"committed_at": "2026-06-02T04:17:45Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "59963957881a78b1609e25ffffc28368c2989234",
"body": "The hero rotating word (e.g. 'promised') was rendering visibly below the baseline of Browser APIs, and in C#.. The .word-rotator container used display: inline-grid with \u000bertical-align: -0.22em, an explicit 1.46em height, and inline-flex children centered with min-height: 100%. Because an inline-gri\n[…]\nline probe matches the surrounding text baseline exactly (delta 0.00px) at desktop and mobile, and local E2E (21/21) still passes.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Align hero word rotator to surrounding text baseline",
"author_name": "David Pine",
"author_login": null,
"committed_at": "2026-06-02T03:55:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e2ccc96c540d5e6c9c9be99f1ab0181a7f6af044",
"body": "Add a [JSAutoEnum] attribute + generator pipeline branch that anchors\non a C# interface and emits a sibling C# enum next to it, plus a\nper-enum JsonConverter<TEnum> that maps each member to its exact raw\nTypeScript string (and back) without relying on JsonStringEnumConverter's\nname-based heuristics.\n[…]\nespaces,\n duplicate-identity dedup, multi-source resolution, and end-to-end\n \"the generated enum source compiles cleanly\" check.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Project TypeScript string-literal unions as C# enums (C2)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "35b0e03739005e49bb21c37f21a0e50422bb41db",
"body": "Adds a single, deterministic-per-compilation\n`BlazoratorsServiceCollectionExtensions.AddBlazoratorsAll(this IServiceCollection)`\nhelper that chains every per-service `Add{ImplementationName}Services()`\nthe generator emitted. Consumers can now write one line to register\nthe full set:\n\n builder.Ser\n[…]\ntor), and syntactic\nvalidity (the generated tree parses cleanly with two chained\ninvocations).\n\nFull suite: 560/560 (was 554/554).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Emit `AddBlazoratorsAll()` aggregator DI extension (G4)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e02ac8849bf9e76a06e52143824373b873298e86",
"body": "Adds a zero-ceremony, assembly-targeted entry point for service\nprojection. Consumers can now write:\n\n [assembly: JSAutoService(\"Geolocation\")]\n [assembly: JSAutoService(\"Clipboard\", \"Storage\")]\n\nand the generator emits the full `I{Name}Service` partial interface,\n`{Name}Service` implementation, a\n[…]\nerride path, BR0006 surface\nwhen the inferred TS type is unknown, and the collision-dedup case.\nFull suite: 554/554 (was 545/545).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Project services from `[assembly: JSAutoService(...)]` (G2)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "dea9491e3c76f9af075ffd312405012623d796c9",
"body": "Consumers can now opt into a minimal attribute form:\n\n [JSAutoInterop]\n public partial interface IGeolocationService { }\n\nis equivalent to\n\n [JSAutoInterop(\n TypeName = \"Geolocation\",\n Implementation = \"window.geolocation\")]\n public partial interface IGeolocationService { }\n[…]\nurface. The diagnostic descriptor\n is retained for defensive use.\n\nFull suite: 545 / 545 green (was 513 pre-G1, +32 new tests).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Infer TypeName and Implementation on `[JSAutoInterop]` (G1)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "67885640fc731a856f07995695c5416e8cef8a1d",
"body": "TS intersection aliases (`type X = A & B`) merge member sets at the\ntype-system level. The closest C# projection would be a synthesized\nDTO that carries members from both sides, which requires resolving\neach arm independently (interface vs. alias vs. generic invocation)\nplus a dedup pass -- a much l\n[…]\nhis slice -- they include `typeof` and\nparens that need a wider parser change. Existing behavior on those\nproperties is unchanged.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Fall back unsupported intersection aliases to `object` (B7)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9e9813666e0fe929e6ebb73c96cec6127b3628d6",
"body": "The `Record<K, V>` -> `Dictionary<TKey, TValue>` translation in both\n`CSharpProperty.MappedTypeName` and `CSharpType.ToParameterString`\nrouted K and V through a single `TypeMap.PrimitiveTypes[...]` lookup.\nThat worked for the DOM corpus (all hits are\n`Record<string, number>`, `Record<string, string>\n[…]\negression)\n- Record<string, Element> -> Dictionary<string, Element> (regression)\n\nSuite: 506 / 506 pass (500 + 6 new).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Recursively map nested generic args in Record (B11)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "64d57a1e85b9499b6076dd6e6ea75c77d5d95286",
"body": "Before this change, TypeScript alias declarations like\n\n type BodyInit = ReadableStream | XMLHttpRequestBodyInit;\n type RequestInfo = Request | string;\n type HeadersInit = [string, string][] | Record<string, string> | Headers;\n\nleaked the raw alias identifier (`BodyInit`, `RequestInfo`,\n`HeadersI\n[…]\nuble (regression)\n- HTMLElement (unknown alias / interface ref) -> HTMLElement (regression)\n\nSuite: 500 / 500 pass (493 + 7 new).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Fall back unsupported union aliases to `object` (B8)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "67484a1163aed0054ddf3d5ab8e061108bb57951",
"body": "Phase B4. A handful of `lib.dom.d.ts` interfaces -- notably `Document`\nand `Window` -- declare properties using the ES2015 accessor syntax:\n\n get location(): Location;\n set location(href: string | Location);\n\nBoth lines were silently dropped today. The getter falls through\n`IsMethod` (regex `\\\n[…]\non`, and a regression guard that the accessor must not\n produce a `get`/`set` method.\n\nFull suite: 493/493 passing (488 + 5 new).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Recover ES2015 getter-accessor properties (e.g. Document.location)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "41309abacbb71b8460a222c2212e2bb2e8f9bad4",
"body": "Add a pure-detection helper that recognizes TypeScript string-literal\nunion aliases (e.g. `type DocumentReadyState = \"complete\" |\n\"interactive\" | \"loading\";`) and converts each raw value into a valid\nC# enum member identifier. This is the foundation for opt-in C# enum\nprojection in a future slice; n\n[…]\nus\nspot checks (`DocumentReadyState`, `PermissionName`, `InsertPosition`)\nplus a `BodyInit` negative. Full suite: 488/488 passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Detect string-literal union aliases (B3 slice 1, no emission)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8471b16e9f393b257569ffc23ac49915b77b2753",
"body": "`InterfaceTypeNameRegex` greedy-matches non-whitespace, so a TypeScript\nheader like `interface CustomEventInit<T = any> extends EventInit { ... }`\nused to surface `TypeName = \"CustomEventInit<T\"` -- breaking both\n`TypeDeclarationReader._typeDeclarationMap` lookups (the bare name\n`\"CustomEventInit\"` \n[…]\nEventInit`\n keeps `Map<string, number>` whole as the primary base and still\n merges `EventInit`'s members.\n\nFull suite: 438/438.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Normalize generic interface names + depth-aware extends split",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b2e7eaf4dc4ca693bb67b74562fc7722a748fc7e",
"body": "`TypeDeclarationParser.Interfaces.ToObject` only captured the first\nbase via the single-token `ExtendsTypeNameRegex`, and that capture\ngreedily included the trailing comma — so `interface DocumentFragment\nextends Node, NonElementParentNode, ParentNode { ... }` produced\n`ExtendsTypeName = \"Node,\"` an\n[…]\nd\nmembers from `Node` + `NonElementParentNode` + `ParentNode` present\nplus the overriding `getElementById`).\n\nFull suite: 436/436.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Merge multi-extends base members in interface parser",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1a8aff22dbd6aee884c075cc0a15406c61960f6e",
"body": "This is the safety net the rest of the universal-coverage work hangs\noff of. Three new xUnit tests in CorpusCoverageTests drive every\ninterface (1062) and type alias (222) in the bundled lib.dom.d.ts\nthrough the parser, assert that nothing throws, and write a coverage\nreport under <BaseDirectory>/co\n[…]\n thin\nwrapper over the existing dictionaries with no behavior change.\n\nAll 435 tests pass (the prior 432 plus three corpus tests).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Add Phase A corpus coverage harness + parser cycle guard & memoization",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-06-02T03:46:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "33c021584daa16a5b65bf935dd526ea3dea5000b",
"body": "Allow the deployed GitHub Pages route canonicalization to add a trailing slash while still asserting the skip link preserves the route and focuses main content.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Handle Pages route slashes in skip-link test",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-30T04:41:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7ab26878cda6b9be29ce027a63bb05faed684978",
"body": "Add comprehensive Playwright end-to-end coverage for every sample route, tighten WCAG-oriented contrast and semantics, improve keyboard/focus behavior, and fix layout polish for the hero rotator and track page panels.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Polish sample site accessibility and UX",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-30T04:19:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "3eaf7cfbb8d2087d9718839d5566c2b124fd47ce",
"body": "Iterated through every demo route capturing screenshots and fixed the\nissues that stood out at typical desktop and mobile widths.\n\nMainLayout\n- Hamburger now toggles the sidebar on every viewport. Single\n `.nav-toggled` class on `.app` collapses the desktop sidebar (grid\n column animates to 0 + si\n[…]\nso we only split when there's\n real room; below that, the animation sits at full width on top with\n the code preview underneath.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Polish UX after audit: hamburger, bubbles, timeline, footer",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-05-17T00:31:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a1d7831a6bf612413ba6dd91a341600c5fbc42c6",
"body": "…ento copy\n\n* Live event timeline on /track: map + timeline side-by-side with prepended\n entries (max 25, dedup'd), pulsing newest dot, splat-in animation,\n HH:mm:ss.fff timestamps, accuracy badges, and lat/lng/speed/heading\n stats; collapses to single column on mobile and respects\n prefers-redu\n[…]\nth\n natural chat-style transcripts (Hello, are you ready?, Listening live...,\n Transcribe everything., Type-safe, cancellable.).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Add live event timeline to /track, richer audio waveform & polished b…",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T17:57:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "db3cb2eb38aa991970bf3911fb079a8ce590bf9e",
"body": "Each demo card now hosts a self-contained CSS/SVG animation panel\nthat illustrates the API it represents:\n\n- Featured Local storage: split layout with an animated stack of mini\n todo cards flying right into a pulsing 'localStorage' disk, beside\n the existing inline code preview (flex-stretched to \n[…]\n on dashed rings\n\nAll animations honor prefers-reduced-motion, and cards subtly speed up\non hover to amplify the spotlight + glow.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Give every bento card its own inner micro-animation",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T17:02:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "882b34b4b93678bcf2a3737cf1dee74ba8a81e25",
"body": "- Aurora-blob hero background with subtle grid overlay and slow drift\n- Cross-fading word rotator (type-safe / ergonomic / promised / generated)\n- Hero stats strip with gradient numerals and net8/9/10 multi-target chip\n- 12-col bento layout with featured 8x2 'Local storage, type-safe' card\n- Inline \n[…]\n icon rotate, shimmer on preview\n- Staggered rise-in entrance via [data-reveal] / .bento children\n- Honours prefers-reduced-motion\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Reimagine landing UX with bento grid + spotlight cards",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T11:28:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b3e576a90ad14872bc24c93d6586a236a1daddaf",
"body": "The sample now targets net10.0 (via global.json \rollForward: latestFeature\npinning to 10.0.100). The workflow was still hard-coded to 9.0.x, which\nwould fail to restore/publish. Use global-json-file so the workflow\nalways tracks the project's SDK without further drift.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "ci: pin gh-pages deploy to project's .NET SDK via global.json",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T11:03:34Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "24fd57033dba35a22dc68a4b5f3ddef7fb7783ec",
"body": "\u0007ria-pressed=@bool was rendering as \u0007ria-pressed=\"\" for true (Blazor\nemits bool attributes as boolean-style attributes), so the CSS selector\n[aria-pressed=\"true\"] never matched and no button looked active.\n\nBind a string ternary so the attribute is always literally \"true\" or\n\"false\". Also bump the a\n[…]\nund instead of --background (which is nearly\nidentical to --muted in dark mode) so the selection reads at a glance\nin both themes.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Fix theme toggle active-state visibility",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T11:03:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bad4298b4cc67791e4b68e835ebac42bc427fa9a",
"body": "Strips Bootstrap and the deprecated Open Iconic font from\n`samples/Blazor.ExampleConsumer`, replaces them with an Unlumen UI\ninspired design language built entirely in CSS + inline SVG. Adds a\nlight/dark theme system, swaps the expired Bing Maps integration for\nMapLibre GL JS over the free, OSS Open\n[…]\n-generator\n parser keeps working on Windows checkouts (it parses\n `Data/lib.dom.d.ts` via a regex that assumes LF line endings).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Modernize GH Pages demo UX with Unlumen-style design",
"author_name": "IEvangelist",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T11:03:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ac0152c7de1d6d0ff867e872be4573dfeacc902b",
"body": "A typed declaration like `getItem<T>(key: string): Promise<T | null>;`\nwent through three independent issues at once:\n\n1. `CSharpMethod.IsReturnTypeNullable` looked only at the outer\n `RawReturnTypeName`. For `Promise<T | null>` that string ends\n with `>`, not `| null`, so `HasNullClause` return\n[…]\npts into `[JSAutoGenericInterop]` against a Promise-\nreturning declaration.\n\n432 tests passing (up from 424; +8 regression cases).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Wrap generic Promise<T> returns in ValueTask under WebAssembly",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:56:09Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a5b4a317e8e7ce7b2da116ad8e6b8714c4e52e83",
"body": "`string.Contains(string)` and `string.LastIndexOf(string)` lack\n`StringComparison` overloads on netstandard2.0 (the target framework\nfor analyzers and source generators). Both fall through to the\nculture-sensitive default implementation, which is the same Turkish-\nlocale class of bug that motivated \n[…]\nNo emit-behaviour change for the existing snapshots; defensive\nfollow-up to the broader culture-invariant pass. 424 tests passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Replace culture-sensitive Contains/LastIndexOf with ordinal lookups",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:50:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4053b6cae073e69cbbf87890a10f8e7aeb6188cb",
"body": "`EmitActionComponentMethod` in `CSharpTopLevelObject.Implementation`\ncalls `arg.Substring(2)` unguarded to strip the synthetic `on`\nprefix added by `ToArgumentString` for callback parameters before\nlooking up the matching `[JSInvokable]` method (e.g. `onSuccess` ->\n`Success` -> `OnSuccess`). For non\n[…]\nng-ops pass).\n\nNo emit-behaviour change for the existing snapshots; defensive fix\nplus matching parity with the rest of the audit.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Harden Action-callback emit path against short parameter names",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:44:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "224304f64ef8a7634de920d0c3d0fcf77bd4ccd7",
"body": "`CSharpObject.AppendHeader` hardcoded `namespace Microsoft.JSInterop;`\nfor every dependent type file (e.g. `PositionOptions.g.cs`,\n`PermissionDescriptor.g.cs`), but the generated interface and\nimplementation land in the consumer's containing namespace and\nreference those types unqualified. Any consu\n[…]\nia the default\nparameter.\n\nAdds `CustomNamespace_DependentTypes_Use_Consumer_Namespace` as\nregression coverage. 424 tests passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Emit dependent DTOs into the consumer's namespace",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:42:26Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f962d9d10695345acef207f5bb4aa4fc5a3fe8a0",
"body": "The generated interface and implementation surfaces routinely emit\n`Action<...>` parameters for TS callback bindings (e.g.\n`Geolocation.GetCurrentPosition(Action<GeolocationPosition> ...)`).\nThe previous output relied on the consumer project having\n`<ImplicitUsings>enable</ImplicitUsings>` for `Syst\n[…]\nre\nself-contained regardless of the host project's settings. Snapshots\nregenerated for the six interface / implementation outputs.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Always emit `using System;` in generated interop sources",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:40:36Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a1a9d6e78ebf888c0139500d188ab4834a726cfc",
"body": "A source generator runs in the host build process, which inherits the\nmachine's current culture. Two related families of operations were\ndefaulting to current-culture behavior:\n\n1. `char.ToUpper` / `char.ToLower` in `StringExtensions.{Capitalize,LowerCase}FirstLetter`\n — these drive every type/met\n[…]\n silently misclassify nullable / readonly modifiers\nunder any locale where casing-sensitive prefix matching diverges\nfrom ordinal.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Use culture-invariant string ops in the source generator",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:37:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "44c842be3739ef5779115a075fb804f64eae5ffa",
"body": "…ions\n\n`CSharpAction.ParameterDefinitions` is declared `List<CSharpType>?`\n(nullable, default `null`). The constructor in\n`TypeDeclarationParser.ToAction` initializes a `CSharpAction` with\njust the type name and only fills `ParameterDefinitions` via a `with`\nclone if the call-signature regex matches\n[…]\n (the\nparallel API on the same record) already had a `is null` guard, so\nthis just brings the dependency-graph walker into parity.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Harden `CSharpAction.AllDependentTypes` against null ParameterDefinit…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:35:30Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f597c98aa0591f4f97c1a90cef8a5be746064e1e",
"body": "The generated `*ServiceCollectionExtensions.g.cs` always lives in\n`Microsoft.Extensions.DependencyInjection` so consumers can chain\n`services.Add*Services()` without an extra `using`. The interface and\nimplementation it references, however, are emitted into the\nconsumer's containing namespace (the n\n[…]\nss of consumer\nnamespace. Adds an inline assertion test\n(`CustomNamespace_DI_Extension_Adds_Consumer_Using`) for the new\nbehavior.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Emit consumer `using` in generated DI extension class",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:34:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "bb7eda2eeee8ee61aa40c133bdf600580f406c83",
"body": "The emitted `JSAutoInteropAttribute` / `JSAutoGenericInteropAttribute`\ndocs claimed the attribute is placed on a `public static partial`\nextension-method class. In reality both attributes have\n`[AttributeUsage(AttributeTargets.Interface)]` and every consumer in\nthe repo places them on a `public part\n[…]\nat `RegisterPostInitial-\nizationOutput` time, so the change ships to every consumer the next\ntime they build against the analyzer.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Correct XML doc examples on emitted interop attributes",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:31:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e257cbcfac1f46a27b2b71a3b34db75de78265c0",
"body": "Internal local in `PropertyBuilderDetails.Create` was spelled\n`javaScriptIndentifier` (missing the first `i` in \"Identifier\"),\nwhich sat next to the correctly-spelled record property\n`FullyQualifiedJavaScriptIdentifier`. Internal-only rename, no\nbehavior change.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Fix `javaScriptIndentifier` typo in `PropertyBuilderDetails`",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:27:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "674ca6713ad84645ed44ae52fbc9e8300946dc47",
"body": "The root README's \"WebAssembly libraries\" and \"Server libraries\"\ntables -- and the analyzer package README's \"consumed by\" list --\nwere missing entries for `Blazor.Permissions.WebAssembly` and the\n`Blazor.SpeechRecognition`/`Blazor.SpeechRecognition.WebAssembly`\npair, even though those projects exist in the solution and ship\nmatching NuGet packages. Add the missing rows so the documentation\nmatches the actual shipping surface.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Update README package tables to include all shipping libraries",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:26:05Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "145049bb1a7584e0631ca7c9c3efbbb64e330ead",
"body": "`CSharpPropertyExtensions.GetPropertyTypes` drives the property\nshape emitted into the top-level generated interface and\nimplementation classes. It already mapped TS `T[]` / `Array<T>` /\n`ReadonlyArray<T>` to a C# array suffix, but silently dropped the\nnullable annotation for any case where `CSharpP\n[…]\nrted-but-incorrect\n`T[]` (the test was added during T1.10 to pin element-mapping but\nlocked in the nullability drop alongside it).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Preserve nullable annotation on non-primitive top-level properties",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:24:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a09698587457040a47ab5ce674a2c4e9b5b6a533",
"body": "The Geolocation_Wasm scenario already pinned the generated\n`AddGeolocationServices` extension shape; the Permissions_Wasm\nscenario was missing the matching snapshot. Add it so the DI wiring\nshape -- specifically the singleton `IJSInProcessRuntime` adapter\nthat resolves `IJSRuntime` and casts to the WASM in-process runtime\n-- is pinned under the Promise/async generation path too.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Pin Permissions DI extension snapshot",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:21:25Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b8b0935972b5b70949b83ef85d9db603c7e763ff",
"body": "Two coupled gaps prevented the package from being usable:\n\n1. The csproj targeted `Microsoft.NET.Sdk` rather than\n `Microsoft.NET.Sdk.Razor`, so `wwwroot/blazorators.permissions.g.js`\n was never published as a static web asset under\n `_content/Blazor.Permissions.WebAssembly/`. Consumers adding\n[…]\nissions API surface (including the\n`_content/Blazor.Permissions.WebAssembly/blazorators.permissions.g.js`\nscript tag instruction).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Convert Blazor.Permissions.WebAssembly to Razor class library",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:18:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4545ace2ab72616c594a878e769c3e56e9cdbed4",
"body": "Promise-returning interop methods route through the async path even\nunder WebAssembly hosting (forced by `MethodBuilderDetails.Create`\nbecause a TS `Promise<T>` can't resolve synchronously). That means\nthe generated service references `ValueTask<T>` regardless of\nhosting model -- but the previous `A\n[…]\nendUsingDeclarations` and emit the using whenever the value is\ntrue. Updated the `Permissions_Wasm` snapshots to pin the new line.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Emit `using System.Threading.Tasks;` for Promise-returning WASM services",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:14:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4ccb48144de39a68b24e0d25be561f3da7c443a4",
"body": "Activating `[JSAutoInterop]` on `IPermissionsService` causes the\ngenerator to route the `Permissions.query(...)` call through\n`blazorators.permissions.query` (the standard `blazorators.<type>.<method>`\nshim path used whenever a parameter is a custom DTO). Ship the\nmatching JS file so `await Permissi\n[…]\nator strips `extends\n EventTarget` and the `onchange` event-handler property, so the\n payload only needs `Name` and `State`.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Add JS shim for `blazorators.permissions.query`",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:09:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ca589a6989488e73491916f0285ff818e1116099",
"body": "Bring the published `Blazor.Permissions.WebAssembly` package in line\nwith the rest of the family (Geolocation, LocalStorage,\nSessionStorage, SpeechRecognition, SpeechSynthesis) by enabling the\n`[JSAutoInterop]` attribute that was previously commented out. The\ngenerator now correctly emits the full s\n[…]\nr\n artefacts (`IPermissionsService.g.cs`, `PermissionsService.g.cs`,\n `PermissionDescriptor.g.cs`, `PermissionStatus.g.cs`).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Activate `[JSAutoInterop]` on Blazor.Permissions.WebAssembly",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:07:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "43fdda018df614de808198e2e1de29a4a1fca432",
"body": "The TS utility type `Record<K, V>` (the dictionary primitive) was\npreviously left untouched by the generator -- a property typed\n`Record<string, number>` emitted as the literal `Record<string,\nnumber>` into the C# DTO, which isn't a valid CLR type and broke\nany consumer that referenced the property.\n[…]\nwnstream DTO\nresolution.\n\n11 new tests in `TypeShapeRecordTests` cover the splitter and the\nproperty mapping. Full suite: 412/412.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Map TS `Record<K, V>` to C# `Dictionary<K, V>`",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T04:04:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c07fc681a6169b37e03c2dd04127a2c69bdc7b2e",
"body": "Adds four snapshot tests around the Permissions DOM type\n(`navigator.permissions.query() -> Promise<PermissionStatus>`) to lock\nin three pre-existing behaviours under one realistic interop surface:\n\n * `Promise<T>` returns map to `ValueTask<T>` with the `Async` method\n suffix and `InvokeAsync<T>\n[…]\nsync, and strip a\ntrailing `| null` / `| undefined` clause so `Promise<T | null>` and\n`T | null` returns resolve against bare `T`.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Pin Permissions sample end-to-end + unwrap Promise<T> for dependent DTOs",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:58:56Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "42c23f09cac23d757d98dcf7d5e25babc0d6f3b8",
"body": "Real DOM declarations use ` | undefined` interchangeably with\n` | null` to mean \"this value might not be present\", especially on\nPromise-returned values. Examples:\n\n * `Cache.match(): Promise<Response | undefined>`\n * `ServiceWorkerContainer.getRegistration(): Promise<ServiceWorkerRegistration | u\n[…]\nturn predicate, array-element extraction across both\nclause forms, and the property mapped-type helper. Full suite is\nnow 388/388.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Treat TS `| undefined` clause as nullable in all emit paths",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:52:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c94759703e6041c9312ea59dcc69db55fa8226d3",
"body": "`AppendTripleSlashMethodComments` derived the generic-argument list\nfor the rendered `<c>System.Action{T1, T2, ...}</c>` token from\n`param.ActionDeclaration.DependentTypes.Keys`. That collection only\ncaptures *custom* types pulled into the dependency graph:\n\n * TS primitives never go through the de\n[…]\nray, mixed, and zero-parameter\ncallback doc rendering, plus a regression assertion for the stray\nquote. Full suite is now 368/368.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Render accurate `System.Action<>` doc comment for callback parameters",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:47:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f33dde3452989e04919bfdd87114751784ad8bfb",
"body": "Real DOM declarations declare parameters whose names collide with C#\nreserved keywords -- e.g. `Document.createElementNS(namespace: string,\nqualifiedName: string, ...)`, `Element.getAttributeNS(namespace, ...)`,\nseveral callback shims with parameters named `event`. The generator\nemitted the bare Typ\n[…]\n and without JSON marshalling), and the\n`null`-bearing parameter shape. Full suite now 363/363 green\n(was 328 before this commit).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Escape C# reserved keywords in generated parameter names",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:43:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "109a0e2b77f77fbc822326e82f5c09aeed8f73f3",
"body": "TypeScript declares dozens of DOM APIs as `Promise<T>`-returning:\n`Permissions.query()`, `Body.arrayBuffer()`,\n`AudioContext.close()`, `Lock.request()`, etc. The generator\npreviously dropped the verbatim `Promise<T>` token straight into\nthe C# method signature and the `_javaScript.Invoke<T>()` call,\n[…]\ne,\nWASM and Server return-type emission for scalar / custom / nullable\n/ array payloads, and the `Promise<void>` shape end-to-end.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Unwrap TS `Promise<T>` return types to `ValueTask<T>`",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:40:13Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "6c02169be93ec91d9e611647620a067086d9f0c0",
"body": "Custom-type return types with a trailing TypeScript `| null` (e.g.\n`getElementById(id: string): HTMLElement | null;`,\n`getActiveElement(): Element | null;`) previously dropped the raw\nTS spelling straight into the generated method signature and the\n`_javaScript.Invoke<T>()` call. `Node | null` is no\n[…]\nom nullable, custom-array nullable,\nprimitive-array nullable, and the existing primitive scalar nullable\npath (regression-pinned).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Map TS `| null` clause to C# nullable suffix for method return types",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:33:42Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a239908c6dbad74690ed697499c21f243bfad8a1",
"body": "The top-level emit path in CSharpTopLevelObject filters TypeScript\nindex-signature properties (`[key: string]: T;`) via\n`CSharpProperty.IsIndexer` before generating the interface and\nimplementation. The dependent-DTO emit path\n(`CSharpObject.ToClassString`) iterated the same property\ndictionary with\n[…]\no the dependent-DTO path mirrors the top-level path's behavior.\n\nAdds three regression tests in CSharpObjectIndexerFilterTests.cs.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Filter indexer properties from dependent DTO class emit",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:26:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ac96bd8b7e159a9f709f56e5b6133ad2f8df60c7",
"body": "The two emit paths for a TS-callback-typed parameter -- the\npublic-facing `Action<...>?` signature in `CSharpType.ToActionString`\nand the private backing field in\n`SourceBuilder.AppendConditionalDelegateFields` -- derived their\ngeneric argument lists from different collections:\n\n* `ToActionString` j\n[…]\nts in CallbackPrimitiveParameterTests.cs\ncovering single-primitive, mixed primitive+custom, nullable, and\nboolean parameter cases.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Map TS primitive params to C# in callback emit paths",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:23:27Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "08a47aa34d4cc8bf3345357ff770695956a87c19",
"body": "The shared property regex\n`^(?'Name'.*)\\:(?:.{1})(?'Type'.*)\\;$` has a greedy `Name` capture\nthat walks to the *last* `:` in a line. For TypeScript property\ndeclarations whose type is an arrow function -- e.g.\n`UnderlyingSource` in lib.dom.d.ts:\n\n pull?: (controller: ReadableStreamDefaultControll\n[…]\n the\n`ToObject` (dependent-DTO) and `ToTopLevelObject` paths.\n\nAdds three regression tests in ArrowFunctionPropertyFilterTests.cs.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Filter arrow-function-typed property lines in IsProperty",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:18:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8d40daf7b2b03259b851fc577a985daf59b4ac7e",
"body": "`lib.dom.d.ts` declares many trivial aliases that point at a primitive\nTS type, e.g.\n\n type DOMHighResTimeStamp = number;\n type GLuint = number;\n type GLboolean = boolean;\n type EpochTimeStamp = number;\n\nPreviously `TryGetPrimitiveType` only resolved string-literal-union\naliases (`type D\n[…]\nthe property, method-return, and parameter surfaces across\nthe three common alias shapes. Full suite: 279 -> 289 tests, all green.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Resolve single-primitive TypeScript aliases (DOMHighResTimeStamp, GL*)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:11:38Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8f897c190b0f7cb0b621d74c1ac0100173251265",
"body": "Three code paths produced uncompilable output when a method accepted\na TS callback with zero parameters (e.g. `VoidFunction`, `(): void;`,\nused by `WindowOrWorkerGlobalScope.queueMicrotask`):\n\n* `CSharpType.ToActionString` joined `ActionDeclaration.DependentTypes`\n keys into the generic argument li\n[…]\nross `CSharpTypeCallbackActionStringTests`\nand `SourceBuilderZeroParameterCallbackTests`. Full suite:\n274 -> 279 tests, all green.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Emit valid C# for zero-parameter TS callbacks (VoidFunction)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T03:03:50Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "41beab2bbf813f3e1515d9b8373ff618f4630ea5",
"body": "When a method parameter or return type was an array of a user-defined\nTypeScript interface (e.g. `MutationRecord[]`), the generator looked\nthe literal type string up in the declaration map without stripping\nthe array suffix. Because the map keys the element type only, no\nmatch occurred, the element \n[…]\nntDependentTypeTests` covering\nparameter and return positions for all three array shapes. Full\nsuite: 268 -> 274 tests, all green.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Emit dependent DTOs for array-of-custom-type parameters and return types",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:58:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "466e854da35b911eac5d5c58e35b444c1f99092a",
"body": "…positions\n\n`CSharpType.ToParameterString` and `CSharpMethodExtensions.GetMethodTypes`\nboth relied on `TypeMap.PrimitiveTypes.IsPrimitiveType(RawTypeName)`\nreturning `true` for the full type spelling. That works for scalar\nTS primitives (`number` -> `double`), but it returns `false` for the\narray fo\n[…]\nsts` (8 cases) and\n`CSharpMethodReturnTypeArrayTests` (11 cases) covering scalar +\nnullable + non-primitive forms. 268 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Map TypeScript primitive arrays to C# arrays in parameter and return …",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:55:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1adaca3077d526200440fe20d0de46fde8e6f408",
"body": "…nostic and polish messages\n\n`Descriptors.PathFromWindowRequiredDiagnostic` carried a stale name\nfrom an earlier iteration of `JSAutoInteropAttribute` (when the\nproperty was called `PathFromWindow`). It now flags a missing\n`Implementation` value, so the field name was misleading - any future\ncontrib\n[…]\ne\n controls\n\nThe diagnostics are still tracked as `Unshipped`, so the message\npolish is in-scope. All 249 tests continue to pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Rename PathFromWindowRequiredDiagnostic to ImplementationRequiredDiag…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:50:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3458ec5e679371260a614b6585d7739687302f28",
"body": "ToObject and ToTopLevelObject classified a property as nullable when\nits raw type string `Contains(\"| null\")`. That returns false positives\nfor shapes where `| null` appears only inside a generic argument or\narray element (e.g. `(number | null)[]`, `Map<string, string | null>`).\nThe reference itself\n[…]\nameterized cases covering the new boundary (including the two\nnested-`| null` regressions that previously failed). 249 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Tighten property-level nullable detection to top-level | null only",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:46:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4d8702001e7db546f6dd06eb68d0b95722db6235",
"body": "CSharpObject.IsActionParameter used to OR shape-based IsCallback with\na name-suffix fallback `TypeName.EndsWith(\"Callback\")`. The latter\nmisclassified any normal DTO whose name happens to end with the\nsubstring, silently dropping it from the generated output (the\npredicate gates AddDependentTypesSou\n[…]\nests with five regression cases\ncovering the previous false-positive and confirming the new\nshape-driven behavior. 242 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "Remove brittle Callback suffix fallback in IsActionParameter",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:44:03Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "42a066be5e76c6252ab1bc198262b1484153dca8",
"body": "…lable arrays\n\n`CSharpProperty.IsArray` and `TryGetArrayElementTypeName` matched on\n`EndsWith(\"[]\")` (and the `Array<...>` / `ReadonlyArray<...>` generic\nprefixes) against the raw TypeScript type. For nullable arrays the\ntype ends with `null`, not `]` or `>`, so the array shape was never\nrecognized.\n[…]\ndouble[]\"\n\nAdds 13 parameterized regression cases across `IsArray`,\n`MappedTypeName`, and `GetPropertyTypes`.\n\nAll 234 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: recognize `T[] | null` (and Array/ReadonlyArray variants) as nul…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:40:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "47e68bddc64aa0d8f38104b17d8fc6abae2b809e",
"body": "…le shapes\n\n`CSharpMethod.IsReturnTypeNullable` checked\n`RawReturnTypeName.Contains(\"null\")`, which returns `true` for any\nidentifier whose name happens to contain the substring \"null\" --\nincluding the bundled DOM types `OnBeforeUnloadEventHandlerNonNull`\nand `OnErrorEventHandlerNonNull`, plus any u\n[…]\nssion cases covering both true positives\n(real `| null` clauses) and false positives (identifier substrings).\n\nAll 221 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: tighten `IsReturnTypeNullable` to recognize only TS-level nullab…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:36:51Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "94fb3f0376c84d91fe81bd71226fc8425b7777a6",
"body": "`ParseParameters` previously detected nullability only from the\nparameter name's trailing `?`. When a `.d.ts` parameter was instead\nwritten as `x: T | null` (without a `?` on the name), the parser\nkept the literal \"| null\" in the C# type token. For primitives like\n`string | null` this happened to wo\n[…]\ns the parameter's `IsNullable` flag flips and that\n`ToParameterString()` no longer contains the literal `| null`.\n\n210 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: normalize type-level `| null` parameter annotations to nullable C#",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:35:15Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "a37b986430b786027758326e7fbde5a38792f3bc",
"body": "…ions\n\n`GenericMethodDescriptors`, `PureJavaScriptOverrides`, and\n`TypeDeclarationSources` accept `string[]?`. With C# 12 collection\nexpressions, consumers can write:\n\n [JSAutoGenericInterop(\n GenericMethodDescriptors = [\"getItem\", \"setItem:value\"])]\n\n`ReadStringArray` recognized `new[] { \n[…]\ner\n - [...] collection expression with literal strings\n - [...] collection expression with const references\n\nAll 207 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "feat: parse string-array attribute args from C# 12 collection express…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:31:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "59131477061f7b7b7aa470e503ed4a5d14017ed9",
"body": "`ResolveParsers` constructed a fresh `TypeDeclarationParser` (and the\nunderlying `TypeDeclarationReader`) for every matched `.d.ts`\nreference in every target. When multiple `[JSAutoInterop]` targets\nin the same compilation point at the same `AdditionalFile` (the\ncommon case once `TypeDeclarationSour\n[…]\nis GC'd with the parsers\nthemselves; we do not extend their lifetime beyond the source-output\nboundary.\n\nAll 203 tests still pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "perf: share TypeDeclarationParser across targets within an Execute pass",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:29:39Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "df5dbb76d6942ef3fcf55162f8038815ad1c9ad1",
"body": "The `Indentation` value type held a `Level` field that was never\nclamped. `Decrease()` computed `Level - 1 - extra`, and `ResetTo(int)`\ncopied the caller's value verbatim. Both could leave `Level` negative.\n`ToString()` then evaluates `new string(' ', Spaces * Level)` which\nthrows `ArgumentOutOfRang\n[…]\n regression tests covering Decrease-from-zero,\nDecrease-with-extra, ResetTo-negative, and the positive paths.\n\nAll 203 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: clamp Indentation Decrease/ResetTo to non-negative levels",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:26:35Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "685cdd3ed6ae2d523f4a392a2207d64626fb95d7",
"body": "…ually shrinks\n\nThe previous test only asserted that *some* output was produced when\n'OnlyGeneratePureJS = true' was set, which any non-trivial code path\nwould satisfy. The flag's documented purpose is to *exclude* methods\nthat need JS-callback wiring (e.g. 'Geolocation.watchPosition'/\n'getCurrentPo\n[…]\ned out).\n\nThis catches regressions where the flag silently stops gating output,\nwhich the prior test did not.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "test: strengthen OnlyGeneratePureJS coverage to verify method-set act…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:25:11Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8ce5d2ab50722d9d80064b8780364125e10a3233",
"body": "…ehavior\n\nTwo internal comments still described TypeDeclarationSources as\n'reserved for future use' even though T5.1 fully wired the property\ninto the generator pipeline. Update both to describe the actual\nbehavior:\n\n* GeneratorOptions.BuildParsers — clarify that this is the fallback\n path used whe\n[…]\nReader(content) directly,\n which is what the generator already does for AdditionalFiles.\n\nNo behavior change. All 198 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "docs: refresh stale TypeDeclarationSources comments to reflect T5.1 b…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:23:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7e5ff5b39f17a2b8b10ec2b7b8b5122ed27cd49a",
"body": "….1 behavior\n\nThe emitted attribute's XML doc for `TypeDeclarationSources` still\nclaimed the property was \"reserved for future use\" and that \"setting\nit has no effect\". The audit's T5.1 work wired this property into the\ngenerator pipeline so the generator now reads matched `.d.ts` files\nfrom `Additi\n[…]\nle doc with the actual behavior, including the\n`AdditionalFiles` MSBuild snippet a consumer needs to wire up.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "docs: align JSAutoInteropAttribute.TypeDeclarationSources doc with T5…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:23:01Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "2a12791de33190827d119fee9c69926287b2c8de",
"body": "Mark every regex in `SharedRegex` as `RegexOptions.Compiled |\nRegexOptions.CultureInvariant`. The parser evaluates these patterns\nmany times per generator run - once per matched interface, method,\nproperty, and array literal across ~800KB of lib.dom.d.ts plus any\nconsumer-supplied `.d.ts` files in `\n[…]\n removes culture-sensitive case-folding\nfrom the matcher even though none of these patterns use `IgnoreCase`.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "perf: compile shared parser regexes",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:21:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "63f31ff1ba80511890840f9ed14c707f5f31fe15",
"body": "… interface\n\n`CSharpProperty.MappedTypeName` deliberately returns the *element* type\nfor array-shaped TypeScript types so that primitive-type lookups and\ndependency-graph walks can ignore the array wrapper. `CSharpObject.AppendProperty`\nalready re-attaches `[]` via a separate `IsArray` check, but th\n[…]\ng\nall three TypeScript array forms (`T[]`, `Array<T>`, `ReadonlyArray<T>`)\nagainst both `IsWebAssembly` arms.\n\nAll 198 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: preserve `[]` suffix when emitting array properties on top-level…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:18:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "af4f9eabc7f78beda830d21c12826adeb02474eb",
"body": "… lookups\n\nTwo small but correct improvements to the generator hot path:\n\n1. `JavaScriptInteropGenerator.Execute` now reads\n `context.CancellationToken` once and calls\n `ThrowIfCancellationRequested()` at the top of every outer-target\n iteration and inside the inner parser loop. Previously the\n[…]\ne across ~800KB of lib.dom.d.ts, so this O(1) lookup\n replaces what was effectively an O(n) per-check scan.\n\nAll 192 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "perf: thread CancellationToken through Execute and speed up primitive…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:16:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8fd9a5e78231085adcce6ebe7c58f99e63f294c7",
"body": "`SourceBuilder.AppendConditionalDelegateCallbackMethods` only called\n`ResetIndentationTo(level)` after the entire loop. Each iteration\ncalls `AppendRaw(..., postIncreaseIndentation: true)` (twice through\n`AppendParameters`), so successive callback methods were emitted at\never-deeper indentation. The\n[…]\nInvokable] block starts at the outer indentation level\nregardless of what the previous iteration left behind.\n\nAll 192 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: reset indentation per [JSInvokable] block in callback emit",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:13:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "58fa3cf5c470bf779d1e9ab14d966b123256e88d",
"body": "Adds five additional [InlineData] cases to GeneratorOutputValidityTests\nthat exercise less-trodden code paths through the generator:\n\n* LocalStorage on Server (generic + non-generic)\n* LocalStorage on WASM (non-generic)\n* Geolocation with OnlyGeneratePureJS = true\n* SessionStorage on WASM (generic)\n\n[…]\nttribute parsing, hosting-model branches,\nand the OnlyGeneratePureJS flag without requiring snapshot updates.\n\nAll 192 tests pass.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "test: expand generator output validity sweep with 5 new scenarios",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-16T02:13:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "838a48e900a4e0cee1df345d7d0d3144626bcbbb",
"body": "Until now `JSAutoInteropAttribute.TypeDeclarationSources` was a\ndocumented option that did nothing - the generator always parsed the\nembedded `lib.dom.d.ts` regardless. Consumers wanting to wire a\nnon-DOM TypeScript declaration file (their own ambient module, a\nthird-party `.d.ts`, or a polyfill typ\n[…]\nes_IsBenignNoOp` E2E test that pinned the old\nno-op behavior. Adds README documentation of the new option.\n\n187/187 tests passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "feat: wire TypeDeclarationSources into AdditionalTexts (T5.1)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T19:12:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3c57b258b0b70b80e34fda60443c16035020edbc",
"body": "The pre-audit attribute argument parser worked entirely on\n`AttributeArgumentSyntax.Expression.ToString()` and string-replaced\nquotes. That approach failed for:\n\n - String literals containing escape sequences. The naive\n `Replace(\"\\\"\", \"\")` mangled escaped quotes (`\"foo\\\"bar\"` became\n `foo\\ba\n[…]\ns) covering\nescape sequences, const references, nameof, verbatim strings,\nenum members, and bool literals.\n\n184/184 tests passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: parse attribute arguments via SemanticModel (T1.11)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T19:02:22Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5fcce88ff9ed0ab72f489d17f598fb311a20dad3",
"body": "Correctness fixes:\n\n - The \"Note\" about packaging incorrectly claimed Server packages\n expose a synchronous API. They expose `ValueTask`-based async\n methods through `IJSRuntime`; the WebAssembly variant uses\n `IJSInProcessRuntime` which is itself synchronous JS dispatch\n but still surf\n[…]\ndditions from the audit\n (previously the generator was silent on missing `partial`,\n unknown `TypeName`, or parse failures).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "docs: README accuracy pass (post-audit)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T18:58:12Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1f4e5c23ff5d55a943b5e2a4f7cb77d4af7da54c",
"body": "`ToClassString` was a single ~65-line method building DTO source by\nhand with raw interpolated `\\n`-terminated strings inside one giant\n`foreach` over properties. The shape made it hard to spot anything\ndistinct - the special-case DOMTimeStamp / EpochTimeStamp UTC accessor\nwas buried inside the prop\n[…]\nng mode.\n - Two new snapshot tests pin the DTO output specifically, so any\n future change to `ToClassString` will fail loudly.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "refactor: split CSharpObject.ToClassString into named helpers (T3.9)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T18:56:02Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "217b870cee43e0da70f6c594f8796637b4a17bac",
"body": "The implementation builder was a 286-line method with three structurally\ndistinct branches nested inside a `foreach (method)` loop:\n\n 1. Pure / non-bi-directional / JS-override invocations\n 2. Generic `TComponent` overload (bi-directional callback shape)\n 3. `Action<T>` callback overload (same ca\n[…]\nweep (`GeneratorOutputValidityTests`) confirms\n every generated tree still parses without syntax errors.\n\nSnapshot diff: empty.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "refactor: split CSharpTopLevelObject.ToImplementationString (T3.8)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T18:53:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "687cacbc6e331ffc4504feec10263acfd397a9b9",
"body": "T5.2 added `void -> void` to `TypeMap.PrimitiveTypes` so the parser\ncan short-circuit on void-returning methods instead of trying to\nrecurse into a non-existent `void` declaration. This (correctly)\nmade `IsPrimitiveType(\"void\")` return true for the first time.\n\nThat flipped a latent ordering bug in\n\n[…]\normalizeWhitespace removal, T3.8\n `ToImplementationString` refactor) producing malformed C#.\n\nTests: 176/176 (was 173 + 3 new).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "fix: emit `ValueTask` (not `ValueTask<void>`) for void Server methods",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T18:48:29Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3b80dc675c58ee775c21bbcb36553d4a83e50e5e",
"body": "Adds a lightweight string-snapshot helper plus 5 baseline snapshots\ncovering the most-exercised interop scenarios:\n\n - Geolocation_Wasm: interface, implementation, DI extension\n - Geolocation_Server: implementation (proves async ValueTask shape)\n - LocalStorage_Wasm_Generic: interface (proves JS\n[…]\nanother reference\nasset and disk layout convention isn't worth it for ~50 lines of\nhelper code.\n\nTests: 173/173 (was 168 + 5 new).\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "test: add hand-rolled snapshot harness for generator output",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T18:45:25Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5572a36f5d0b85a195a0551905cc81fb5709b9d0",
"body": "Adds primitive mappings for the TypeScript tokens that flow through\n`lib.dom.d.ts` but were previously unhandled by `TypeMap.PrimitiveTypes`.\nAnything not in the map falls through `IsPrimitiveType` to the\ndeclaration-recursion branch, which either emits an empty placeholder\nDTO (for declared interfa\n[…]\nrough a translated parameter type).\n - Negative cases - real DOM interface names still report `false`.\n\nTotal tests: 168 passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "feat: expand TypeMap to cover void/any/bigint/typed-arrays (T5.2)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-15T18:43:31Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b4356a1ba8ecf0c8ff74e0c40c53ef8b2ce3b2f9",
"body": "…T1.4)\n\nThe `TypeDeclarationSources` attribute parameter was documented as\naccepting \"URLs or file paths\" but the implementation is a no-op:\n`TypeDeclarationReader.Factory(string)` ignores its argument and\nreturns the default embedded-resource reader, with the URI handling\ncommented out.\n\nThis commi\n[…]\n the no-op contract so any future implementation has to\n actively change behavior, not just compile.\n\nTotal tests: 120 passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "refactor: clarify TypeDeclarationSources as reserved-for-future-use (…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-14T22:35:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "165ef6e8d907f9de2f677043b2a41ba8a229ca22",
"body": "…T3.10)\n\nPreviously the parser identified TypeScript callback interfaces using a\nbrittle `typeName.EndsWith(\"Callback\")` heuristic in two places:\n\n - `TypeDeclarationParser.ParseParameters` - to decide whether to call\n `ToAction(...)` and emit an `Action<T>` parameter, or `ToObject(...)`\n and\n[…]\negative cases (regular interfaces, properties-only, empty bodies,\n whitespace, non-interface input).\n\nTotal tests: 119 passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "refactor: replace `EndsWith(\"Callback\")` with shape-based detection (…",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-14T22:32:34Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4aacf1c24785fcf3684f461904420839e94da6d4",
"body": "Six end-to-end tests covering the actual shape of the generated\noutput across all four artifact kinds the generator emits per\n`[JSAutoInterop]` hit:\n\n- `Geolocation_InterfaceFile_DeclaresExpectedMembers` - the\n `IGeolocationService` interface file declares `ClearWatch`,\n `GetCurrentPosition`, `Wat\n[…]\ntic and hosting-model tests added earlier,\nthis closes the Tier 4 \"end-to-end generation\" coverage gap.\n\nTotal tests: 105 passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "test: add end-to-end snapshot-style generation tests (T4)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-14T22:29:04Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "279e214545947929f4fad5f44f297d3351ed93a6",
"body": "Four tests verifying that the `HostingModel = BlazorHostingModel.X`\nattribute argument correctly switches the generator between\nWebAssembly (synchronous, `IJSInProcessRuntime`) and Server\n(asynchronous, `IJSRuntime`) output shapes.\n\n- `Default_GeneratesWebAssemblyExtensions` - default mode emits\n `\n[…]\nse the interface filename also ends with that\nsuffix - exact filename match is the only safe comparison.\n\nTotal tests: 99 passing.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
"is_bot": false,
"headline": "test: add WebAssembly vs Server hosting-model regression tests (T4)",
"author_name": "David Pine",
"author_login": "IEvangelist",
"committed_at": "2026-05-14T22:28:06Z",
"body_truncated": true,
"is_coding_agent": true
}
],
"releases_count": 43,
"commits_last_year": 124,
"latest_release_at": "2026-07-24T18:48:52Z",
"latest_release_tag": "10.1.0",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 5,
"days_since_latest_release": 0,
"mean_days_between_releases": 142
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 71,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "Blazor.DOM",
"exists": true,
"license": null,
"keywords": [
"dotnet",
"dotnetcore",
"csharp",
"blazor",
"server",
"dom",
"interop",
"jsinterop"
],
"ecosystem": "nuget",
"matches_repo": true,
"registry_url": "https://www.nuget.org/packages/Blazor.DOM",
"is_deprecated": false,
"latest_version": "10.1.0",
"repository_url": "https://github.com/IEvangelist/blazorators",
"versions_count": 1,
"total_downloads": 0,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T18:52:39.883000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
},
{
"name": "Blazor.Clipboard",
"exists": true,
"license": null,
"keywords": [
"dotnet",
"blazor",
"server",
"dom",
"interop",
"clipboard"
],
"ecosystem": "nuget",
"matches_repo": true,
"registry_url": "https://www.nuget.org/packages/Blazor.Clipboard",
"is_deprecated": false,
"latest_version": "10.1.0",
"repository_url": "https://github.com/IEvangelist/blazorators",
"versions_count": 1,
"total_downloads": 0,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T18:52:38.400000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
},
{
"name": "Blazor.Credentials",
"exists": true,
"license": null,
"keywords": [
"dotnet",
"blazor",
"server",
"dom",
"interop",
"credentials",
"webauthn"
],
"ecosystem": "nuget",
"matches_repo": true,
"registry_url": "https://www.nuget.org/packages/Blazor.Credentials",
"is_deprecated": false,
"latest_version": "10.1.0",
"repository_url": "https://github.com/IEvangelist/blazorators",
"versions_count": 1,
"total_downloads": 0,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T18:52:39Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
},
{
"name": "Blazor.Geolocation",
"exists": true,
"license": null,
"keywords": [
"dotnet",
"dotnetcore",
"csharp",
"blazor",
"server",
"wasm",
"generators",
"sourcegen",
"roslyn"
],
"ecosystem": "nuget",
"matches_repo": true,
"registry_url": "https://www.nuget.org/packages/Blazor.Geolocation",
"is_deprecated": false,
"latest_version": "10.1.0",
"repository_url": "https://github.com/IEvangelist/blazorators",
"versions_count": 19,
"total_downloads": 94337,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T18:52:40.950000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
},
{
"name": "Blazor.LocalStorage",
"exists": true,
"license": null,
"keywords": [
"dotnet",
"dotnetcore",
"csharp",
"blazor",
"generators",
"sourcegen",
"roslyn"
],
"ecosystem": "nuget",
"matches_repo": true,
"registry_url": "https://www.nuget.org/packages/Blazor.LocalStorage",
"is_deprecated": false,
"latest_version": "10.1.0",
"repository_url": "https://github.com/IEvangelist/blazorators",
"versions_count": 19,
"total_downloads": 84532,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T18:52:41.440000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
},
{
"name": "Blazor.MediaDevices",
"exists": true,
"license": null,
"keywords": [
"dotnet",
"blazor",
"server",
"dom",
"interop",
"media-devices",
"get-user-media",
"display-capture"
],
"ecosystem": "nuget",
"matches_repo": true,
"registry_url": "https://www.nuget.org/packages/Blazor.MediaDevices",
"is_deprecated": false,
"latest_version": "10.1.0",
"repository_url": "https://github.com/IEvangelist/blazorators",
"versions_count": 1,
"total_downloads": 0,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2026-07-24T18:52:41.963000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 0
},
{
"name": "Blazor.Notifications",
"exists": true,
"license": null,
"keywords": [
"Blazor",
"Notifications",
"C#",
".NET",
"Standard",
".NET",
"Core"
],
"ecosystem": "nuget",
"matches_repo": false,
"registry_url": "https://www.nuget.org/packages/Blazor.Notifications",
"is_deprecated": false,
"latest_version": "0.2.0",
"repository_url": "https://github.com/vertonghenb/Blazor.Notifications",
"versions_count": 2,
"total_downloads": 3360,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": null,
"first_published_at": null,
"latest_published_at": "2018-06-19T23:35:33.853000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 2956
}
]
},
"popularity": {
"forks": 32,
"stars": 392,
"watchers": 13,
"fork_history": {
"days": [
{
"date": "2021-10-12",
"count": 1
},
{
"date": "2022-03-08",
"count": 1
},
{
"date": "2022-03-25",
"count": 1
},
{
"date": "2022-04-04",
"count": 1
},
{
"date": "2022-04-08",
"count": 1
},
{
"date": "2022-04-12",
"count": 3
},
{
"date": "2022-04-14",
"count": 1
},
{
"date": "2022-04-21",
"count": 1
},
{
"date": "2022-05-11",
"count": 1
},
{
"date": "2022-10-07",
"count": 1
},
{
"date": "2022-10-23",
"count": 1
},
{
"date": "2022-11-04",
"count": 1
},
{
"date": "2022-12-01",
"count": 1
},
{
"date": "2023-01-24",
"count": 1
},
{
"date": "2023-02-02",
"count": 1
},
{
"date": "2023-02-10",
"count": 1
},
{
"date": "2023-02-15",
"count": 1
},
{
"date": "2023-02-16",
"count": 1
},
{
"date": "2023-02-17",
"count": 1
},
{
"date": "2023-04-20",
"count": 1
},
{
"date": "2023-04-22",
"count": 1
},
{
"date": "2023-06-09",
"count": 1
},
{
"date": "2023-11-18",
"count": 1
},
{
"date": "2024-01-01",
"count": 1
},
{
"date": "2024-01-08",
"count": 1
},
{
"date": "2024-01-14",
"count": 1
},
{
"date": "2024-03-19",
"count": 1
},
{
"date": "2024-07-02",
"count": 1
},
{
"date": "2025-04-04",
"count": 1
},
{
"date": "2025-05-17",
"count": 1
}
],
"complete": true,
"collected": 32,
"total_forks": 32
},
"star_history": null,
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [
"samples"
],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"tools/Blazor.DOM.TypeScriptModel/tsconfig.json"
],
"toolchain_manifests": [
"samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj",
"samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj",
"src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj",
"src/Blazor.BrowserCoordination/Blazor.BrowserCoordination.csproj",
"src/Blazor.Clipboard.WebAssembly/Blazor.Clipboard.WebAssembly.csproj",
"src/Blazor.Clipboard/Blazor.Clipboard.csproj",
"src/Blazor.Credentials.WebAssembly/Blazor.Credentials.WebAssembly.csproj",
"src/Blazor.Credentials/Blazor.Credentials.csproj",
"src/Blazor.DOM.Generation/Blazor.DOM.Generation.csproj",
"src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj",
"src/Blazor.DOM/Blazor.DOM.csproj",
"src/Blazor.FileSystemAccess.WebAssembly/Blazor.FileSystemAccess.WebAssembly.csproj",
"src/Blazor.FileSystemAccess/Blazor.FileSystemAccess.csproj",
"src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj",
"src/Blazor.Geolocation/Blazor.Geolocation.csproj",
"src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"src/Blazor.MediaDevices.WebAssembly/Blazor.MediaDevices.WebAssembly.csproj",
"src/Blazor.MediaDevices/Blazor.MediaDevices.csproj",
"src/Blazor.Notifications.WebAssembly/Blazor.Notifications.WebAssembly.csproj",
"src/Blazor.Notifications/Blazor.Notifications.csproj",
"src/Blazor.OfflineStorage.WebAssembly/Blazor.OfflineStorage.WebAssembly.csproj",
"src/Blazor.OfflineStorage/Blazor.OfflineStorage.csproj",
"src/Blazor.Performance.WebAssembly/Blazor.Performance.WebAssembly.csproj",
"src/Blazor.Performance/Blazor.Performance.csproj",
"src/Blazor.Permissions.WebAssembly/Blazor.Permissions.WebAssembly.csproj",
"src/Blazor.Permissions/Blazor.Permissions.csproj",
"src/Blazor.Screen.WebAssembly/Blazor.Screen.WebAssembly.csproj",
"src/Blazor.Screen/Blazor.Screen.csproj",
"src/Blazor.Serialization/Blazor.Serialization.csproj",
"src/Blazor.SessionStorage.WebAssembly/Blazor.SessionStorage.WebAssembly.csproj",
"src/Blazor.SessionStorage/Blazor.SessionStorage.csproj",
"src/Blazor.Share.WebAssembly/Blazor.Share.WebAssembly.csproj",
"src/Blazor.Share/Blazor.Share.csproj",
"src/Blazor.SourceGenerators/Blazor.SourceGenerators.csproj",
"src/Blazor.SpeechRecognition.WebAssembly/Blazor.SpeechRecognition.WebAssembly.csproj",
"src/Blazor.SpeechRecognition/Blazor.SpeechRecognition.csproj",
"src/Blazor.SpeechSynthesis.WebAssembly/Blazor.SpeechSynthesis.WebAssembly.csproj",
"src/Blazor.SpeechSynthesis/Blazor.SpeechSynthesis.csproj",
"src/Blazor.StorageManagement.WebAssembly/Blazor.StorageManagement.WebAssembly.csproj",
"src/Blazor.StorageManagement/Blazor.StorageManagement.csproj",
"src/Blazor.WakeLock.WebAssembly/Blazor.WakeLock.WebAssembly.csproj",
"src/Blazor.WakeLock/Blazor.WakeLock.csproj",
"src/Blazor.WebCrypto.WebAssembly/Blazor.WebCrypto.WebAssembly.csproj",
"src/Blazor.WebCrypto/Blazor.WebCrypto.csproj",
"tests/Blazor.BrowserCoordination.Tests/Blazor.BrowserCoordination.Tests.csproj",
"tests/Blazor.Clipboard.Tests/Blazor.Clipboard.Tests.csproj",
"tests/Blazor.Credentials.Tests/Blazor.Credentials.Tests.csproj",
"tests/Blazor.DOM.Accessors.CompilationTests/Blazor.DOM.Accessors.CompilationTests.csproj",
"tests/Blazor.DOM.AdvancedTypes.CompilationTests/Blazor.DOM.AdvancedTypes.CompilationTests.csproj",
"tests/Blazor.DOM.CSharpGenerator.Tests/Blazor.DOM.CSharpGenerator.Tests.csproj",
"tests/Blazor.DOM.Generic.CompilationTests/Blazor.DOM.Generic.CompilationTests.csproj",
"tests/Blazor.DOM.GlobalNamespace.CompilationTests/Blazor.DOM.GlobalNamespace.CompilationTests.csproj",
"tests/Blazor.DOM.NonEventDeferrals.CompilationTests/Blazor.DOM.NonEventDeferrals.CompilationTests.csproj",
"tests/Blazor.DOM.ProfileRuntime/Blazor.DOM.ProfileRuntime.csproj",
"tests/Blazor.DOM.ResolvedFailures.CompilationTests/Blazor.DOM.ResolvedFailures.CompilationTests.csproj",
"tests/Blazor.DOM.Server.CompilationTests/Blazor.DOM.Server.CompilationTests.csproj",
"tests/Blazor.DOM.SupplementalBrowserApis.CompilationTests/Blazor.DOM.SupplementalBrowserApis.CompilationTests.csproj",
"tests/Blazor.DOM.Tests/Blazor.DOM.Tests.csproj",
"tests/Blazor.DOM.TypedEvents.CompilationTests/Blazor.DOM.TypedEvents.CompilationTests.csproj",
"tests/Blazor.DOM.TypedUnions.CompilationTests/Blazor.DOM.TypedUnions.CompilationTests.csproj",
"tests/Blazor.DOM.WakeLock.CompilationTests/Blazor.DOM.WakeLock.CompilationTests.csproj",
"tests/Blazor.DOM.WebAssembly.CompilationTests/Blazor.DOM.WebAssembly.CompilationTests.csproj",
"tests/Blazor.ExampleConsumer.EndToEndTests/Blazor.ExampleConsumer.EndToEndTests.csproj",
"tests/Blazor.FileSystemAccess.Tests/Blazor.FileSystemAccess.Tests.csproj",
"tests/Blazor.OfflineStorage.Tests/Blazor.OfflineStorage.Tests.csproj",
"tests/Blazor.Performance.Tests/Blazor.Performance.Tests.csproj",
"tests/Blazor.Screen.Tests/Blazor.Screen.Tests.csproj",
"tests/Blazor.Share.Tests/Blazor.Share.Tests.csproj",
"tests/Blazor.SourceGenerators.Tests/Blazor.SourceGenerators.Tests.csproj",
"tests/Blazor.StorageManagement.Tests/Blazor.StorageManagement.Tests.csproj",
"tests/Blazor.WakeLock.Tests/Blazor.WakeLock.Tests.csproj",
"tests/Blazor.WebCrypto.Tests/Blazor.WebCrypto.Tests.csproj",
"tools/Blazor.DOM.CSharpGenerator/Blazor.DOM.CSharpGenerator.csproj"
],
"largest_source_bytes": 816786,
"source_files_sampled": 429,
"oversized_source_files": 7,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [
{
"name": "fast-uri",
"direct": false,
"version": "3.1.3",
"severity": "high",
"ecosystem": "npm",
"cvss_score": 7.5,
"advisory_ids": [
"GHSA-v2hh-gcrm-f6hx"
],
"fixed_version": "4.1.1",
"advisory_count": 1,
"oldest_advisory_days": 2
},
{
"name": "ajv",
"direct": false,
"version": "8.17.1",
"severity": "moderate",
"ecosystem": "npm",
"cvss_score": 5.3,
"advisory_ids": [
"GHSA-2g4f-4pwh-qvx6"
],
"fixed_version": "8.18.0",
"advisory_count": 1,
"oldest_advisory_days": 162
}
],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {
"high": 1,
"moderate": 1
},
"advisory_count": 2,
"affected_count": 2,
"assessed_count": 19,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 19,
"direct_affected_count": 0
},
"ecosystems": [],
"dependencies": [
{
"name": "Microsoft.SourceLink.GitHub",
"manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "MinVer",
"manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.AspNetCore.Components.WebAssembly",
"manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.Extensions.DependencyInjection",
"manifest": "src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.SourceLink.GitHub",
"manifest": "src/Blazor.DOM/Blazor.DOM.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "MinVer",
"manifest": "src/Blazor.DOM/Blazor.DOM.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.AspNetCore.Components.Web",
"manifest": "src/Blazor.DOM/Blazor.DOM.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.Extensions.DependencyInjection",
"manifest": "src/Blazor.DOM/Blazor.DOM.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.JSInterop",
"manifest": "src/Blazor.DOM/Blazor.DOM.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.SourceLink.GitHub",
"manifest": "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "MinVer",
"manifest": "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.AspNetCore.Components.Web",
"manifest": "src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.SourceLink.GitHub",
"manifest": "src/Blazor.Geolocation/Blazor.Geolocation.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "MinVer",
"manifest": "src/Blazor.Geolocation/Blazor.Geolocation.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.AspNetCore.Components.Web",
"manifest": "src/Blazor.Geolocation/Blazor.Geolocation.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.SourceLink.GitHub",
"manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "MinVer",
"manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.Extensions.DependencyInjection",
"manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.Extensions.Primitives",
"manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.JSInterop",
"manifest": "src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.SourceLink.GitHub",
"manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "MinVer",
"manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.Extensions.DependencyInjection",
"manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.Extensions.Primitives",
"manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"ecosystem": "nuget",
"version_constraint": null
},
{
"name": "Microsoft.JSInterop",
"manifest": "src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"ecosystem": "nuget",
"version_constraint": null
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "Microsoft.AspNetCore.Components.Web",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.AspNetCore.Components.WebAssembly",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.Extensions.DependencyInjection",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.Extensions.Primitives",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.JSInterop",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.SourceLink.GitHub",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "MinVer",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "@pagefind/darwin-arm64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@pagefind/darwin-x64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@pagefind/freebsd-x64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@pagefind/linux-arm64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@pagefind/linux-x64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@pagefind/windows-arm64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@pagefind/windows-x64",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "@types/node",
"direct": false,
"version": "26.1.1",
"ecosystem": "npm"
},
{
"name": "@webgpu/types",
"direct": false,
"version": "0.1.71",
"ecosystem": "npm"
},
{
"name": "@webref/idl",
"direct": false,
"version": "3.81.3",
"ecosystem": "npm"
},
{
"name": "ajv",
"direct": false,
"version": "8.17.1",
"ecosystem": "npm"
},
{
"name": "fast-deep-equal",
"direct": false,
"version": "3.1.3",
"ecosystem": "npm"
},
{
"name": "fast-uri",
"direct": false,
"version": "3.1.3",
"ecosystem": "npm"
},
{
"name": "json-schema-traverse",
"direct": false,
"version": "1.0.0",
"ecosystem": "npm"
},
{
"name": "pagefind",
"direct": false,
"version": "1.5.0",
"ecosystem": "npm"
},
{
"name": "require-from-string",
"direct": false,
"version": "2.0.2",
"ecosystem": "npm"
},
{
"name": "typescript",
"direct": false,
"version": "5.9.3",
"ecosystem": "npm"
},
{
"name": "undici-types",
"direct": false,
"version": "8.3.0",
"ecosystem": "npm"
},
{
"name": "webidl2",
"direct": false,
"version": "24.5.0",
"ecosystem": "npm"
},
{
"name": "Basic.Reference.Assemblies",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "coverlet.collector",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Deque.AxeCore.Playwright",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Humanizer.Core",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.AspNetCore.Components.WebAssembly.DevServer",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.CodeAnalysis.Analyzers",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.CodeAnalysis.CSharp",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.NET.Test.Sdk",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Microsoft.Playwright",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "System.Reactive.Linq",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "xunit",
"direct": false,
"version": null,
"ecosystem": "nuget"
},
{
"name": "xunit.runner.visualstudio",
"direct": false,
"version": null,
"ecosystem": "nuget"
}
],
"collected": true,
"truncated": false,
"total_count": 38,
"direct_count": 7,
"indirect_count": 31
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 28,
"open_issues": 0,
"closed_ratio": 1,
"closed_issues": 32,
"closed_unmerged_prs": 3
},
"bus_factor": 1,
"bot_contributors": 2,
"top_contributors": [
{
"type": "User",
"login": "IEvangelist",
"commits": 300,
"avatar_url": "https://avatars.githubusercontent.com/u/7679720?v=4"
},
{
"type": "User",
"login": "WeihanLi",
"commits": 3,
"avatar_url": "https://avatars.githubusercontent.com/u/7604648?v=4"
},
{
"type": "User",
"login": "colindembovsky",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/1932561?v=4"
},
{
"type": "User",
"login": "taori",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/5545184?v=4"
},
{
"type": "User",
"login": "robertmclaws",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/1657085?v=4"
},
{
"type": "User",
"login": "TanayParikh",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/14852843?v=4"
}
],
"contributors_sampled": 6,
"top_contributor_share": 0.974
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"build-validation.yml",
"pr-validation.yml",
"publish-nuget.yml",
"publish-to-gh-pages.yml"
],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [
"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": 7,
"reason": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7",
"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/28 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 6 contributing companies or organizations",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 0 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": 1,
"reason": "dependency not pinned by hash detected -- score normalized to 1",
"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": 10,
"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": "abe9091425dc6bd6126011894642fc370bc2876d",
"ran_at": "2026-07-24T19:01:55Z",
"aggregate_score": 5.4,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T19:01:34Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-23T20:57:01Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/IEvangelist/blazorators",
"host": "github.com",
"name": "blazorators",
"owner": "IEvangelist"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"security": 63,
"vitality": 74,
"community": 64,
"governance": 66,
"engineering": 71
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 74,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"commits_last_year": 124,
"human_commit_share": 1,
"days_since_last_push": 0,
"active_weeks_last_year": 5
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "5/52 weeks with commits",
"points": 3.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 5
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "124 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 124
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "good",
"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": 84,
"inputs": {
"releases_count": 43,
"latest_release_tag": "10.1.0",
"releases_from_tags": false,
"days_since_latest_release": 0,
"mean_days_between_releases": 142
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "43 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 43
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~142 days",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 142
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 0,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 0 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 0
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 64,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "moderate",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"forks": 32,
"stars": 392,
"watchers": 13,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "392 stars",
"points": 42,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 392
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "32 forks",
"points": 12.4,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 32
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "13 watchers",
"points": 6,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 13
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": true,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 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": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 68,
"inputs": {
"packages": [
"Blazor.DOM",
"Blazor.Clipboard",
"Blazor.Credentials",
"Blazor.Geolocation",
"Blazor.LocalStorage",
"Blazor.MediaDevices"
],
"dependents": null,
"ecosystems": "nuget",
"total_downloads": 178869,
"monthly_downloads": null
},
"components": [
{
"key": "total_downloads",
"name": "Total downloads",
"detail": "178,869 downloads all-time across nuget",
"points": 54.6,
"status": "partial",
"details": [
{
"code": "downloads_total",
"params": {
"count": 178869,
"ecosystems": "nuget"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 66,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 28,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 6,
"top_contributor_share": 0.974
},
"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 97% of commits",
"points": 0.6,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 97
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "6 contributors",
"points": 8.1,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 6
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 6 contributing companies or organizations",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 81,
"inputs": {
"merged_prs": 28,
"open_issues": 0,
"closed_issues": 32,
"issue_closed_ratio": 1,
"closed_unmerged_prs": 3
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "100% of issues closed",
"points": 46.8,
"status": "met",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 100
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "28/31 decided PRs merged",
"points": 34.5,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 28,
"decided": 31
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/28 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "good",
"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": 71,
"inputs": {
"followers": 1017,
"owner_type": "User",
"is_verified": null,
"owner_login": "IEvangelist",
"public_repos": 336,
"account_age_days": 4445
},
"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": "1,017 followers of IEvangelist",
"points": 21.6,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 1017,
"login": "IEvangelist"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "336 public repos, account ~12 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 336
}
},
{
"code": "account_age_years",
"params": {
"years": 12
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"Blazor.DOM",
"Blazor.Clipboard",
"Blazor.Credentials",
"Blazor.Geolocation",
"Blazor.LocalStorage",
"Blazor.MediaDevices"
],
"ecosystems": "nuget",
"any_deprecated": false,
"min_days_since_publish": 0
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "6 package(s) on nuget",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 6,
"ecosystems": "nuget"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 0 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 0
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "19 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 19
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "good",
"name": "Engineering Quality",
"value": 71,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 68,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "4 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 4
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 6.4,
"status": "met",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7",
"points": 14,
"status": "partial",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "good",
"name": "Documentation",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"topics": [
"blazor",
"blazor-webassembly",
"javascript",
"typescript",
"javascript-interop",
"source-generators",
"hacktoberfest"
],
"has_wiki": true,
"homepage": "https://ievangelist.github.io/blazorators/",
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": "https://ievangelist.github.io/blazorators/",
"points": 15,
"status": "met",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "7 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 7
}
}
],
"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": 63,
"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": 54,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 5.4
},
"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": "3 out of 4 merged PRs checked by a CI test -- score normalized to 7",
"points": 1.8,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/28 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 6 contributing companies or organizations",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 0 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 1",
"points": 0.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": 5,
"status": "met",
"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, No advisories left outstanding. Remaining weights renormalized. Matched 19 resolved dependencies against OSV; 19 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). 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",
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_repository",
"params": {
"assessed": 19
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 19
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 2,
"affected_packages": 2,
"assessed_packages": 19,
"unassessed_packages": 19,
"affected_by_severity": "high 1, moderate 1",
"direct_affected_packages": 0
},
"components": [
{
"key": "direct_dependencies_free_of_known_advisories",
"name": "Direct dependencies free of known advisories",
"detail": "no direct dependency carries a known advisory",
"points": 35,
"status": "met",
"details": [
{
"code": "no_direct_advisories",
"params": {}
}
],
"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 carries a publication date",
"points": 0,
"status": "excluded",
"details": [
{
"code": "advisories_no_publication_date",
"params": {}
}
],
"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": 19,
"malicious_packages": 0,
"direct_malicious_packages": 0,
"withdrawn_malicious_packages": 0,
"installable_malicious_packages": 0
},
"components": [
{
"key": "no_dependency_reported_as_a_malicious_package",
"name": "No dependency reported as a malicious package",
"detail": "no dependency is reported as a malicious package",
"points": 100,
"status": "met",
"details": [
{
"code": "no_malicious_dependencies",
"params": {}
}
],
"max_points": 100
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 14
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 60,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.92,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "92 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 92,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 67,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [
"package-lock.json"
],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"tools/Blazor.DOM.TypeScriptModel/tsconfig.json"
],
"agent_commit_share": 0.98,
"toolchain_manifests": [
"samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj",
"samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj",
"src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj",
"src/Blazor.BrowserCoordination/Blazor.BrowserCoordination.csproj",
"src/Blazor.Clipboard.WebAssembly/Blazor.Clipboard.WebAssembly.csproj",
"src/Blazor.Clipboard/Blazor.Clipboard.csproj",
"src/Blazor.Credentials.WebAssembly/Blazor.Credentials.WebAssembly.csproj",
"src/Blazor.Credentials/Blazor.Credentials.csproj",
"src/Blazor.DOM.Generation/Blazor.DOM.Generation.csproj",
"src/Blazor.DOM.WebAssembly/Blazor.DOM.WebAssembly.csproj",
"src/Blazor.DOM/Blazor.DOM.csproj",
"src/Blazor.FileSystemAccess.WebAssembly/Blazor.FileSystemAccess.WebAssembly.csproj",
"src/Blazor.FileSystemAccess/Blazor.FileSystemAccess.csproj",
"src/Blazor.Geolocation.WebAssembly/Blazor.Geolocation.WebAssembly.csproj",
"src/Blazor.Geolocation/Blazor.Geolocation.csproj",
"src/Blazor.LocalStorage.WebAssembly/Blazor.LocalStorage.WebAssembly.csproj",
"src/Blazor.LocalStorage/Blazor.LocalStorage.csproj",
"src/Blazor.MediaDevices.WebAssembly/Blazor.MediaDevices.WebAssembly.csproj",
"src/Blazor.MediaDevices/Blazor.MediaDevices.csproj",
"src/Blazor.Notifications.WebAssembly/Blazor.Notifications.WebAssembly.csproj",
"src/Blazor.Notifications/Blazor.Notifications.csproj",
"src/Blazor.OfflineStorage.WebAssembly/Blazor.OfflineStorage.WebAssembly.csproj",
"src/Blazor.OfflineStorage/Blazor.OfflineStorage.csproj",
"src/Blazor.Performance.WebAssembly/Blazor.Performance.WebAssembly.csproj",
"src/Blazor.Performance/Blazor.Performance.csproj",
"src/Blazor.Permissions.WebAssembly/Blazor.Permissions.WebAssembly.csproj",
"src/Blazor.Permissions/Blazor.Permissions.csproj",
"src/Blazor.Screen.WebAssembly/Blazor.Screen.WebAssembly.csproj",
"src/Blazor.Screen/Blazor.Screen.csproj",
"src/Blazor.Serialization/Blazor.Serialization.csproj",
"src/Blazor.SessionStorage.WebAssembly/Blazor.SessionStorage.WebAssembly.csproj",
"src/Blazor.SessionStorage/Blazor.SessionStorage.csproj",
"src/Blazor.Share.WebAssembly/Blazor.Share.WebAssembly.csproj",
"src/Blazor.Share/Blazor.Share.csproj",
"src/Blazor.SourceGenerators/Blazor.SourceGenerators.csproj",
"src/Blazor.SpeechRecognition.WebAssembly/Blazor.SpeechRecognition.WebAssembly.csproj",
"src/Blazor.SpeechRecognition/Blazor.SpeechRecognition.csproj",
"src/Blazor.SpeechSynthesis.WebAssembly/Blazor.SpeechSynthesis.WebAssembly.csproj",
"src/Blazor.SpeechSynthesis/Blazor.SpeechSynthesis.csproj",
"src/Blazor.StorageManagement.WebAssembly/Blazor.StorageManagement.WebAssembly.csproj",
"src/Blazor.StorageManagement/Blazor.StorageManagement.csproj",
"src/Blazor.WakeLock.WebAssembly/Blazor.WakeLock.WebAssembly.csproj",
"src/Blazor.WakeLock/Blazor.WakeLock.csproj",
"src/Blazor.WebCrypto.WebAssembly/Blazor.WebCrypto.WebAssembly.csproj",
"src/Blazor.WebCrypto/Blazor.WebCrypto.csproj",
"tests/Blazor.BrowserCoordination.Tests/Blazor.BrowserCoordination.Tests.csproj",
"tests/Blazor.Clipboard.Tests/Blazor.Clipboard.Tests.csproj",
"tests/Blazor.Credentials.Tests/Blazor.Credentials.Tests.csproj",
"tests/Blazor.DOM.Accessors.CompilationTests/Blazor.DOM.Accessors.CompilationTests.csproj",
"tests/Blazor.DOM.AdvancedTypes.CompilationTests/Blazor.DOM.AdvancedTypes.CompilationTests.csproj",
"tests/Blazor.DOM.CSharpGenerator.Tests/Blazor.DOM.CSharpGenerator.Tests.csproj",
"tests/Blazor.DOM.Generic.CompilationTests/Blazor.DOM.Generic.CompilationTests.csproj",
"tests/Blazor.DOM.GlobalNamespace.CompilationTests/Blazor.DOM.GlobalNamespace.CompilationTests.csproj",
"tests/Blazor.DOM.NonEventDeferrals.CompilationTests/Blazor.DOM.NonEventDeferrals.CompilationTests.csproj",
"tests/Blazor.DOM.ProfileRuntime/Blazor.DOM.ProfileRuntime.csproj",
"tests/Blazor.DOM.ResolvedFailures.CompilationTests/Blazor.DOM.ResolvedFailures.CompilationTests.csproj",
"tests/Blazor.DOM.Server.CompilationTests/Blazor.DOM.Server.CompilationTests.csproj",
"tests/Blazor.DOM.SupplementalBrowserApis.CompilationTests/Blazor.DOM.SupplementalBrowserApis.CompilationTests.csproj",
"tests/Blazor.DOM.Tests/Blazor.DOM.Tests.csproj",
"tests/Blazor.DOM.TypedEvents.CompilationTests/Blazor.DOM.TypedEvents.CompilationTests.csproj",
"tests/Blazor.DOM.TypedUnions.CompilationTests/Blazor.DOM.TypedUnions.CompilationTests.csproj",
"tests/Blazor.DOM.WakeLock.CompilationTests/Blazor.DOM.WakeLock.CompilationTests.csproj",
"tests/Blazor.DOM.WebAssembly.CompilationTests/Blazor.DOM.WebAssembly.CompilationTests.csproj",
"tests/Blazor.ExampleConsumer.EndToEndTests/Blazor.ExampleConsumer.EndToEndTests.csproj",
"tests/Blazor.FileSystemAccess.Tests/Blazor.FileSystemAccess.Tests.csproj",
"tests/Blazor.OfflineStorage.Tests/Blazor.OfflineStorage.Tests.csproj",
"tests/Blazor.Performance.Tests/Blazor.Performance.Tests.csproj",
"tests/Blazor.Screen.Tests/Blazor.Screen.Tests.csproj",
"tests/Blazor.Share.Tests/Blazor.Share.Tests.csproj",
"tests/Blazor.SourceGenerators.Tests/Blazor.SourceGenerators.Tests.csproj",
"tests/Blazor.StorageManagement.Tests/Blazor.StorageManagement.Tests.csproj",
"tests/Blazor.WakeLock.Tests/Blazor.WakeLock.Tests.csproj",
"tests/Blazor.WebCrypto.Tests/Blazor.WebCrypto.Tests.csproj",
"tools/Blazor.DOM.CSharpGenerator/Blazor.DOM.CSharpGenerator.csproj"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj, samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj, src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "samples/Blazor.ExampleConsumer/Blazor.ExampleConsumer.csproj, samples/BlazorServer.ExampleConsumer/BlazorServer.ExampleConsumer.csproj, src/Blazor.BrowserCoordination.WebAssembly/Blazor.BrowserCoordination.WebAssembly.csproj"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tools/Blazor.DOM.TypeScriptModel/tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tools/Blazor.DOM.TypeScriptModel/tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "lockfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "lockfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "98 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 98,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 1",
"points": 1,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 99,
"inputs": {
"primary_language": "C#",
"largest_source_bytes": 816786,
"source_files_sampled": 429,
"oversized_source_files": 7
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "C# (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "C#"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "7/429 source files over 60KB",
"points": 54.1,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 429,
"oversized": 7
}
}
],
"max_points": 55
}
]
},
{
"key": "ai_interfaces",
"band": "at_risk",
"name": "Machine-readable interfaces",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"example_dirs": [
"samples"
],
"has_mcp_signal": false,
"api_schema_files": []
},
"components": [
{
"key": "api_schema_openapi_graphql_proto",
"name": "API schema (OpenAPI/GraphQL/proto)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 40
},
{
"key": "mcp_server",
"name": "MCP server",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "runnable_examples",
"name": "Runnable examples",
"detail": "samples",
"points": 40,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "samples"
}
}
],
"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",
"nuget package 'Blazor.Notifications' points at a different repository (https://github.com/vertonghenb/Blazor.Notifications); excluded from ecosystem scoring",
"Could not fetch nuget package 'Blazor.DOM.WebAssembly' from its registry"
],
"report_type": "repository",
"generated_at": "2026-07-24T19:02:09.211042Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/i/IEvangelist/blazorators.svg",
"full_name": "IEvangelist/blazorators",
"license_state": "standard",
"license_spdx": "MIT"
}Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.
Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v1.13.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.
Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistiken — NuGet.