JSON-Rohbericht maschinenlesbar
{
"data": {
"repo": {
"topics": [
"accessibility",
"ai",
"automation",
"csharp",
"dotnet",
"hacktoberfest",
"homelab",
"jellyfin",
"jellyfin-plugin",
"media-management",
"media-server",
"open-source",
"parakeet",
"self-hosted",
"speech-to-text",
"stt",
"subtitles",
"transcription",
"whisper",
"whisper-cpp"
],
"is_fork": false,
"size_kb": 1228,
"has_wiki": true,
"homepage": null,
"languages": {
"C#": 943627,
"HTML": 166918,
"Shell": 3743,
"Python": 38452,
"Dockerfile": 7271,
"JavaScript": 14959
},
"pushed_at": "2026-07-20T23:25:42Z",
"created_at": "2025-12-05T21:24:26Z",
"owner_type": "User",
"updated_at": "2026-07-23T21:00:26Z",
"description": "Jellyfin plugin for local AI-powered subtitle generation using Whisper - all processing stays on your server",
"is_archived": false,
"is_disabled": false,
"license_spdx": "GPL-3.0",
"default_branch": "main",
"license_spdx_raw": "GPL-3.0",
"primary_language": "C#",
"significant_languages": [
"C#",
"HTML"
]
},
"owner": {
"blog": "https://geiser.cloud",
"name": "Sergio Fernández",
"type": "User",
"login": "GeiserX",
"company": null,
"location": "Murcia, Spain",
"followers": 113,
"avatar_url": "https://avatars.githubusercontent.com/u/9169332?v=4",
"created_at": "2014-10-12T21:57:52Z",
"is_verified": null,
"public_repos": 186,
"account_age_days": 4302
},
"license": {
"state": "standard",
"spdx_id": "GPL-3.0",
"raw_spdx": "GPL-3.0",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v4.3.1.0",
"kind": "other",
"published_at": "2026-07-13T21:26:45Z"
},
{
"tag": "v4.3.0.0",
"kind": "other",
"published_at": "2026-07-12T20:44:05Z"
},
{
"tag": "v4.2.0.0",
"kind": "other",
"published_at": "2026-07-10T00:16:49Z"
},
{
"tag": "v4.1.1.0",
"kind": "other",
"published_at": "2026-07-07T00:17:01Z"
},
{
"tag": "v4.1.0.0",
"kind": "other",
"published_at": "2026-07-06T22:36:30Z"
},
{
"tag": "v4.0.0.0",
"kind": "other",
"published_at": "2026-07-06T17:26:38Z"
},
{
"tag": "v3.29.0.0",
"kind": "other",
"published_at": "2026-07-06T12:09:11Z"
},
{
"tag": "v3.28.0.0",
"kind": "other",
"published_at": "2026-07-05T16:53:42Z"
},
{
"tag": "v3.27.0.0",
"kind": "other",
"published_at": "2026-07-05T13:32:38Z"
},
{
"tag": "v3.26.0.1",
"kind": "other",
"published_at": "2026-07-02T16:50:37Z"
},
{
"tag": "v3.26.0.0",
"kind": "other",
"published_at": "2026-07-02T15:45:48Z"
},
{
"tag": "v3.25.0.0",
"kind": "other",
"published_at": "2026-07-01T14:01:06Z"
},
{
"tag": "v3.24.0.0",
"kind": "other",
"published_at": "2026-06-29T09:59:45Z"
},
{
"tag": "v3.23.0.0",
"kind": "other",
"published_at": "2026-06-28T13:03:03Z"
},
{
"tag": "v3.22.1.0",
"kind": "other",
"published_at": "2026-06-27T23:45:07Z"
},
{
"tag": "v3.22.0.0",
"kind": "other",
"published_at": "2026-06-26T17:57:25Z"
},
{
"tag": "v3.21.3.0",
"kind": "other",
"published_at": "2026-06-26T15:59:43Z"
},
{
"tag": "v3.21.2.0",
"kind": "other",
"published_at": "2026-06-26T10:37:09Z"
},
{
"tag": "v3.21.1.0",
"kind": "other",
"published_at": "2026-06-25T20:50:33Z"
},
{
"tag": "v3.21.0.0",
"kind": "other",
"published_at": "2026-06-25T15:25:47Z"
},
{
"tag": "v3.20.0.0",
"kind": "other",
"published_at": "2026-06-18T19:31:40Z"
},
{
"tag": "v3.19.1.0",
"kind": "other",
"published_at": "2026-06-18T13:52:23Z"
},
{
"tag": "v3.19.0.0",
"kind": "other",
"published_at": "2026-06-16T18:14:29Z"
},
{
"tag": "v3.18.8.0",
"kind": "other",
"published_at": "2026-06-16T14:16:47Z"
},
{
"tag": "v3.18.7.0",
"kind": "other",
"published_at": "2026-06-14T23:07:27Z"
},
{
"tag": "v3.18.6.0",
"kind": "other",
"published_at": "2026-06-13T20:37:17Z"
},
{
"tag": "v3.18.5.0",
"kind": "other",
"published_at": "2026-06-07T13:48:48Z"
},
{
"tag": "v3.18.4.0",
"kind": "other",
"published_at": "2026-06-06T22:58:14Z"
},
{
"tag": "v3.18.3.0",
"kind": "other",
"published_at": "2026-06-06T22:43:26Z"
},
{
"tag": "v3.18.2.0",
"kind": "other",
"published_at": "2026-06-06T17:31:36Z"
},
{
"tag": "v3.18.1.0",
"kind": "other",
"published_at": "2026-05-25T18:24:49Z"
},
{
"tag": "v3.18.0.0",
"kind": "other",
"published_at": "2026-05-19T09:33:59Z"
},
{
"tag": "v3.17.1.0",
"kind": "other",
"published_at": "2026-05-15T19:15:08Z"
},
{
"tag": "v3.17.0.0",
"kind": "other",
"published_at": "2026-05-12T09:15:19Z"
},
{
"tag": "v3.16.0.0",
"kind": "other",
"published_at": "2026-05-11T10:49:18Z"
},
{
"tag": "v3.15.0.0",
"kind": "other",
"published_at": "2026-05-11T09:36:39Z"
},
{
"tag": "v3.14.2.0",
"kind": "other",
"published_at": "2026-05-07T22:59:39Z"
},
{
"tag": "v3.14.1.0",
"kind": "other",
"published_at": "2026-05-07T21:48:47Z"
},
{
"tag": "v3.14.0.0",
"kind": "other",
"published_at": "2026-05-05T10:59:01Z"
},
{
"tag": "v3.13.2.0",
"kind": "other",
"published_at": "2026-05-04T23:15:18Z"
},
{
"tag": "v3.13.1.0",
"kind": "other",
"published_at": "2026-05-04T23:10:15Z"
},
{
"tag": "v3.13.0.0",
"kind": "other",
"published_at": "2026-05-04T17:48:45Z"
},
{
"tag": "v3.12.2.0",
"kind": "other",
"published_at": "2026-04-29T19:29:43Z"
},
{
"tag": "v3.12.1.0",
"kind": "other",
"published_at": "2026-04-28T23:39:25Z"
},
{
"tag": "v3.12.0.0",
"kind": "other",
"published_at": "2026-04-28T09:43:25Z"
},
{
"tag": "v3.11.3.0",
"kind": "other",
"published_at": "2026-04-23T08:45:37Z"
},
{
"tag": "v3.11.2.0",
"kind": "other",
"published_at": "2026-04-18T11:55:38Z"
},
{
"tag": "v3.11.1.0",
"kind": "other",
"published_at": "2026-04-17T22:55:53Z"
},
{
"tag": "v3.11.0.0",
"kind": "other",
"published_at": "2026-04-16T11:52:32Z"
},
{
"tag": "v3.10.0.0",
"kind": "other",
"published_at": "2026-04-16T08:43:14Z"
},
{
"tag": "v3.9.1.0",
"kind": "other",
"published_at": "2026-04-15T11:51:43Z"
},
{
"tag": "v3.9.0.0",
"kind": "other",
"published_at": "2026-04-15T10:52:14Z"
},
{
"tag": "v3.8.5.0",
"kind": "other",
"published_at": "2026-04-15T09:45:40Z"
},
{
"tag": "v3.8.4.0",
"kind": "other",
"published_at": "2026-04-14T23:19:28Z"
},
{
"tag": "v3.8.3.0",
"kind": "other",
"published_at": "2026-04-14T23:15:00Z"
},
{
"tag": "v3.8.2.0",
"kind": "other",
"published_at": "2026-04-14T23:11:55Z"
},
{
"tag": "v3.8.1.0",
"kind": "other",
"published_at": "2026-04-14T23:07:09Z"
},
{
"tag": "v3.8.0.0",
"kind": "other",
"published_at": "2026-04-14T23:01:43Z"
},
{
"tag": "v3.7.1.0",
"kind": "other",
"published_at": "2026-04-13T15:50:13Z"
},
{
"tag": "v3.7.0.0",
"kind": "other",
"published_at": "2026-04-13T08:56:49Z"
},
{
"tag": "v3.6.0.0",
"kind": "other",
"published_at": "2026-04-13T08:13:50Z"
},
{
"tag": "v3.5.0.0",
"kind": "other",
"published_at": "2026-04-11T21:32:24Z"
},
{
"tag": "v3.4.0.0",
"kind": "other",
"published_at": "2026-04-11T19:26:48Z"
},
{
"tag": "v3.3.0.0",
"kind": "other",
"published_at": "2026-04-11T18:16:40Z"
},
{
"tag": "v3.2.0.0",
"kind": "other",
"published_at": "2026-04-10T22:38:50Z"
},
{
"tag": "v3.1.5.0",
"kind": "other",
"published_at": "2026-04-08T08:42:09Z"
},
{
"tag": "v3.1.4.0",
"kind": "other",
"published_at": "2026-04-06T23:02:46Z"
},
{
"tag": "v3.1.3.0",
"kind": "other",
"published_at": "2026-04-06T22:57:15Z"
},
{
"tag": "v3.1.2.0",
"kind": "other",
"published_at": "2026-04-06T22:48:05Z"
},
{
"tag": "v3.1.1.0",
"kind": "other",
"published_at": "2026-04-06T18:24:54Z"
},
{
"tag": "v3.1.1",
"kind": "patch",
"published_at": "2026-04-06T18:24:26Z"
},
{
"tag": "v3.1.0.0",
"kind": "other",
"published_at": "2026-04-06T15:39:44Z"
},
{
"tag": "v3.0.0.0",
"kind": "other",
"published_at": "2026-04-06T15:08:41Z"
},
{
"tag": "v2.5.0.0",
"kind": "other",
"published_at": "2026-04-03T08:44:17Z"
},
{
"tag": "v2.4.0.0",
"kind": "other",
"published_at": "2026-03-25T19:42:27Z"
},
{
"tag": "v2.3.0.0",
"kind": "other",
"published_at": "2026-03-25T09:39:15Z"
},
{
"tag": "v2.2.0.0",
"kind": "other",
"published_at": "2026-03-25T09:22:13Z"
},
{
"tag": "v2.1.0.0",
"kind": "other",
"published_at": "2026-03-24T21:15:25Z"
},
{
"tag": "v2.0.0.0",
"kind": "other",
"published_at": "2026-03-24T15:30:59Z"
},
{
"tag": "v1.0.4.2",
"kind": "other",
"published_at": "2025-12-09T21:29:34Z"
},
{
"tag": "v1.0.4.1",
"kind": "other",
"published_at": "2025-12-09T19:45:09Z"
},
{
"tag": "v1.0.4.0",
"kind": "other",
"published_at": "2025-12-09T19:40:16Z"
},
{
"tag": "v1.0.3.5",
"kind": "other",
"published_at": "2025-12-09T19:32:48Z"
},
{
"tag": "v1.0.3.4",
"kind": "other",
"published_at": "2025-12-09T19:31:51Z"
},
{
"tag": "v1.0.3.3",
"kind": "other",
"published_at": "2025-12-09T19:21:33Z"
},
{
"tag": "v1.0.3.2",
"kind": "other",
"published_at": "2025-12-09T19:16:35Z"
},
{
"tag": "v1.0.3.1",
"kind": "other",
"published_at": "2025-12-09T19:10:25Z"
},
{
"tag": "v1.0.3.0",
"kind": "other",
"published_at": "2025-12-09T18:58:16Z"
},
{
"tag": "v1.0.2.0",
"kind": "other",
"published_at": "2025-12-07T18:10:14Z"
},
{
"tag": "v1.0.1.0",
"kind": "other",
"published_at": "2025-12-05T22:15:03Z"
},
{
"tag": "v1.0.0.0",
"kind": "other",
"published_at": "2025-12-05T21:32:34Z"
}
],
"recent_commits": [
{
"oid": "129503878cd479d1068694641a2ec0eb20ac9781",
"body": "Bumps Microsoft.Extensions.Http from 9.0.17 to 9.0.18\n\n---\nupdated-dependencies:\n- dependency-name: Microsoft.Extensions.Http\n dependency-version: 9.0.18\n dependency-type: direct:production\n update-type: version-update:semver-patch\n dependency-group: minor-and-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "deps: Bump the minor-and-patch group with 1 update (#137)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-20T23:25:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "db4a48b99546e5fc3ce0257b03a07e7eb96b04c6",
"body": "…-endpoint concurrency + worker self-heal (#136)\n\n* fix(worker): serialise inference + self-heal a wedged whisper-server\n\nwhisper.cpp's whisper-server runs one inference at a time, so a request arriving mid-transcription\nsits in the OS accept queue behind it — invisible to the disconnect-watcher — a\n[…]\n the exact\ncompute_backend_timeout scaling the review corrected (long film not guillotined, still bounded)\nand the inflight semaphore's exactly-once/cancelled-client/over-release accounting. 10 tests.",
"is_bot": false,
"headline": "fix(v4.3.1): eliminate M4 worker stalls — lightweight detection + per…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-13T21:23:29Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6d7280f1fe02b403a3d2170d4a14f479a8fda16e",
"body": null,
"is_bot": false,
"headline": "docs: worklog — configurable naming shipped + released 4.3.0.0 (#135)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-13T20:45:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8c13fb70b1d484c3ee288e144a567ef22a215576",
"body": "…sperSubs) + release 4.3.0.0 (#134)\n\n* feat: configurable subtitle filename naming with brand label (default WhisperSubs)\n\nAdds SubtitleLabel + SubtitleFilenameTemplate config (default {name}.{lang}.{label}{.type}\n-> Episode.en.WhisperSubs.srt), so the Jellyfin picker reads 'WhisperSubs - English' i\n[…]\n Classify (legacy OR new), switched hasFullSrt and\nthe status full-bucket to Classify==Full, and delete a resumed legacy partial after the canonical\nwrite. +4 regression tests. 1059 tests, 0 warnings.",
"is_bot": false,
"headline": "feat: configurable subtitle filename naming (brand label, default Whi…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-12T20:39:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "60325c5276ef55ecdb837d2dd700fb3e111a6ae3",
"body": "release: 4.2.0.0 — hot-add workers, multi-audio toggle, auto-retry, GenerateAll allow-list",
"is_bot": false,
"headline": "Merge pull request #133 from GeiserX/v4-dev",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-10T00:13:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "11b5cc62fd87203c33d4c577b063a2b307380bd0",
"body": "… auto-retry, GenerateAll allow-list)",
"is_bot": false,
"headline": "release: bump plugin to 4.2.0.0 (hot-add workers, multi-audio toggle,…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-10T00:10:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "af857afbed4c9f3ec8a7aac300c1ac142f8822f6",
"body": "… all beads resolved",
"is_bot": false,
"headline": "docs(loop): /sergio-loop complete — 9gq merged (#132), ezg won't-fix,…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T23:42:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6eb3b430411ab38c88f9413b87a24db9397f7f7c",
"body": "…isper-subs-9gq) (#132)\n\n* feat: hot-add workers to the live pool without a restart (whisper-subs-9gq)\n\nA worker added to the config mid-backlog previously never joined the live pool:\nGetPool only rebuilds when the pool is idle (ActiveJobs == 0), so a just-added\nworker (e.g. a new Mac mini) was unus\n[…]\nt-shrink accounting.\n\nAdds 12 unit tests (WorkerPoolReconcileTests, WorkerSignatureTests): 985 green.\n\n* fix: harden 9gq — over-release tripwire, log added/removed workers, order-insensitive signature",
"is_bot": false,
"headline": "feat: hot-add workers to the live pool without a Jellyfin restart (wh…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-09T23:34:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7c85b17fce6672b624e6c493297daeb7104cfb01",
"body": "…freeze; start 9gq",
"is_bot": false,
"headline": "docs(loop): czk+qv4 merged (#131); re-record meo resolution + schema-…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T22:14:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5d213328b50ac1c1c9ff375d63b7ecde2a02a161",
"body": "…#131)\n\nwhisper-subs-czk: invert the GenerateAll / user-request guard from a\nreject-list to an allow-list. The old MediaItemResolver.IsWholeLibraryContainer\nonly blocked library roots (CollectionFolder / UserView / AggregateFolder), so a\nBoxSet collection, MusicArtist, or plain Folder slipped throug\n[…]\neintroduce\nthe reserve-leak the bead described.\n\nAdds MediaItemResolverTests covering the allowed leaves/containers and the\nrejected BoxSet / MusicArtist / Folder / CollectionFolder / AggregateFolder.",
"is_bot": false,
"headline": "fix: allow-list GenerateAll targets + document the de-dup invariant (…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-09T22:11:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c79881c2c6dd8654a7a82a154bcbf291a845fa64",
"body": "…ct verifying ezg/qv4/czk + designing 9gq",
"is_bot": false,
"headline": "docs(loop): continue with other beads; M4 health reconfirmed; archite…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T21:10:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b3b10a15be66d91536b165bf29bd9a5fd92af784",
"body": "…oop deactivated",
"is_bot": false,
"headline": "docs(loop): /sergio-loop complete — M4 worker + beads 1t0/v00 done; l…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T21:00:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "941a8f0cd26548a5739bbea117d9f2b2e332a6f8",
"body": "…gq filed",
"is_bot": false,
"headline": "docs(loop): v00 PR #130; M4-restart deferred (active viewers); bead 9…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T20:58:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "62c1d31c28f1a7e3b0791ce1d31c12dafaff6c0e",
"body": "…ription (whisper-subs-v00)",
"is_bot": false,
"headline": "feat: add AudioLanguageSelection toggle + document multi-audio transc…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T20:52:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "614f373c7117ef89faa39d7ac273902fc3e7707c",
"body": null,
"is_bot": false,
"headline": "docs(loop): 1t0 merged (#129); v00 in progress",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T20:40:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1fd3da79ecbc71d67a9fc5ac1c699f66e9e3ce9d",
"body": "…isper-subs-1t0) (#129)\n\n* feat: auto-retry killed/cancelled jobs + persist in-flight leases (whisper-subs-1t0)\n\nThe queue previously persisted only the pending lanes. An item that was DEQUEUED and running lived solely in the in-memory _inFlight set, so if its task was stopped, Jellyfin restarted, o\n[…]\nding unchanged), Pending-InFlight overlap collapse,\nskip of unparseable/missing items, tier-less normalisation, and ShouldRestore /\nRestoredRetryCount truth tables. Full suite 949 passing, 0 warnings.",
"is_bot": false,
"headline": "feat: auto-retry killed/cancelled jobs + persist in-flight leases (wh…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-09T20:38:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8c433877a44e01ab6917d7bbfdd0f788b075f878",
"body": "… for idle",
"is_bot": false,
"headline": "docs(loop): v00 design recorded; 1t0 in flight; M4 activation waiting…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T19:45:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5b0fbf1437dd32380427bcd0f0e8b8a7e144e048",
"body": "…-delete + M4 activation deferred",
"is_bot": false,
"headline": "docs(loop): Mac mini M4 Metal worker built+verified (46x faster); meo…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-09T19:41:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6de1b715121bbc3f94b3208a5b35fb6e74b74c7b",
"body": "…accuracy) (#128)\n\n* fix: Workers/TestConnection distinguishes reachable-but-slow from unreachable (#126)\n\nA slow GPU worker (e.g. large-v3 on an Intel iGPU) can take longer than the probe's transcribe timeout to decode even the silent test clip, because whisper decodes silence as a worst-case full-\n[…]\nthe image at /opt/whisper-vad/ -- outside the /models bind-mount so a mounted cache can't shadow it -- with a build-time size guard. Bump worker VERSION 0.1.1 -> 0.1.2 (VAD-on is a change from 0.1.1).",
"is_bot": false,
"headline": "release: 4.1.1.0 (TestConnection fix) + worker image 0.1.2 (decoding …",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-07T00:13:10Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "cccd5e63dc6b5332a55651708795f4970cf6aa66",
"body": "* fix: v4.0.1 — post-release audit fixes + v4.0 docs + worker-image robustness (#122)\n\n* fix: dispatcher wedge-on-throw, atomic queue.json, SSRF hardening, single-server panel (v4.0.1)\n\nPost-release audit fixes:\n- CONC-H1: EnsureDispatching built the pool OUTSIDE the Task.Run try, so a throw from\n \n[…]\nmage workflow's push-trigger tag now comes from worker/VERSION\ninstead of a hardcoded 0.1.0 default, so a main push can never re-push an\nexisting tag with different content. Dispatch input still wins.",
"is_bot": false,
"headline": "release: 4.1.0.0 — parallel automatic sweep + 4.0.1 hardening (#125)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T22:33:26Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "347765daf3a5e8fd392209c00ab6e2ca0e9ef8f9",
"body": "…121)\n\nPublishes drumsergio/whisper-subs-worker on worker/ changes + via workflow_dispatch,\nso the v4.0 example worker can be deployed by pulling the image (never :latest).\nFree ubuntu-latest (public repo); push/dispatch only (no fork-PR secret exposure).",
"is_bot": false,
"headline": "ci: build + push the worker image to Docker Hub (worker-image.yml) (#…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T17:45:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "671d6a0b0d9ce9660312960c908bcab5f0d5cc7f",
"body": "…#120)\n\nrelease: v4.0.0.0 — distributed / pooled multi-worker transcription",
"is_bot": false,
"headline": "release: v4.0.0.0 — distributed / pooled multi-worker transcription (…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T17:23:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ac4f35135c402217ae5d480125c0755b8ad7b33",
"body": "…ker transcription)",
"is_bot": false,
"headline": "chore(release): bump version to 4.0.0.0 (distributed/pooled multi-wor…",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-06T17:13:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4ddfb0daea198696361a2b840109641f4139fc1f",
"body": "…ty (v4.0 PR-5) (#119)\n\nWorker-pool config section + queue inbound/outbound + per-worker 'what's running where' panels + Test-connection. Backend unit-tested; simple-by-default.",
"is_bot": false,
"headline": "feat(ui+api): worker-pool config UI + queue inbound/outbound visibili…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T17:12:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "aa51027fe43412dd54dbe3b54836e9698d914962",
"body": "….0 PR-4) (#118)\n\nExample whisper.cpp+Vulkan worker image behind a stdlib OpenAI-compatible adapter, security-reviewed + hardened. Additive worker/ files only.",
"is_bot": false,
"headline": "feat(worker): whisper.cpp + Vulkan OpenAI-compatible worker image (v4…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T17:11:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cb004057351a56e8140afb5d2dd07d72ead6c9a7",
"body": "…ionLock (v4.0 PR-3) (#117)\n\nReplace the single global TranscriptionLock(1,1) + single-worker drain with a shared WorkerPool gating concurrency at ΣMaxConcurrency and routing each job to the cheapest capable free worker. Default one local worker = one job at a time (byte-identical to the old lock); \n[…]\nabbit; fixed a double-dispatch race (dispatch-gate atomicity), a latent _isDraining wedge, a stuck task-running flag, /Queue processed-count parity, and AcquireAsync self-guard. 879 tests, 0 warnings.",
"is_bot": false,
"headline": "feat(workers): N-slot pool dispatcher replacing the global Transcript…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T15:05:20Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b15612c1552b86a3fe4dddab97766debd2ce4ee2",
"body": "… 2/5)\n\nPure worker-selection model + config for the distributed pool, backend-agnostic and simple-by-default. WorkerScheduling (cost-weighted local-first routing), WhisperWorker config (empty by default), ITranscriptionWorker, and the backward-compat WorkerPlan — all pure logic 100% covered, no runtime change yet. Dispatcher wiring is PR-3.",
"is_bot": false,
"headline": "feat(workers): worker model + cost-weighted routing + config (v4.0 PR…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T12:22:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ee25673bc813c0fbf31fde92625b6f1b63f24511",
"body": "whisper-subs is a PUBLIC repo, so GitHub-hosted runners are free + unlimited\n(matches the public-repo CI policy). Switches the 8 build-whisper matrix jobs\nfrom [self-hosted, Linux, X64] to ubuntu-latest, removing the dependency on the\nself-hosted fleet for releases. The workflow already installs all build deps\n(cmake, CUDA via Jimver, Vulkan SDK, aarch64 cross-toolchain) and cross-compiles\narm64 (no QEMU emulation), so it runs cleanly on a stock ubuntu-latest.",
"is_bot": false,
"headline": "ci: build releases on free GitHub-hosted runners, not self-hosted (#115)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T12:05:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6192cbe3e815457b0f46bba8cd99d93873707044",
"body": null,
"is_bot": false,
"headline": "Merge remote-tracking branch 'origin/main' into v4-dev",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-06T11:26:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5b058e06fd043844a3534fed95fc480520fa9cf3",
"body": "… (v3.29.0.0)\n\nPure 3.x correctness fixes, valuable to all current users:\n- Per-call deadline (audio-length-derived, clamped) replaces the fixed 30-min HttpClient.Timeout that caused the 70-hour-stuck-task class; deadline surfaces as TimeoutException, caller-cancel propagates.\n- Forced-detection loo\n[…]\ng ~260MB x N in RAM.\nCodeRabbit reviewed the substance clean; two hardening fixes (deadline ceiling, multi-writer-safe temp) added from an adversarial review pass. 844 tests, pure policy 100% covered.",
"is_bot": false,
"headline": "fix: transcription resilience — bound calls, atomic writes, fail-fast…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-06T11:25:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0fba9f0884d43809ec7d6b67781cb91210ecf083",
"body": null,
"is_bot": false,
"headline": "chore: let CodeRabbit review PRs into the v4-dev integration branch",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-06T10:31:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bf756426ff9107c402904c5ebb72cda9f818c5df",
"body": null,
"is_bot": false,
"headline": "ci: run CI on the v4-dev integration branch (release stays main-only)",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-06T10:28:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c5cd3af97173636e984e342b1676508943850627",
"body": "User-facing subtitle requests + a named-tier priority queue (Critical > High > Medium > Low > Background), tier assigned server-side by role. Opt-in and off by default (existing installs unchanged); when on, approval-required with per-user quota/caps/de-dup. Separate authenticated request controller keeps the admin controller's elevation. 835 tests, 100% patch coverage, 4-lens review + CodeRabbit addressed.\n\nCloses #112",
"is_bot": false,
"headline": "feat: subtitle request system with named-tier priority queue (#112)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-05T16:47:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f01793cffd190683d1d21bddcf6ec987c7793965",
"body": "…110) (#111)\n\nThe scheduled task re-probed the filesystem for every candidate item on\nevery run (~5 directory scans across the media + metadata dirs per item), so\na large library spent tens of minutes each run just re-confirming subtitles\nthat already exist — a 13k-item library took ~40 minutes to r\n[…]\ning (blind to the plugin's own un-indexed .generated.srt\nsidecars — verified against Jellyfin 10.11 source) after a research panel;\nmirrors the change-token cache pattern used by intro-skipper/Bazarr.",
"is_bot": false,
"headline": "feat(scan): cache already-subtitled items so repeat runs skip fast (#…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-05T13:26:35Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "3d080a149acac6d6ef66d5b13a85bca5d6160c81",
"body": "The GitHub Pages deployment for 4cbb37d wedged in deployment_queued across\ntwo attempts (deploy-pages keys the Pages deployment by commit SHA, so\nretries of the same SHA inherit the wedged state), leaving the release\nassets published but the plugin manifest stuck at 3.25.0.0. No code\nchanges — a fresh version/SHA gets a fresh Pages deployment.",
"is_bot": false,
"headline": "chore(release): 3.26.0.1 — redeploy manifest",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-02T16:42:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "46ac827157ea23962e367c27915b83a7850b156d",
"body": "GitHub Pages deployments for 4cbb37d wedged in deployment_queued across two\nattempts (deploy-pages derives the deployment id from the commit SHA, and the\ncanceled deployment blocks retries of the same SHA). A fresh commit gets a\nfresh deployment id. No code changes.",
"is_bot": false,
"headline": "chore: retrigger release deploy",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-07-02T16:34:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4cbb37d178f523a4366bbfb4c71f7e0634ceec2b",
"body": "…) (#109)\n\n* feat(web): inject via File Transformation plugin when installed (#108)\n\nRegister a serve-time index.html transformation with IAmParadox27's File\nTransformation plugin whenever it is installed, so the in-page \"Generate\nSubtitles\" button works on read-only web roots (Docker) without any\np\n[…]\nbly — stop) from a FAILED scan (error while\nassemblies still load at startup — keep retrying), so a transient scan\nexception on the first attempt no longer disables the integration for the\nwhole boot.",
"is_bot": false,
"headline": "feat(web): inject via File Transformation plugin when installed (#108…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-02T15:38:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ff0b31484ffe6ff5c9d75cd74b60b1cc404bcae6",
"body": "Bumps the github-actions group with 2 updates: [actions/cache](https://github.com/actions/cache) and [actions/checkout](https://github.com/actions/checkout).\n\n\nUpdates `actions/cache` from 5 to 6\n- [Release notes](https://github.com/actions/cache/releases)\n- [Changelog](https://github.com/actions/ca\n[…]\nsion-update:semver-major\n dependency-group: github-actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "ci: bump the github-actions group with 2 updates (#107)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-07-01T23:59:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "28f46383831905c8698fd66bda7d79cc9f63e13f",
"body": "…#105) (#106)\n\n* feat(vad): selectable Silero VAD model + tunable --vad-* parameters (#105)\n\nLet users choose the Silero VAD model and tune whisper-cli's native VAD\nparameters, addressing #105. Fully backward compatible: the default config\nproduces a byte-identical whisper-cli command and uses the s\n[…]\nd cap is meaningless — unlike\nthe other tuning fields where 0 is a valid setting. Addresses CodeRabbit\nreview on #106. Behavior unchanged (pinned by AppendVadTuning_MaxSpeechS_ExactlyZero_NotEmitted).",
"is_bot": false,
"headline": "feat(vad): selectable Silero VAD model + tunable --vad-* parameters (…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-07-01T13:51:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "a271f3b479e12ca281358a8be0ac12131c67acac",
"body": "…AD (#104)\n\nRefs #78. Adds AlignSubtitlesToSpeechWithVad (default off): the early-cue forward-snap (AlignSrtToSpeech) can now run alongside VAD, since native VAD improves transcription but doesn't always correct whisper's slightly-early cue starts. Default off → existing VAD installs unchanged (the gate ShouldAlignToSpeech(align, usesVad, alignWithVad) is algebraically identical when the opt-in is off). Config-page checkbox + README/CLAUDE.md docs + truth-table tests. v3.24.0.0, 632 tests pass.",
"is_bot": false,
"headline": "feat(timing): opt-in to run speech-alignment forward-snap on top of V…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-29T09:49:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9d981b85cea3a2b9f27c118eb84e688cd5c52d2f",
"body": "…ave-with-media-off libraries (#103)\n\nCloses #101. Generated subtitles now save to the item's internal metadata path (item.GetInternalMetadataPath(), e.g. /config/metadata/library/aa/<guid>/) when the library's 'Save subtitles into media folders' is off or the media folder is read-only — mirroring h\n[…]\nata path, so already-generated items aren't reprocessed and status is correct. Writability probed only when save-with-media is on. Lyrics stay media-adjacent (out of scope). v3.23.0.0, 623 tests pass.",
"is_bot": false,
"headline": "feat(save): save subtitles to Jellyfin metadata path on read-only / s…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-28T12:56:51Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "05b74fbc730783ddd819a4d0cfd271960ddb6adc",
"body": "…ble message (#102)\n\nFollow-up to #94 / v3.22.0.0. The injection-status panel's 'not writable' message now shows the concrete fix with the server's real index.html path — sudo chown root:jellyfin \"<path>\" && sudo chmod 664 \"<path>\" — scoped to install type (package vs Docker PUID/PGID / read-only mount). Pure DescribeInjection gains the path param; tests lock the quoted path, the 664 mode, the spaces-in-path case, and the fallback. v3.22.1.0 (patch). 610 tests pass.",
"is_bot": false,
"headline": "fix(integration): copy-paste chown/chmod remediation in the not-writa…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-27T23:39:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d2564868d340f49150ad0058a7a022192ab2745e",
"body": "…utton (#100)\n\nDiagnosability for #94: the in-page \"Generate Subtitles\" button + menu come from whisperSubs.js injected into Jellyfin's index.html, which silently fails on read-only web roots / no restart / cached pages.\n\n- Config-page 'In-page button & menu' panel shows whether the script is inject\n[…]\nt.\n- whisperSubs.js logs load + admin status at console.log (was hidden console.debug).\n- Pure ComputeInjection/DescribeInjection helpers + ScriptInjectionTests; 608 tests pass.\n- v3.22.0.0 (feature).",
"is_bot": false,
"headline": "feat(integration): client-script injection status panel + Re-inject b…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-26T17:49:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7a309eb093dca88e0d86dcf34d0bf6239b3a5550",
"body": "…p double-VAD (#99)\n\nForced-subtitle follow-ups to #95 (v3.21.3.0):\n- Translate foreign dialogue to English for English libraries (was transcribed in source language into the .eng track).\n- Skip whisper's second VAD pass on already-trimmed forced chunks (was emptying short chunks).\n- Log whisper-cli's normal stderr at Debug, not Warning.\nPure ShouldUseVad/LanguageIsEnglish helpers + ForcedTranslateTests; 595 tests pass.",
"is_bot": false,
"headline": "fix(forced): translate foreign dialogue to English, quiet stderr, ski…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-26T15:53:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1effc73745b4dac7cca94fdbc062cf9cec42bd96",
"body": "…ixes the per-chunk timeout (#98)\n\nThird fix for #95 — the one that targets the actual current failure. Forced-mode per-chunk --detect-language loaded the full ~1 GB transcription model on the CPU under a 120s timeout, so on a no-AVX2 CPU every chunk timed out (TaskCanceledException) and the film ne\n[…]\nore the forced loop gives the background download a head start so the first run is fast too.\n\nMakes per-chunk detection finish in seconds on any hardware, no GPU needed. Release: v3.21.2.0. Fixes #95.",
"is_bot": false,
"headline": "fix: small dedicated model for forced-subtitle language detection — f…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-26T10:30:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ce35d6e8f7ed3e31c4e9f0192e594aef7adfcd2e",
"body": "…t (#97)\n\nFollow-up to #96 / issue #95. Closes two residual gaps for AVX-but-not-AVX2 users:\n\n- Persist the validated binary variant (WhisperBinaryVariant) so the setup page re-offers the user's installed compatibility build instead of silently re-defaulting the dropdown to the GPU recommendation on\n[…]\nrrect Compatibility build no longer shows the misleading red 'will crash' warning (green only when the CPU lacks AVX2; amber 'use the standard variant' otherwise).\n\nRelease: v3.21.1.0. Relates to #95.",
"is_bot": false,
"headline": "fix: persist whisper binary variant + correct setup compatibility hin…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-25T20:44:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e00be421f27320f27162fef84a40a2a9dce5c70f",
"body": "Closes #94, fixes #95.\n\n#94 — Visible \"Generate Subtitles\" button on movie/episode/season/series detail pages (alongside the existing context-menu item), enqueue-time de-duplication (no double-queue on double-clicks / overlapping seasons), and a library-root guard. Admin-only.\n\n#95 — Language detect\n[…]\nhose CPUs to the noavx variant), and the detection path surfaces the precise 'switch to the noavx variant' message on a SIGILL instead of a misleading 'could not detect language'.\n\nRelease: v3.21.0.0.",
"is_bot": false,
"headline": "feat: generate subtitles from the item page + AVX2 detection fix (#96)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-25T15:08:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7016ba8fca248981161edb2e13cddae3a90aa208",
"body": "The whisper-cli build artifacts (incl. 727MB CUDA binaries) are transient\nhand-offs to the release job; the final binaries are published to the\nGitHub Release. They were retained 90 days by default, accumulating ~15GB\nof paid Actions storage. Cap retention at 1 day.\n\nCo-authored-by: GeiserX <drumsergio@gmail.com>",
"is_bot": false,
"headline": "ci: cap artifact retention at 1 day to stop storage billing (#92)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-23T10:51:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5a7e2eb7a82479065e90697ea9e5f8a50e3da885",
"body": "Public repos get free, unlimited standard GitHub-hosted runners. Move\nself-hosted Linux CI jobs to ubuntu-latest: frees the home-lab servers,\nruns PR code in throwaway isolated VMs (removing the fork-PR attack\nsurface), and costs nothing on public repos. The previous self-hosted\nfork-guard is removed as it is no longer needed.\n\nCo-authored-by: GeiserX <drumsergio@gmail.com>",
"is_bot": false,
"headline": "ci: use GitHub-hosted ubuntu-latest runners (#93)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-23T10:40:22Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e312b77f1d12f6794325a3c69d5bcdfbb2edf378",
"body": "Jobs triggered on pull_request that run on the self-hosted runner could\nexecute untrusted fork PR code on the runner host. Add an if: guard so\nthese jobs run only for same-repo events (push, schedule, workflow_dispatch,\nand PRs from branches in this repo), never for fork PRs. Runner stays\nself-hosted for trusted runs.\n\nCo-authored-by: GeiserX <drumsergio@gmail.com>",
"is_bot": false,
"headline": "security: block fork PRs from running on the self-hosted runner (#91)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-22T22:56:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3083a2faf9ab76ad7e6d0c0a9f78d698f794c4bd",
"body": "…ng, dropdown descriptions (#89)\n\nFollow-up to #88. Adds a CanTranslate capability flag to the model catalog (false for the distilled turbo models, which can't translate; true for full models) and a pure ModelCatalog.IsTranslationCapable helper. SubtitleManager now logs a clear, non-blocking warning\n[…]\nrected the F16 speed/RAM claims. The config UI now shows the selected model's description under the download dropdown, and a catalog-load ordering race is fixed. New ModelCatalogTests; 554 tests pass.",
"is_bot": false,
"headline": "feat: translation-aware model catalog — CanTranslate guard, Q5 steeri…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-18T19:19:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e34ed17d3ab9013f2ba0304a17c82b9f98edfc4c",
"body": "Adds full large-v3 (ggml-large-v3.bin, 3095 MB) and its q5_0 quant (ggml-large-v3-q5_0.bin, 1081 MB) to the model download catalog. These are the only translation-capable large models — large-v3-turbo was distilled without the translate task, so users translating foreign-language titles to English n\n[…]\nv3 (or medium), which the UI previously didn't offer. Both download from the same ggerganov/whisper.cpp HuggingFace repo; sizes verified against Content-Length. Thanks to @hrones for the contribution.",
"is_bot": false,
"headline": "feat: add full large-v3 models (F16 + Q5) to the download catalog (#88)",
"author_name": "hrones",
"author_login": "hrones",
"committed_at": "2026-06-18T18:50:07Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2c4308f47f5b3c09c3ccdfca290fb934670bc477",
"body": "… --print-progress wiring (#87)\n\nFollow-up to #86. Resets the per-file progress bar inside the single transcription choke point (TranscribeInternalAsync, before process.Start()) so the manual Generate queue and multi-pass items no longer show the previous run's stale 100% and run backwards. Anchors \n[…]\ntderr line can't be misread as progress. Extracts a pure, unit-tested BuildTranscribeArguments (byte-identical arg vector incl. --print-progress) so the flag can't be silently dropped. 538 tests pass.",
"is_bot": false,
"headline": "fix: reset per-file progress per run, anchor progress parse, test the…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-18T13:41:16Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ac2d0b902e2374e1205f97213c70a016a03876b6",
"body": "…(#86)\n\nwhisper-cli's progress = N% stderr lines are already parsed and forwarded to the per-file progress bar, but the main transcription invocation never passed --print-progress (default off), so whisper emitted nothing and the bar stayed frozen. Add the flag to the transcription argument list. Thanks to @hrones for the fix.",
"is_bot": false,
"headline": "fix: add --print-progress so the transcription progress bar advances …",
"author_name": "hrones",
"author_login": "hrones",
"committed_at": "2026-06-18T12:13:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "487260b46fa480e15338a41fafea192a0ce8b8c2",
"body": "…e-subs option (#83) (#85)\n\nAdds honest controls mirroring what whisper can produce: a single 'Generate original-language subtitles' switch (transcription), a separate 'Translation to English' section (fills the English gap only when absent), and a 'Count image-based subtitles as present' toggle. Replaces a scrapped free-text allow-list. Single source of truth for sidecar extensions; pure, unit-tested gating. 509 tests pass.",
"is_bot": false,
"headline": "feat: subtitle generation toggle + English translation section + imag…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-16T18:03:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "24a8422bf5d4c402f2d7103264c8f5ebd6506116",
"body": "* feat: skip media that already has usable subtitles (#82)\n\nThe auto-generation task transcribed + translated media that already had\nsubtitles (the reporter's 1188-item library wasted ~7h/movie on an iGPU). Two\nroot causes: (1) with EnableTranslation on, the only HasSubtitles skip was\ndisabled so ev\n[…]\ntrip). Full suite 484 green.\n\nDeferred to #83 (out of scope, larger refactor): extracting the ~279-line\nExecuteAsync `alreadyComplete` block — #83 must rework it for desired-languages\nprofiles anyway.",
"is_bot": false,
"headline": "feat: skip media that already has usable subtitles (#82) (#84)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-16T14:04:44Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c0d28a7edd600794c790fe935b16bbd31bd71e23",
"body": "Bumps Microsoft.Extensions.Http from 9.0.16 to 9.0.17\n\n---\nupdated-dependencies:\n- dependency-name: Microsoft.Extensions.Http\n dependency-version: 9.0.17\n dependency-type: direct:production\n update-type: version-update:semver-patch\n dependency-group: minor-and-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "deps: Bump the minor-and-patch group with 1 update (#81)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-16T08:51:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3e9fb6235f0880f4c26c19437461821893d01928",
"body": "* feat: use native Silero VAD for subtitle speech-onset timing (#78)\n\nThe v3.18.6.0 energy-based silencedetect alignment failed in production — the\nuser re-reported identical \"subtitles appear during the silence before the line\"\nbehavior with a recording. An empirical pilot (whisper-cli on a synthes\n[…]\nles to speech\" as the fallback (used only when VAD is\n off), drop the misleading \"Recommended\" tag.\n\nAdds 10 tests (UsesVad contract on both providers, VAD tuning-flag denials).\nFull suite 411 green.",
"is_bot": false,
"headline": "feat: native Silero VAD for subtitle speech-onset timing (#78) (#80)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-14T22:47:05Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "7b1036363445e084bf7690d65a80ca38fc4dfc8e",
"body": "… (#78) (#79)\n\n* feat: align subtitle timing to speech, compensate audio start offset (#78)\n\nIssue #78: subtitles appear during the silence before their line is spoken.\nwhisper.cpp emits gapless segments (next.start == prev.end), and the plugin\npassed its SRT through verbatim, so the next subtitle s\n[…]\niling-bare-number, round-trip) and serialized the\nSubtitleService-singleton-mutating test classes into a non-parallel collection\nto kill a pre-existing flaky race. Full suite 391 green, deterministic.",
"is_bot": false,
"headline": "feat: align subtitle timing to speech + compensate audio start offset…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-13T20:20:46Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f13a51a957c6a988ff9f3354872ab943307e64e5",
"body": "Bumps the github-actions group with 11 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [actions/cache](https://github.com/actions/cache) | `4` | `5` |\n| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4` | `7` |\n| [actions/checkout](https://github.com/actions/checkou\n[…]\nsion-update:semver-major\n dependency-group: github-actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "ci: bump the github-actions group with 11 updates (#77)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-06-07T17:21:13Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "27701ce8fe3e38541b94e84cc3659d3a1fa60a83",
"body": "Remove the semver-major ignore from the github-actions ecosystem so action major upgrades (Node-runtime bumps) get PRs. npm/docker majors stay gated.",
"is_bot": false,
"headline": "ci(dependabot): allow github-actions major bumps (#76)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-07T16:30:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3306435c4ce70c137b124dcd03fe2ebfb5d25b6b",
"body": "- actions/configure-pages: v4→v5\n- actions/stale: v9→v10\n- softprops/action-gh-release: v1→v2",
"is_bot": false,
"headline": "ci(deps): bump deprecated GitHub Actions to current majors (#75)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-07T15:46:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "027b5525983cccd33dd9a0981e174260ddf6d3c9",
"body": "…SIGILL (#74)\n\nReported on #70: after the libgomp fix, a TrueNAS user's transcription failed\nwith exit 132 (SIGILL). Their CPU lacks AVX, but our cpu/cuda12/vulkan binaries\nare compiled with AVX/AVX2, so they crash on launch. The auto-fallback didn't\nhelp because (a) validation runs `whisper-cli --h\n[…]\nAVX-capable users to the slower build; the runtime\nSIGILL handler remains the backstop.\n\nTests: CpuInfoHasAvx parser (avx present/absent/avx512-only/empty) and\nVariantRequiresAvx mapping. 367 passing.",
"is_bot": false,
"headline": "fix: handle CPUs without AVX — detect, recommend noavx, fall back on …",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-07T13:38:23Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "2c6960f8892fb9e458c25d8ed871a070e02512e5",
"body": "…(#73)\n\nReview hardening for the #70/#72 auto-fallback:\n\n- DownloadBinaryAsync: replace recursive fallback with an iterative walk over\n the fallback chain. The recursive version had the inner frame release the\n _isRunning lock mid-chain (safe only by accident of an unconditional return);\n the loo\n[…]\nurns null for CPU\" — cpu now maps to noavx).\n- Tests: cover unknown/empty/null/case-sensitive inputs and add a chain-\n termination/no-cycle property test guarding against an accidental fallback loop.",
"is_bot": false,
"headline": "refactor: harden binary fallback (iterative walk, cycle-guard tests) …",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-06T22:45:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e56f8ec4c643d276ba74d6dd3ef9f9a6d8c01336",
"body": "…missing (#72)\n\nv3.18.2.0 disabled OpenMP on all variants to fix the libgomp.so.1 failure in\nminimal containers — but that slowed CPU transcription for everyone to rescue a\nminority, and still didn't route the affected user anywhere.\n\nBetter approach: keep the fast OpenMP-linked builds for cpu/cuda1\n[…]\n: cpu -> noavx (arm64 asset resolved by platform)\n- Bump cache keys v10->v11, rocm v3->v4 so OpenMP-on binaries rebuild\n- README: libgomp1 required for cpu/gpu again, documents the noavx auto-fallback",
"is_bot": false,
"headline": "fix: keep OpenMP for performance, auto-fall back to noavx if libgomp …",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-06T21:08:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8afd3d5283de78845aebefe3b3e6ebf49620e9e5",
"body": "… (#71)\n\n* fix: self-contained CPU binary + surface transcription failures (#70)\n\nTwo bugs from #70:\n\n1. whisper-cli failed at transcribe time in minimal TrueNAS containers with\n \"libgomp.so.1: cannot open shared object file\". The binaries dynamically\n linked the GNU OpenMP runtime. Disable Open\n[…]\nrstError is preserved and the queue/UI shows the actionable cause.\n- Clarify that libgomp/OpenMP detection is informational only (binaries are now\n built with -DGGML_OPENMP=OFF), matching the README.",
"is_bot": false,
"headline": "fix: self-contained CPU binary + surface transcription failures (#70)…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-06-06T16:16:53Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5df9f8a12745fbbef2fd657131de58753d3a62a2",
"body": "…g (#69)\n\nThe semicolons in CMAKE_CUDA_ARCHITECTURES were interpreted as shell\ncommand separators when expanded via ${{ matrix.cmake_flags }}.",
"is_bot": false,
"headline": "fix(ci): quote CUDA architectures to prevent shell semicolon splittin…",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-25T17:33:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d16d8b6b56d47fcd51d2cd7678af2cac00cf6ab7",
"body": "- Remove non-existent cudart-static sub-package (static lib included in cudart-dev)\n- Remove non-existent libcublas-static-12-6 (static lib included in libcublas-dev)\n- Replace vulkan-headers + shaderc with glslc (correct package names on Noble)",
"is_bot": false,
"headline": "fix(ci): correct CUDA and Vulkan package names for Ubuntu 24.04 (#68)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-25T17:23:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bc42c14ff3313f30d96aec2df67536592c4db698",
"body": "Add -DGGML_STATIC=ON to both CUDA matrix entries, which statically\nlinks cudart, cublas, and cublasLt into the binary. The only remaining\nruntime dependency is libcuda.so.1 (driver API), which\nnvidia-container-toolkit always provides.\n\nAlso adds -DCMAKE_CUDA_ARCHITECTURES=61;70;75;80;86;89;90 to ens\n[…]\n-and-suspenders measure, adds auto-fallback: if a GPU binary\nfails validation (missing shared libs), automatically downloads the\ncorresponding CPU variant instead of leaving the user stuck.\n\nFixes #66",
"is_bot": false,
"headline": "fix: statically link CUDA runtime to eliminate container deps (#67)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-25T17:11:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c16ea15632218cfd7b9ded19b0a2afc6afba56a8",
"body": null,
"is_bot": false,
"headline": "chore: remove AGENTS.md (migrated to CLAUDE.md)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-25T13:44:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4333e17defb8922a285c610bd62d10312188eaa6",
"body": null,
"is_bot": false,
"headline": "chore: merge AGENTS.md into CLAUDE.md",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-25T13:44:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "46b08ec4662dd2e614f32c2f56c2702d203d8a03",
"body": null,
"is_bot": false,
"headline": "chore: add CLAUDE.md",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-25T13:29:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "506c3b0e59eba2916011ff83ba740ff5671d9697",
"body": "* fix(ci): add vulkan-headers package for Vulkan builds\n\nLunarG's libvulkan-dev on 22.04 doesn't include vulkan.h — it's in\nthe separate vulkan-headers package.\n\n* feat: add custom whisper-cli arguments field\n\nAdd a \"Custom Whisper Arguments\" text input in Advanced settings that\nappends user-provide\n[…]\n.\n\nAlso makes AppendCustomArgs internal for testability and adds 10 unit\ntests covering: empty input, valid args, denied flags, equals-style,\ncase insensitivity, mixed valid+denied, and null handling.",
"is_bot": false,
"headline": "feat: custom whisper-cli arguments (#65)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-19T09:22:54Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e1b3a44ad43c31955399d7c4f6464913ee1f13da",
"body": "Bumps Microsoft.Extensions.Http from 9.0.15 to 9.0.16\n\n---\nupdated-dependencies:\n- dependency-name: Microsoft.Extensions.Http\n dependency-version: 9.0.16\n dependency-type: direct:production\n update-type: version-update:semver-patch\n dependency-group: minor-and-patch\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
"is_bot": true,
"headline": "deps: Bump the minor-and-patch group with 1 update (#63)",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2026-05-19T09:00:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f13709090f5a3dce48064c8c4cea01fcd9067f41",
"body": "LunarG's libvulkan-dev on 22.04 doesn't include vulkan.h — it's in\nthe separate vulkan-headers package.",
"is_bot": false,
"headline": "fix(ci): add vulkan-headers package for Vulkan builds (#62)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-15T19:01:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a65fbf6023b0d5506a1152b712b0fa4dd3545fa2",
"body": "The self-hosted runner (Ubuntu 22.04) has the LunarG repo configured\nwhich provides the shaderc package containing glslc.",
"is_bot": false,
"headline": "fix(ci): use shaderc package for glslc on Ubuntu 22.04 (#61)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-15T16:25:28Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f7c1c462bdc4c23f991d560fa02c2fe3c828002e",
"body": "- Add software-properties-common + wget (needed by CUDA toolkit action)\n- Add LunarG Vulkan SDK repo for glslc (not in base Ubuntu 22.04)\n- Clean /tmp before clone (self-hosted runners persist /tmp across jobs)",
"is_bot": false,
"headline": "fix(ci): resolve self-hosted runner dependency issues (#60)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-15T15:43:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cb94afd50d3fe3b1d4e5b335837aa4d95188279c",
"body": "- Use matrix.os for runs-on (was hardcoded, causing scheduling issues)\n- Bump cache key v7→v8 to force fresh builds on self-hosted runners\n (old cache from GitHub-hosted runners had wrong paths)\n- Fetch live manifest from Pages instead of committing back to main\n (branch protection blocks direct pushes from Actions)\n- Deduplicate versions when prepending to manifest",
"is_bot": false,
"headline": "fix(ci): resolve self-hosted runner build failures (#59)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-15T15:28:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b894dc0e268f5d5255c1d93d1658fbb0db97b75b",
"body": "- Manifest now preserves version history (last 5 releases) using jq\n instead of overwriting with only the latest\n- Seed manifest.json with actual checksums for v3.14.1–v3.17.0\n- Pages artifact deploys only manifest.json, not entire workspace\n- Commit manifest back to repo so versions accumulate across releases\n- Add arm64-noavx build variant to matrix and release assets",
"is_bot": false,
"headline": "ci: improve release workflow and fix manifest deployment (#58)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-15T15:04:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "289dd25d983af984f877062d353f83850263f286",
"body": null,
"is_bot": false,
"headline": "ci: add ARM64 cross-compilation toolchain for linux-arm64 build",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-15T12:10:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "272ecd22efcb6398ffa684a8b6d7f46d57cde905",
"body": null,
"is_bot": false,
"headline": "ci: migrate build-whisper to self-hosted runners",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-15T09:09:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4cebaeac63b61c1f890dcc5a865a522d55d8b7f9",
"body": null,
"is_bot": false,
"headline": "ci: migrate to self-hosted runners",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-14T08:37:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6704c696dd2ded1ee29bc98de7b9975e684dfb92",
"body": null,
"is_bot": false,
"headline": "ci: migrate to self-hosted runners",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-14T08:34:43Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "89153867be9f0bf68203f7236f9dd14616e9ab93",
"body": "* fix: interrupt transcription when playback starts mid-process\n\nPreviously, pause-on-playback only checked between items. Once whisper\nstarted transcribing a file (which can take hours for long content), it\nwould run to completion regardless of active playback.\n\nNow monitors sessions during transcr\n[…]\nk starts. The partial SRT is saved automatically, and after\nplayback ends the item is retried with resume-from-partial logic.\n\nCloses #49\n\n* fix: await monitorTask to prevent unobserved task exception",
"is_bot": false,
"headline": "fix: interrupt transcription when playback starts mid-process (#56)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-13T13:48:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "13ecc658027189d7eeecfc3669d7aa585f562b3c",
"body": "* feat: add search/filter box in Subtitle Management\n\nAdds a text search input between the library selector and items table.\nFilters by item name or filename with 300ms debounce. Server-side\nfiltering via new searchTerm query parameter on the Items endpoint.\n\nCloses #54\n\n* refactor: push search filtering to database layer\n\nUse InternalItemsQuery.SearchTerm instead of loading all items into\nmemory then filtering. Also adds maxlength=200 on the search input.",
"is_bot": false,
"headline": "feat: add search/filter box in Subtitle Management (#55)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-12T09:13:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3db3dc59b2d410c6cb288b48690ab47284f55f86",
"body": "* feat: add GPU compatibility variants for older CPUs\n\nAdd cuda12-noavx and vulkan-noavx build variants for users with\nolder CPUs (no AVX support) that have a dedicated GPU. Fixes the\nillegal instruction crash when using CUDA/Vulkan on old CPUs\n(e.g. TrueNAS Scale with GTX 1050 Ti).\n\nAlso pins expli\n[…]\n assets and update test assertions\n\nAdd cuda12-noavx and vulkan-noavx to the GitHub Release files list\nso users can actually download them. Update BinaryCatalogTests to\nexpect 7 variants instead of 5.",
"is_bot": false,
"headline": "feat: add GPU compatibility variants for older CPUs (#53)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-11T09:54:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "f72b3b52dbf4d1e97ba525f5176d5f8427507017",
"body": "Ubuntu 22.04 lacks glslc (CMake FindVulkan requires it). Vulkan users\nrun modern distros so glibc 2.35 compat isn't needed for this variant.\nCPU builds remain on 22.04 for maximum container compatibility.",
"is_bot": false,
"headline": "fix(ci): build Vulkan variant on Ubuntu 24.04",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-11T09:31:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5d2d86de73c32d467f53af6ed7b97bb7265848a2",
"body": "glslc is not a standalone package on Ubuntu 22.04 — it's provided by\nglslang-tools. This fixes the Vulkan binary build step that broke after\nthe glibc compatibility migration from Ubuntu 24.04 to 22.04.",
"is_bot": false,
"headline": "fix(ci): use glslang-tools for Vulkan build on Ubuntu 22.04",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-11T09:29:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "efc3fdff35f3ed61a9c8fad4a22fdc43e8b25c17",
"body": "* feat: pause subtitle generation during active playback\n\nAdds a \"Pause generation during playback\" checkbox. When enabled, the\nscheduled task polls ISessionManager.Sessions between items and waits\nuntil no user is actively playing media before processing the next file.\n\nCloses #49\n\n* review: add 4-\n[…]\n, immediate return on idle\nsessions, waiting until playback stops, cancellation during wait, and\nempty session list. Also reports \"Waiting for playback to stop\" phase\nto the Queue API during the wait.",
"is_bot": false,
"headline": "feat: pause subtitle generation during active playback (#52)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-11T09:15:17Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6222d7003b7388faf137762158d1f9801ecf1d45",
"body": "Binaries built on Ubuntu 24.04 require glibc 2.38 which isn't available\non Debian 12 (glibc 2.36) or older distros. Building on 22.04 targets\nglibc 2.35, covering Debian 12+, Ubuntu 22.04+, and all current distros.\n\nFixes #50",
"is_bot": false,
"headline": "fix: build whisper binaries on Ubuntu 22.04 for glibc 2.35 compat (#51)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-11T08:52:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "39b6521c51bb6b6558427656aeca00110c95569f",
"body": "Users on minimal containers (TrueNAS Scale, barebones Docker) couldn't\nfind the noavx binary in the UI — it existed in releases but had no\ncatalog entry. Now shows as \"CPU (Compatibility)\" with appropriate hint.\n\nFixes #46",
"is_bot": false,
"headline": "fix: add noavx variant to Setup tab binary dropdown (#48)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-07T22:58:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "81ff1f2549009c59a2e058b2113e31ea2f6a8e17",
"body": "The noavx binary is meant to run on minimal environments (e.g. TrueNAS\nScale Jellyfin containers) that don't ship libgomp.so.1. whisper.cpp\nfalls back to pthreads threading when OpenMP is disabled.\n\nFixes #46",
"is_bot": false,
"headline": "fix: disable OpenMP in noavx build to remove libgomp dependency (#47)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-07T21:38:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9439e334de4acdb02862ac839d37f40070d67143",
"body": "Bug reports now require plugin/Jellyfin version, engine type, model,\nSetup/Status endpoint output, filtered logs, and Docker config.\nBlank issues disabled in favor of structured forms.",
"is_bot": false,
"headline": "Add issue templates requiring diagnostic info",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-07T08:41:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1d6c20ea896040a7dd5564685a4bcbc116c3c7e5",
"body": "* feat: add TranslationOnly subtitle mode (#44)\n\nAdds a new SubtitleMode (TranslationOnly=3) that skips native-language\ntranscription entirely and only produces English translated subtitles\nin a single whisper pass. Halves processing time for users who only\nneed English subs from foreign-language me\n[…]\nteTranslationVisibility() into loadConfiguration callback to\neliminate race condition, normalize EnableTranslation on save to prevent\nstate pollution, and remove racy setTimeout from pageshow handler.",
"is_bot": false,
"headline": "feat: add TranslationOnly subtitle mode (#45)",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-05-05T10:57:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "26fcc006bcd09937a904f53c4a684934ccb7a270",
"body": "The default whisper-cli-linux-x64 stays fully optimized (AVX2/FMA/BMI2)\nfor the majority of users. A separate whisper-cli-linux-x64-noavx binary\n(SSE4.2 only) is provided for Celeron/Atom/older CPUs lacking AVX.\n\nRef #43",
"is_bot": false,
"headline": "Keep default x64 binary optimized (AVX2), add -noavx variant",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-04T23:12:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "612aa159b84bcd1567991507ada60a27c07796fb",
"body": "GGML_BMI2 defaults to ON and was not explicitly disabled in the generic\nbuild. J4125 (Goldmont Plus) lacks BMI2 — pdep/pext instructions cause\nSIGILL even with AVX/FMA/F16C already disabled.\n\nRef #43",
"is_bot": false,
"headline": "Fix generic x64 build: disable BMI2 for Celeron/Atom CPUs",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-04T23:08:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f0ac4fe23e7c5286f7d1d8874ff2232b295bf084",
"body": "The default whisper-cli-linux-x64 was built with -march=native on GHA\nrunners, baking in AVX2/FMA/F16C. This crashes with SIGILL (exit 132)\non Intel Celeron J4125, Atom, and other Goldmont/Tremont CPUs that only\nsupport SSE4.2.\n\nNow ships two x64 CPU binaries:\n- whisper-cli-linux-x64: generic SSE4.2-only (works everywhere)\n- whisper-cli-linux-x64-avx2: optimized for Haswell+ (~30-40% faster)\n\nFixes #43",
"is_bot": false,
"headline": "Ship generic x86_64 binary for CPUs without AVX (Celeron/Atom)",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-05-04T17:38:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "60b00d0d48554903fe24283fdb1c2687d4fc1e92",
"body": "Releases the remote Whisper API key authentication support merged in PR #42.",
"is_bot": false,
"headline": "Bump version to 3.12.2.0 for API key auth feature",
"author_name": "GeiserX",
"author_login": "GeiserX",
"committed_at": "2026-04-29T19:28:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "de720959514cc3363f3be80a3834aaa5b37c51ca",
"body": "feat(remote): support API key auth for remote Whisper API",
"is_bot": false,
"headline": "Merge pull request #42 from mvanhorn/osc/40-api-key-auth",
"author_name": "Sergio Fernández",
"author_login": "GeiserX",
"committed_at": "2026-04-29T19:27:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "919cffdb631448f773265accf9fa41b16be53d43",
"body": "…caps, defensive trim\n\n- RemoteWhisperProvider: log a warning when API key is configured with a\n non-HTTPS URL, and trim the key defensively in the constructor.\n- configPage.html: maxlength=256, autocomplete=new-password, spellcheck=false\n on the API key input.\n- Capitalize 'Speaches' (the product\n[…]\nuration suggestion -- the\n factory takes config as a DI argument intentionally, switching to the\n singleton would couple unit tests to global Plugin.Instance state and\n ripple through 3 call sites.",
"is_bot": false,
"headline": "Address review feedback: cleartext warning, HTML hardening, Speaches …",
"author_name": "Matt Van Horn",
"author_login": "mvanhorn",
"committed_at": "2026-04-29T17:23:11Z",
"body_truncated": true,
"is_coding_agent": false
}
],
"releases_count": 91,
"commits_last_year": 249,
"latest_release_at": "2026-07-13T21:26:45Z",
"latest_release_tag": "v4.3.1.0",
"releases_from_tags": false,
"days_since_last_push": 3,
"active_weeks_last_year": 20,
"days_since_latest_release": 10,
"mean_days_between_releases": 1.2
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": false,
"health_percentage": 57,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": []
},
"popularity": {
"forks": 6,
"stars": 81,
"watchers": 1,
"fork_history": {
"days": [
{
"date": "2026-04-29",
"count": 1
},
{
"date": "2026-05-10",
"count": 1
},
{
"date": "2026-05-21",
"count": 1
},
{
"date": "2026-06-18",
"count": 1
},
{
"date": "2026-06-20",
"count": 1
},
{
"date": "2026-07-22",
"count": 1
}
],
"complete": true,
"collected": 6,
"total_forks": 6
},
"star_history": null,
"open_issues_and_prs": 2
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": true,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"WhisperSubs.csproj"
],
"largest_source_bytes": 105363,
"source_files_sampled": 107,
"oversized_source_files": 1,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 41683
},
"dependencies": {
"manifests": [
"WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"WhisperSubs.csproj"
],
"advisories": {
"error": null,
"scope": "repository_graph",
"source": "osv",
"findings": [],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 3,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 5,
"direct_affected_count": 0
},
"ecosystems": [
"nuget"
],
"dependencies": [
{
"name": "Microsoft.NET.Test.Sdk",
"manifest": "WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"ecosystem": "nuget",
"version_constraint": "17.*"
},
{
"name": "xunit",
"manifest": "WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"ecosystem": "nuget",
"version_constraint": "2.*"
},
{
"name": "xunit.runner.visualstudio",
"manifest": "WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"ecosystem": "nuget",
"version_constraint": "2.*"
},
{
"name": "Moq",
"manifest": "WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"ecosystem": "nuget",
"version_constraint": "4.*"
},
{
"name": "coverlet.collector",
"manifest": "WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"ecosystem": "nuget",
"version_constraint": "6.*"
},
{
"name": "Jellyfin.Model",
"manifest": "WhisperSubs.csproj",
"ecosystem": "nuget",
"version_constraint": "10.11.0"
},
{
"name": "Jellyfin.Controller",
"manifest": "WhisperSubs.csproj",
"ecosystem": "nuget",
"version_constraint": "10.11.0"
},
{
"name": "Microsoft.Extensions.Http",
"manifest": "WhisperSubs.csproj",
"ecosystem": "nuget",
"version_constraint": "9.0.18"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "coverlet.collector",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Jellyfin.Controller",
"direct": true,
"version": "10.11.0",
"ecosystem": "nuget"
},
{
"name": "Jellyfin.Model",
"direct": true,
"version": "10.11.0",
"ecosystem": "nuget"
},
{
"name": "Microsoft.Extensions.Http",
"direct": true,
"version": "9.0.18",
"ecosystem": "nuget"
},
{
"name": "Microsoft.NET.Test.Sdk",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "Moq",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "xunit",
"direct": true,
"version": null,
"ecosystem": "nuget"
},
{
"name": "xunit.runner.visualstudio",
"direct": true,
"version": null,
"ecosystem": "nuget"
}
],
"collected": true,
"truncated": false,
"total_count": 8,
"direct_count": 8,
"indirect_count": 0
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 102,
"open_issues": 2,
"closed_ratio": 0.941,
"closed_issues": 32,
"closed_unmerged_prs": 1
},
"bus_factor": 1,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "GeiserX",
"commits": 235,
"avatar_url": "https://avatars.githubusercontent.com/u/9169332?v=4"
},
{
"type": "User",
"login": "mvanhorn",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/455140?v=4"
},
{
"type": "User",
"login": "hrones",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/235208089?v=4"
}
],
"contributors_sampled": 3,
"top_contributor_share": 0.983
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"build-release.yml",
"ci.yml",
"stale.yml",
"worker-image.yml"
],
"has_docs_dir": true,
"linter_configs": [],
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 3,
"reason": "branch protection is not maximal on development and all release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 10,
"reason": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/18 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 0,
"reason": "project has 0 contributing companies or organizations -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 23 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": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 4,
"reason": "security policy file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": 0,
"reason": "Project has not signed or included provenance with any releases.",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "129503878cd479d1068694641a2ec0eb20ac9781",
"ran_at": "2026-07-24T07:55:28Z",
"aggregate_score": 5.2,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": true,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T01:51:39Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-07-20T23:25:40Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 5,
"created_at": "2026-04-06T22:42:18Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 41,
"created_at": "2026-04-29T07:34:23Z",
"last_comment_at": "2026-04-29T08:07:36Z",
"last_comment_author": "GeiserX"
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/GeiserX/whisper-subs",
"host": "github.com",
"name": "whisper-subs",
"owner": "GeiserX"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 63,
"inputs": {
"security": 62,
"vitality": 83,
"community": 43,
"governance": 50,
"engineering": 75
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 83,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "good",
"name": "Development activity",
"note": null,
"notes": [],
"value": 78,
"inputs": {
"commits_last_year": 249,
"human_commit_share": 0.95,
"days_since_last_push": 3,
"active_weeks_last_year": 20
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 3 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 3
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "20/52 weeks with commits",
"points": 13.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 20
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "249 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 249
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 23 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": null,
"notes": [],
"value": 90,
"inputs": {
"releases_count": 91,
"latest_release_tag": "v4.3.1.0",
"releases_from_tags": false,
"days_since_latest_release": 10,
"mean_days_between_releases": 1.2
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "91 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 91
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 10 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 10
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~1.2 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 1.2
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 10,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 10 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 10
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 43,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "at_risk",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 37,
"inputs": {
"forks": 6,
"stars": 81,
"watchers": 1,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "81 stars",
"points": 30.9,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 81
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "6 forks",
"points": 5.8,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 6
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "1 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 1
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": false,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (GPL-3.0)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "GPL-3.0"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 50,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 14,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 3,
"top_contributor_share": 0.983
},
"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 98% of commits",
"points": 0.4,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 98
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "3 contributors",
"points": 4.1,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 3
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 82,
"inputs": {
"merged_prs": 102,
"open_issues": 2,
"closed_issues": 32,
"issue_closed_ratio": 0.941,
"closed_unmerged_prs": 1
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "94% of issues closed",
"points": 44,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 94
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "102/103 decided PRs merged",
"points": 37.9,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 102,
"decided": 103
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/18 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "moderate",
"name": "Ownership & stewardship",
"note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"verified_domain"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 62,
"inputs": {
"followers": 113,
"owner_type": "User",
"is_verified": null,
"owner_login": "GeiserX",
"public_repos": 186,
"account_age_days": 4302
},
"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": "113 followers of GeiserX",
"points": 14.8,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 113,
"login": "GeiserX"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "186 public repos, account ~11 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 186
}
},
{
"code": "account_age_years",
"params": {
"years": 11
}
}
],
"max_points": 25
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "good",
"name": "Engineering Quality",
"value": 75,
"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": false,
"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": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10",
"points": 20,
"status": "met",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "excellent",
"name": "Documentation",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"topics": [
"accessibility",
"ai",
"automation",
"csharp",
"dotnet",
"hacktoberfest",
"homelab",
"jellyfin",
"jellyfin-plugin",
"media-management",
"media-server",
"open-source",
"parakeet",
"self-hosted",
"speech-to-text",
"stt",
"subtitles",
"transcription",
"whisper",
"whisper-cpp"
],
"has_wiki": true,
"homepage": null,
"has_readme": true,
"has_docs_dir": true,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 25,
"status": "met",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "20 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 20
}
}
],
"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": 62,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"name": "Security posture",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 18,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 0,
"scorecard_aggregate": 5.2
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection is not maximal on development and all release branches",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "19 out of 19 merged PRs checked by a CI test -- score normalized to 10",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/18 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 0 contributing companies or organizations -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 23 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 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file detected",
"points": 2,
"status": "partial",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "Project has not signed or included provenance with any releases.",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"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 3 resolved dependencies against OSV; 5 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": 3
}
},
{
"code": "advisories_unassessed",
"params": {
"count": 5
}
},
{
"code": "advisories_repo_graph_caveat",
"params": {}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 0,
"affected_packages": 0,
"assessed_packages": 3,
"unassessed_packages": 5,
"affected_by_severity": "none",
"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": 3,
"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": 2
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "good",
"name": "AI Readiness",
"value": 78,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.979,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 41683
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "CLAUDE.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "93 of 95 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 93,
"sampled": 95
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": true,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0,
"toolchain_manifests": [
"WhisperSubs.Tests/WhisperSubs.Tests.csproj",
"WhisperSubs.csproj"
],
"dependency_bot_commit_share": 0.05
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "WhisperSubs.Tests/WhisperSubs.Tests.csproj, WhisperSubs.csproj (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "WhisperSubs.Tests/WhisperSubs.Tests.csproj, WhisperSubs.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": "C# (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "C#"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": "Dockerfile",
"points": 10,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "Dockerfile"
}
}
],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "no agent-authored commits among the last 100",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_authored_commits",
"params": {
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "5 of the last 100 commits are automated dependency updates",
"points": 8,
"status": "met",
"details": [
{
"code": "dependency_bot_commits",
"params": {
"count": 5,
"sampled": 100
}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "C#",
"largest_source_bytes": 105363,
"source_files_sampled": 107,
"oversized_source_files": 1
},
"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": "1/107 source files over 60KB",
"points": 54.5,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 107,
"oversized": 1
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
"Could not fetch nuget package 'WhisperSubs' from its registry"
],
"report_type": "repository",
"generated_at": "2026-07-24T07:55:45.588282Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/GeiserX/whisper-subs.svg",
"full_name": "GeiserX/whisper-subs",
"license_state": "standard",
"license_spdx": "GPL-3.0"
}