Informe JSON sin procesar legible por máquina
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 1261,
"has_wiki": false,
"homepage": null,
"languages": {
"Shell": 41197,
"JavaScript": 10331,
"TypeScript": 531706
},
"pushed_at": "2026-07-19T22:38:10Z",
"created_at": "2026-06-01T21:44:59Z",
"owner_type": "Organization",
"updated_at": "2026-07-19T12:56:04Z",
"description": "@broberg/ai-sdk — config-wrapper SDK",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": null,
"primary_language": "TypeScript",
"significant_languages": [
"TypeScript"
]
},
"owner": {
"blog": "broberg.ai",
"name": "broberg.ai",
"type": "Organization",
"login": "broberg-ai",
"company": null,
"location": "Denmark",
"followers": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/276013563?v=4",
"created_at": "2026-04-14T13:31:16Z",
"is_verified": null,
"public_repos": 10,
"account_age_days": 102
},
"license": {
"state": "absent",
"spdx_id": null,
"raw_spdx": null,
"file_present": false,
"scorecard_found": false,
"profile_has_license": false
},
"activity": {
"releases": [
{
"tag": "v0.25.1",
"kind": "patch",
"published_at": "2026-07-19T12:55:52Z"
},
{
"tag": "v0.25.0",
"kind": "minor",
"published_at": "2026-07-18T00:27:41Z"
},
{
"tag": "v0.24.0",
"kind": "minor",
"published_at": "2026-07-17T16:31:32Z"
},
{
"tag": "v0.23.0",
"kind": "minor",
"published_at": "2026-07-17T13:53:33Z"
},
{
"tag": "v0.22.0",
"kind": "minor",
"published_at": "2026-07-05T10:52:14Z"
},
{
"tag": "v0.21.1",
"kind": "patch",
"published_at": "2026-07-02T12:38:54Z"
},
{
"tag": "v0.21.0",
"kind": "minor",
"published_at": "2026-06-30T19:38:58Z"
},
{
"tag": "v0.20.0",
"kind": "minor",
"published_at": "2026-06-30T13:32:52Z"
},
{
"tag": "v0.19.0",
"kind": "minor",
"published_at": "2026-06-23T10:24:22Z"
},
{
"tag": "v0.18.0",
"kind": "minor",
"published_at": "2026-06-23T10:13:49Z"
},
{
"tag": "v0.17.1",
"kind": "patch",
"published_at": "2026-06-16T18:16:18Z"
},
{
"tag": "v0.17.0",
"kind": "minor",
"published_at": "2026-06-16T18:02:47Z"
},
{
"tag": "v0.16.0",
"kind": "minor",
"published_at": "2026-06-16T17:00:14Z"
},
{
"tag": "v0.15.0",
"kind": "minor",
"published_at": "2026-06-16T16:27:19Z"
},
{
"tag": "v0.14.0",
"kind": "minor",
"published_at": "2026-06-16T15:51:41Z"
},
{
"tag": "v0.13.1",
"kind": "patch",
"published_at": "2026-06-15T19:48:07Z"
},
{
"tag": "v0.13.0",
"kind": "minor",
"published_at": "2026-06-14T23:42:37Z"
},
{
"tag": "v0.12.0",
"kind": "minor",
"published_at": "2026-06-13T10:40:52Z"
},
{
"tag": "v0.11.0",
"kind": "minor",
"published_at": "2026-06-13T10:20:48Z"
},
{
"tag": "v0.10.5",
"kind": "patch",
"published_at": "2026-06-11T07:18:10Z"
},
{
"tag": "v0.10.4",
"kind": "patch",
"published_at": "2026-06-08T23:46:58Z"
},
{
"tag": "v0.10.3",
"kind": "patch",
"published_at": "2026-06-07T18:55:17Z"
},
{
"tag": "v0.10.2",
"kind": "patch",
"published_at": "2026-06-07T18:33:57Z"
},
{
"tag": "v0.10.1",
"kind": "patch",
"published_at": "2026-06-07T18:17:40Z"
},
{
"tag": "v0.10.0",
"kind": "minor",
"published_at": "2026-06-07T17:59:37Z"
},
{
"tag": "v0.9.1",
"kind": "patch",
"published_at": "2026-06-06T19:40:06Z"
},
{
"tag": "v0.9.0",
"kind": "minor",
"published_at": "2026-06-05T00:38:43Z"
},
{
"tag": "v0.8.0",
"kind": "minor",
"published_at": "2026-06-05T00:00:14Z"
},
{
"tag": "v0.7.0",
"kind": "minor",
"published_at": "2026-06-04T23:19:39Z"
},
{
"tag": "v0.6.0",
"kind": "minor",
"published_at": "2026-06-04T21:17:40Z"
},
{
"tag": "v0.5.1",
"kind": "patch",
"published_at": "2026-06-04T14:33:09Z"
},
{
"tag": "v0.5.0",
"kind": "minor",
"published_at": "2026-06-03T11:19:15Z"
},
{
"tag": "v0.4.1",
"kind": "patch",
"published_at": "2026-06-02T16:03:30Z"
},
{
"tag": "v0.4.0",
"kind": "minor",
"published_at": "2026-06-02T12:45:52Z"
},
{
"tag": "v0.3.1",
"kind": "patch",
"published_at": "2026-06-02T11:54:50Z"
},
{
"tag": "v0.3.0",
"kind": "minor",
"published_at": "2026-06-02T11:42:19Z"
},
{
"tag": "v0.2.0",
"kind": "minor",
"published_at": "2026-06-02T10:12:17Z"
},
{
"tag": "v0.1.2",
"kind": "patch",
"published_at": "2026-06-02T09:56:00Z"
},
{
"tag": "v0.1.1",
"kind": "patch",
"published_at": "2026-06-02T08:25:27Z"
}
],
"recent_commits": [
{
"oid": "54389c48e062f418d8b3e34688388d7cc6e7a61c",
"body": "F036 shipped word/segment timestamps but only the Whisper (openai) adapter\nhonored them — Azure/Mistral silently returned { text }. A repo with only\nAZURE_SPEECH_KEY (e.g. contentpush) couldn't use the timestamps API \"as\nannounced\". Azure fast-transcription already returns phrases + per-word ms\noffs\n[…]\nft as a verified follow-up.\n- Seal: 3 azure tests (word+segment parsed ms→sec, single \"segment\" hides\n words, no-timestamps stays plain text).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(F036.1): Azure adapter honors ai.transcribe timestamps too (v0.25.1)",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-19T12:55:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "619565a564f8c95f8bab15d4eb025fca1573afbc",
"body": "contentpush F016.5 (time-synced captions) needs a timing source for TTS'd\nspeech. ai.transcribe returned only { text, usage }; Whisper natively supports\nword + segment timestamps via verbose_json. Additive, opt-in, backward-compat.\n\n- ai.transcribe({ audio, timestamps: \"word\" | \"segment\" | (\"word\"|\"\n[…]\n audio only; word boundaries need the Speech SDK over WebSocket (a\ntransport re-architecture) — transcribe covers the caption use-case cheaply.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F036): opt-in word/segment timestamps on ai.transcribe (v0.25.0)",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-18T00:27:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aac792ccdd2341d7c60f8e63e4e860306416544b",
"body": "…ice (backlog)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F035): fal image extra/params passthrough + bless fal-recraft pr…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-07-17T20:39:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c670716e1be4dca15d89c8012f3392c430713ca6",
"body": "A consumer (happy-little-place) read \"image (fal.ai)\" and assumed the recraft\nvector slug was a fal app-id → 404 + $0 cost detour. Recraft SVG routes via\nOpenRouter's Image API (F033.1): the \"-vector\" slug is an OpenRouter model and\nreturns image/svg+xml with ground-truth cost. Note the raster(fal)/vector(OR)\nsplit so the next reader doesn't take the same wrong turn.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(README): clarify image route — recraft SVG is OpenRouter, not fal",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-17T20:37:10Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "550f3ce5f03cc5535c31d6a78fddcb04f1640382",
"body": "…om env\n\nRoot cause: createAI() reported to a cost sink ONLY when the caller passed\nconfig.costSink explicitly. Fleet-wide most call-sites don't (cardmem alone\nhad 4 createAI() on mistral-large with no sink) → ~91% of Mistral spend\n(125M input tokens = the €53 invoice) was invisible in upmetrics. Pe\n[…]\nd (which imports /registry).\n- Seal: 3 tests — no-sink+env auto-POSTs to /api/agent, ship-dark no-POST,\n explicit-sink-wins skips auto-wiring.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F034): cost-tracking on by default — auto-wire upmetrics sink fr…",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-17T16:31:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "03ab0a89b61e3c56493fca0edc208639037b6878",
"body": "…ery consumer\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F034): default env-based cost-sink in createAI() — auto-track ev…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-07-17T16:18:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b50ca2962a4600d225c10a6c8c85e3593b0210ca",
"body": "… (v0.23.0)\n\nFAL_KEY-only consumers (contentpush F014 video spike) can now call\nai.animate({ image, override:{ provider:'fal',\nmodel:'fal-ai/kling-video/v2.5-turbo/pro/image-to-video' } }) with correct\ncost-tracking instead of a misleading $0 — no raw-provider hack.\n\n- FAL_VIDEO_PRICE_PER_SEC: bless\n[…]\no) — fal is override-only.\n- Seal cost-tracking: a test that fails if the blessed model bills $0, plus\n a config.pricePerSecond override test.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F014): bless fal Kling 2.5 Turbo Pro i2v + $0.07/s cost-tracking…",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-17T13:53:33Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b5c5c37d2312c4a3be68bb824c60e95de2d80922",
"body": "npm v12's `npm publish --provenance` fails with \"Cannot find module\n'sigstore'\" (fleet-wide, flagged 2026-07-10). Pin to 11.5.1 (OIDC trusted\npublishing needs >= 11.5.1) instead of @latest so provenance minting works.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(ci): pin npm@11.5.1 in publish.yml — npm v12 breaks --provenance",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-17T13:53:33Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0ad5b00db927a96c3edaf63348dbefa93bc50387",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-16T10:27:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c15a5224471b90dad17414c28d42e6c2340b1528",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-13T13:50:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0e8c076e50da4b813d0635c943f8070b13205d57",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-13T11:55:32Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d28139fc17b9d7326eaf43cc3d433d6a9153a3dc",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-11T16:57:19Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c1b95175aee4f347b1ba0f1870d5a9ec5205fca4",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-10T22:16:15Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f66bb60a23e85d9091d3775d266c349780265a01",
"body": "Applied canonical cardmem hooks/skills/settings via the daemon (F075.3).",
"is_bot": false,
"headline": "chore(cardmem): update .claude templates to 851e0f45",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-10T22:16:15Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7ef4869b9be3ca8545d131e78bf471491d77d504",
"body": "…craft v4.1 image gen\n\nThree EU/provider capabilities land on the ai.image()/translate facade, all\nbuild+test green (335 tests):\n\n- F031 — Vertex AI Veo adapter: EU-resident image-to-video. Shared image-input\n helper extracted to src/providers/media.ts (URL/bytes/data-URI → inline base64).\n- F032 —\n[…]\nngle-image\n contract, ground-truth usage.cost with local price fallback. Unblocks Contentpush\n F003.3 (on-brand logos + brand illustrations).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F031,F032,F033): Vertex Veo (EU i2v) + DeepL (EU translate) + Re…",
"author_name": "Christian Broberg",
"author_login": null,
"committed_at": "2026-07-05T10:52:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "63c7622bd70c8682c67e7c9b0a9f0c24cc06b063",
"body": "…cardmem_write_plan\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F033): write docs/features/F033-contentpush-image-models.md via …",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-07-03T20:37:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "97b16e5191c734d95d03af6828e0573b1aaa6470",
"body": "… fixes)\n\nUpdate registry and wiring tests to verify fable-5 is now available and\nmythos-5 remains suspended (unverified).",
"is_bot": false,
"headline": "test: update availability tests for fable-5 re-enablement (additional…",
"author_name": "Aidan Nielsen",
"author_login": null,
"committed_at": "2026-07-02T12:38:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fb277febecfd58b5f454698f21ee7f0b1852708b",
"body": "Fable 5 is now available (re-enabled by Anthropic). Update resolve tests to\nverify fable-5 is available and use mythos (still suspended) for suspension-\nbehavior tests instead.",
"is_bot": false,
"headline": "test(F022): update availability tests for claude-fable-5 re-enablement",
"author_name": "Aidan Nielsen",
"author_login": null,
"committed_at": "2026-07-02T12:37:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "59aeefd04a2683561e7749744768038fb19ad7a4",
"body": null,
"is_bot": false,
"headline": "chore(release): v0.21.1 — re-enable claude-fable-5 (Anthropic restored)",
"author_name": "Aidan Nielsen",
"author_login": null,
"committed_at": "2026-07-02T12:33:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "185208627610526722929e722b4c7d53da70e38c",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ca546feb6dc78c0f0e7d08a5d6ec660fe73baecd",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b67fec69d5f7793d66c767ef4b34cebd4b7fe713",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "d9071dbce7f62b29daf046d3b7270c6b41b50427",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9fee94dd39ab4c4f83b3e67b8b78b8b24bc29531",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f392469a0fb3a5f0568f5958d14e5d99604f039d",
"body": "Applied canonical cardmem hooks/skills/settings via the daemon (F075.3).",
"is_bot": false,
"headline": "chore(cardmem): update .claude templates to e73d8ab0",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e4955313311c527d3d6c043df5140151d0c89c90",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-07-01T11:51:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dbb1729a5be12e372135086a8d04e9b274061877",
"body": "[skip ci]",
"is_bot": true,
"headline": "docs(F032): plan — DeepL translation adapter (EU, dedicated MT engine)",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-07-01T02:16:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8b1e06531645bbc2017d5d0cadd04daea308a8ab",
"body": "[skip ci]",
"is_bot": true,
"headline": "docs(F031): plan — Vertex AI Veo adapter (EU-resident image-to-video)",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-07-01T01:02:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "35afc252ffc6298c1545e8133ed64429484ef0f6",
"body": "…esolveModel fallback off Anthropic\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(F030): finish canonical ai-sdk CLAUDE.md block — env example + r…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-30T19:46:49Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a48d20f5e96d9e270ea73734a33da285338b4ccd",
"body": "…ral EU\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): v0.21.0 — F030 phase out Anthropic API default → Mist…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-30T19:38:58Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "9f7a836a94180ca8728d25bfe778be7d46a1cf63",
"body": "…econdary\n\nDEFAULT_TIER_MAP: fast/smart/powerful/vision off Anthropic → Mistral EU (Schrems II).\nfast/vision/cheap=mistral-small-latest, smart/powerful=mistral-large-latest. No default\ntier hits Anthropic (ANTHROPIC_API_KEY removed). New deepseekAdapter (direct, OpenAI-\ncompatible, DEEPSEEK_API_KEY)\n[…]\npt-in non-PII secondary; anthropic kept for\noverride-only. PII always stays on Mistral EU. CLAUDE.md tier table + mistral stub +\ntests updated.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F030): phase out Anthropic API default → Mistral EU + DeepSeek s…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-30T19:38:32Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9309be7a9f4db4560f34e25c7292fe1b651b5e2d",
"body": "…to-Text\n\n- F028: requestyAdapter (OpenRouter-alternative AI gateway, EU endpoint)\n- F029: Azure Speech-to-Text (transcribe) on azureAdapter, EU da-DK + phraseList\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): v0.20.0 — F028 Requesty provider + F029 Azure Speech-…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-30T13:32:52Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "0933e17c432c362305c3c466637c0e378e8e61e9",
"body": "… primary + DeepSeek V4 Pro secondary\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F030): plan — phase out Anthropic API default route → Mistral EU…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-30T13:26:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5c6f5209ae27312f22184e5f87482fe5661f511a",
"body": "…EU da-DK\n\nazureAdapter.transcribe() via fast transcription (regional EU host, da-DK forced —\nVoxtral can't), per-minute cost from the response's real duration, ship-dark. Generic\nphrases? on ai.transcribe → Azure definition.phraseList (api-version 2025-10-15;\n2024-11-15 rejects it). Live-verified Danish prose; phraseList wired but unproven on\nsynthetic audio (validate on real speech). Second EU STT next to Voxtral.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F029): Azure Speech-to-Text (transcribe) + phraseList biasing — …",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-29T21:12:36Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "a63adba636358663b1352835d872bcc185c33b38",
"body": "… EU da-DK\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F029): plan — Azure Speech-to-Text (transcribe) on azureAdapter,…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-29T16:55:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f899c15f7a3be236198358b4abd019afe0151fd0",
"body": "… endpoint)\n\nrequestyAdapter on the OpenAI-compatible core: 400+ models via one REQUESTY_API_KEY,\nground-truth usage.cost, ship-dark. eu:true → router.eu.requesty.ai (gateway-in-EU;\nend-to-end EU still needs an EU-region model slug). Opt-in upstream like openrouter;\nai-sdk facade unchanged.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F028): Requesty provider — OpenRouter-alternative AI gateway (EU…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-29T14:57:53Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1287a5316b088ea4262d08713f9040424d32f91d",
"body": "…ay, EU endpoint)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F028): plan — Requesty provider (OpenRouter-alternative AI gatew…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-29T11:35:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a28debfbc342563dec829577ac1e0bfba1478411",
"body": "…text\n\nThrowaway preview clips (cardmem F160 read-aloud use-case text) so Christian can\near-A/B the Azure neural Danish voices in cardmem's Chat→Artifacts. Generated live\nvia the F026 azureAdapter (swedencentral). Removable after the voice pick.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F026): Christel + Jeppe A/B samples of cardmem's daily-summary …",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-25T23:54:19Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "97717d179864e4c721d049dbd63ef3a37d874ae6",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): v0.19.0 — AI Pricing API (F027)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T10:24:50Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "07d71d9439da86e0293dae00172293be635ab6f2",
"body": "getModelPrice/listModelPrices/findModelPrices/priceCall/pricingGeneratedAt over all\n~346 inventory models, browser/edge-clean (no fs/bun:sqlite). gen-pricing.mjs trims\ninventory.json into a bundled pricing-data module; curated PRICING overlaid as\nauthoritative. Lets Trail (edge) read exact prices without reaching the ai-sdk session.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F027): AI Pricing API — @broberg/ai-sdk/pricing subpath",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T10:24:50Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6ac564f2ebc84c57c5ec7d6e04cf933d0dad710f",
"body": "…m package)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F027): plan — AI Pricing API (model prices queryable from the np…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-23T10:18:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "99ef32408276fd31ee913ab89e47675d74182bfb",
"body": "…ral TTS\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(release): v0.18.0 — F025 cost read-back client + F026 Azure Neu…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T10:13:49Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6ca38c44a7d1a235490b981895c0fa91c8e6bb16",
"body": "azureAdapter (Azure Speech, region-pinned EU, SSML, ship-dark) reachable via\noverride:{provider:'azure'}. Curated da-DK roster (3F+3M: Christel/Jeppe native +\nseraphina/ava/florian/andrew multilingual) exposed via listAzureDanishVoices().\nSpeaking-rate control (ai.tts rate) + per-voice defaultRate (Christel 0.85).\nCost-tracked per-char. ElevenLabs stays the ai.tts default. 285/285 green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F026): Azure Neural TTS provider (EU da-DK) behind ai.tts",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T10:11:36Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4841e7b381838edb0b793c4ba73dd2fa93e1ebb2",
"body": "…rate control\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F026): Christel speed samples (rate 0.9 + 0.85) — SSML prosody …",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T10:04:45Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "56baecc9be6db9a554c6ca831b3e72ed6bcbcd97",
"body": "3 female (christel native, seraphina/ava multilingual) + 3 male (jeppe native,\nflorian/andrew multilingual). Same Danish sentence for a fair A/B. Kept in-repo as testimonials.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F026): 6 Azure da-DK voice samples (3F + 3M) for selection",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T09:58:16Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ad4c53675c815615cd307c05fa54daace7c99df4",
"body": "… listen\n\nThrowaway preview clips so Christian can ear-A/B the Azure neural Danish voices.\nGenerated live via the F026 azureAdapter (swedencentral). Can be removed after the voice pick.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F026): Azure da-DK TTS voice samples (Christel + Jeppe) for A/B…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-23T09:52:24Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "59d7e748571d280ec9d0cfa0a77f4095ad2a243b",
"body": "[skip ci]",
"is_bot": true,
"headline": "docs(F026): plan — Azure Neural TTS provider (EU Danish) behind ai.tts",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-19T10:24:26Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c5932195717372c937473e8c8cc4baf7d47abd20",
"body": "… docs\n\nupmetricsCostClient reads your own rolled-up cost (summary/timeseries,\nmicro-USD, per-tenant groupBy) from Upmetrics' COST-API — the read companion\nto upmetricsSink. Positions upmetrics as the canonical cost method (#1);\ndiscord/sqlite are extras. Browser-clean (pure fetch, no bun:sqlite).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F025): Upmetrics cost read-back client + canonical cost-delivery…",
"author_name": "Aidan Nielsen",
"author_login": null,
"committed_at": "2026-06-19T10:14:10Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "fd83497eac171f1da95958a841da5afc1bef3790",
"body": "…ack client\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F025): plan — Upmetrics as canonical cost-delivery + cost read-b…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-18T16:59:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "09a274198c6d94e7a6c0e1c28e43714543a61c7d",
"body": "…hed to scene (v0.17.1)\n\nChristian's preference: generated dialogue is the weak link (esp. non-English) and\nhe won't use it; environment-matched ambient sound IS wanted. So every ai.animate\nprompt now gets a default directive appended — \"No spoken dialogue, no talking, no\nvoiceover. Include natural \n[…]\nso it applies to both the Veo and fal routes. Just describe\nthe scene; the SDK adds the audio guidance. 270 tests green; .env-parked CI parity.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F024): ai.animate audio default — no speech, ambient sounds matc…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T18:16:18Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "ffb9ad0d74fb291ca9dca229a1c9fc8cbb80b0a1",
"body": "…-verified)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(F024): record Veo-direct-via-Gemini pivot (shipped v0.17.0, live…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T18:04:15Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4fd1bd21fdd3dbeebbb1a02b107c9db9998dac70",
"body": "….17.0)\n\nLive-verified end-to-end: a still portrait → an 8s 1080p clip through createAI().\n\n- ai.animate({ image, prompt?, durationSec?, resolution? }) → { url, bytes?, mimeType?, usage }.\n New ProviderAdapter.animate? + Capability:\"animate\" + AnimateRequest/Result + schema.\n- DEFAULT route = Veo 3\n[…]\nata); durationSeconds is a number (not string).\n- Consent-gated, US-hosted (EU route deferred, F024.4). 270 tests green; .env-parked CI parity.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F024): ai.animate image-to-video — Veo 3.1 direct via Gemini (v0…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T18:02:47Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d0ab90c55e60a6e1d1314cffcd40cc8cd8b483df",
"body": "…ck, consent-gated\n\nInvestigation result: BFL does NOT do video (probed api.eu.bfl.ai /v1/{video,\nflux-video,i2v,...} → 404; /v1/video 403, image-only confirmed). Landscape:\nVeo/Grok/Runway/Luma = US, Kling/Seedance/Hailuo = CN, fal.ai aggregator = US.\n\nPolicy (Christian): EU-preferred when a route \n[…]\n chain. New ai.animate capability\n(ai.video is taken by F019 understanding). Interim plan with open Qs (first fal\nmodel, naming) for Christian.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(F024): plan — image-to-video (ai.animate), EU-first/US-CN-fallba…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T17:16:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "eac279a47a946e8d4151adc2990779d3631c3623",
"body": "bflCredits({ apiKey?, baseUrl?, fetch? }) → { credits, usd } — standalone export\n(not on the AiClient facade; BFL-specific). Reads GET /v1/credits (EU-pinned),\n1 credit = $0.01. For budget-gating before a generate call.\n\nBFL has NO pre-flight pricing endpoint (probed /v1/pricing|cost|estimate|\ncalcu\n[…]\n014, per-MP) + the real per-call cost are the honest answer.\n\n- bfl.test.ts: bflCredits EU-pin + USD conversion + missing-key throw. 267 green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F023.6): bflCredits() balance check + honest pricing docs (v0.16.0)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T17:00:14Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9787a4df5a2b9b331d4f1f78c71f00a6f4df7c37",
"body": "…e({referenceImages}) via BFL FLUX 2 (v0.15.0)\n\nBFL flux-2-max/pro support multi-reference generation: 1–8 reference photos\nstraight into the generate call, no finetune/training step. Live-verified\nend-to-end on api.eu.bfl.ai (and on a real face through createAI()): EU-resident\nwhole chain (submit a\n[…]\n (table/section/changelog) updated; supersedes the manual\n dashboard step for the common case (finetune stays for high-volume single subject).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F023.5): EU-resident person portraits with NO training — ai.imag…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T16:27:19Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "aac823cacc59af8058b4d5d6757f3cdbe50e0d1b",
"body": "…({finetune}) (v0.14.0)\n\nDelt flow: BFL retired finetune-CREATE from its public API (live-verified —\nPOST /v1/finetune 404s on every region while inference paths 422; legacy\neu1/us1 hosts TCP-dead), so a subject is trained once manually in dashboard.bfl.ai\n(mode=character, EU region); the SDK automa\n[…]\nty run clean.\n- F023 plan-doc reshaped BLOCKED → SHIPPED(delt flow) + manual-training SOP; API.md\n rows + v0.14.0 changelog + governance note.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(F023): EU-resident person/portrait generation via BFL — ai.image…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T15:51:41Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "4b5c4de1ae85e097c454648c30d5f5ae55cc028e",
"body": "… (all regions)\n\nLive-probed api.{eu,us,}.bfl.ai before building: the EU endpoint runs + manages\nfinetunes (inference flux-pro-*-finetuned, my_finetunes, finetune_details,\ndelete_finetune all present) but NO create/train endpoint exists on any region's\npublic OpenAPI (/v1/finetune 404s everywhere; e\n[…]\nfinetune can't be built; create is dashboard-only.\nF023 blocked pending Christian's re-decision (split dashboard+API / self-host EU / fal-DPA).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(F023): BLOCKER finding — BFL API has no finetune-create endpoint…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-16T15:19:28Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c591a82fb68f52993aaf9ac2c6bad22112419f4f",
"body": "…PR-safe)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F023): plan — Person/Portrait LoRA via Black Forest Labs (EU, GD…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-16T15:06:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c0e78b5e565747e8dd44955a5bee065cc03539b8",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-15T21:00:28Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1ded1e76e3955642c675aae8683c3cd90127e0ae",
"body": "…image (v0.13.1)\n\nVerified against Google's official ai.google.dev/gemini-api/docs/pricing (standard\npaid tier, 1K/1024px output):\n- ADD gemini-3.1-flash-image = $0.067/image (Google's recommended migration target\n for the deprecated Imagen 4 endpoints; resolution-tiered $0.045/0.067/0.101/0.151\n \n[…]\nNo 404 risk.\n\nTest switched to gemini-2.5-flash-image (the real $0.039 model) for the per-image\ncost assertion. 255 tests green; dist verified.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(gemini): correct gemini-3-pro image price + add gemini-3.1-flash-…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-15T19:48:07Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d66145f469070960f144cdc9879665b447cbf4bf",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore(F149): sync canonical CLAUDE.md sections (scaffold v2 reuse-first)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-15T05:55:21Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "7a900a88797f95ea46530a2819fe3fdd22ede8b1",
"body": "…st (v0.13.0)\n\nChristian policy shift (relayed via cardmem #5174):\n- `claude -p` is retired fleet-wide (agent-CLI transport moved to Layer 1 /tmux\n via buddycloud). The `cheap` tier no longer routes through it.\n- `cheap` now defaults to mistral-small-latest over HTTP — cheapest-that's-good-\n enoug\n[…]\nmem F149.4\nbackfills into all 15 repos) + README + API.md changelog + tier-map test.\n255 tests green; dist verified cheap→mistral-small-latest.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(routing): retire claude -p as cheap default → mistral-small-late…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-14T23:42:37Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "1c88fa97f7840089d5c1a33c9b61352f73ae2c17",
"body": "…gle source for cardmem F149.3 scaffold)\n\ncardmem scaffolds a fixed '## @broberg/ai-sdk — the AI/LLM gateway (MUST)'\nsection into every new broberg.ai repo (F149). Per Christian's one-source rule,\nthe canonical text lives HERE; cardmem's scaffolder (F149.3) pulls this file\nverbatim instead of a pasted copy, so model IDs / tiers update in one place.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: canonical @broberg/ai-sdk AI/LLM-gateway CLAUDE.md section (sin…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-14T22:05:53Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "653635cbbf09b76187de39d28f8d1dcb0bb6034a",
"body": "…stry (v0.12.0)\n\ncardmem build-verified that `import { listModels } from \"@broberg/ai-sdk\"`\nhard-fails in a Vite/Rollup browser build: the root barrel transitively pulls\nbun:sqlite (budget-store, sqlite-sink) + node:zlib (fal). That forced UI pickers\nthrough a per-repo server bridge — a fetch, defea\n[…]\nd. Subpath returns the Fable-suspended row byte-identical to the root\n(one source, no drift). 255 tests green; tsc clean. Root entry unchanged.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(availability): F022.5 browser-clean subpath @broberg/ai-sdk/regi…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-13T10:40:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "5d589ba91d64a83f494efade0529558f909ed4e3",
"body": "…try + refresh + listModels (v0.11.0)\n\nA runtime safety-net so a suspended/removed model never reaches a user as a raw\nprovider error (triggered by Anthropic's 2026-06-12 global Fable 5 / Mythos 5\nsuspension; requested via cardmem #4841, spawn-time contract refined #4842).\n\n- resolveModel(requested,\n[…]\n suspended\n primary before dispatch; default off → existing call sites byte-identical.\n\n255 tests green; built dist smoke-verified end-to-end.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(availability): F022 Model Availability Harness — resolve + regis…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-13T10:20:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b6d3a94a9529e61b9ff0ebbee0849dacd3ad87d7",
"body": "…lve) per cardmem #4842\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F022): bake in spawn-time hot-path contract (sync, zero-I/O reso…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-13T10:13:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d5f7319d3fc9fca9dd80c9511ee89e09c182ee1b",
"body": "…efresh + listModels)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F022): plan — Model Availability Harness (resolve + registry + r…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-13T10:12:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "48aee3c464dd1ebca05fd3c49fc7e4fb5ead8a38",
"body": "…o ai.vision/video (v0.10.5)\n\nTwo real gaps caught by cms (#4423) building a Lens vision-critic:\n\n1) chat() did `text = msg.content ?? ''` — but reasoning/multimodal models\n (magistral etc.) can return `content` as an ARRAY of blocks, which fell\n through and crashed the consumer with 'text.repla\n[…]\nstem message before the image/video message.\n\n227 suite green (array-content coercion + null-content + vision system-prepend);\ntypecheck clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(vision/chat): coerce reasoning-model array content + add system t…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-11T07:18:10Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "9072b0c51f0fd313751a6542c60d53d649e7b75d",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-10T15:29:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bca50f1e8b9ffc90f17c9b2197545db17f3ac5a3",
"body": "Self-description in the canonical locked form (YAML header + 8 prose sections,\nmatching webhousecode/buddy/RESEARCHTARGET.md) so the Research Adapter worker can\nroute + pre-filter articles by interest before waking this session, and the\nreceiving cc can judge fit fast. Interests: LLM models/pricing, provider APIs,\ncost optimization, multimodal, GDPR/EU hosting, model routing.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs: add RESEARCHTARGET.md (F125 Research Adapter fleet convention)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-09T16:17:47Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "ccc8e029b954303fe0c7a45eb22c24edee117ca6",
"body": "…v0.10.4)\n\ntoMessages early-returned input.messages and never reached the system-prepend\nbranch, so ai.chat({ system, messages }) silently DROPPED the system prompt — a\n'return ONLY JSON' instruction never reached the model. Affected every consumer\npassing both system + messages (caught by cms #4234\n[…]\ns).\n\n3 facade tests (system+messages preserved, no dup when caller leads with system,\nprompt-path unchanged); 224 suite green, typecheck clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(chat): keep top-level `system` when `messages` is also supplied (…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-08T23:46:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "38a0e2a798a5939112cf7f681e3cdbb6d922b923",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-08T21:46:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e48dcc334ce14fc130db1ee7e361b75f092a0aa5",
"body": "Applied canonical cardmem hooks/skills/settings via the daemon (F075.3).",
"is_bot": false,
"headline": "chore(cardmem): update .claude templates to 325da84d",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-08T11:47:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "07ff78768cb98e2824b011df48720c7e5e3f7103",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-07T23:51:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c81c7d443935a88ddf35d7bc9b305808264244e1",
"body": "…1.4, v0.10.3)\n\nfal's NSFW safety-checker occasionally false-positives on clean LoRA output and\nreturns a fully black image (has_nsfw_concepts[0]=true). sa's F021 pilot saw ~1/8.\nai.image({ retryOnBlack:true }) now detects the flag in the fal adapter and\nre-rolls ONCE with a fresh seed; both generat\n[…]\nmage behaviour unchanged.\n\n219→221 suite green (retry re-rolls + bills ×2; no-flag path untouched), typecheck\nclean. Plan-doc updated (F021.4).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(fal): ai.image retryOnBlack — re-roll fal NSFW black images (F02…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-07T18:55:17Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "d70e99c6453c6e8eb88cdb53600cba7a18f9af80",
"body": "…IFIED (F021, v0.10.2)\n\nRoot cause (found via a real run on Christian's test key): fal REJECTS a data:\nURI for images_data_url ('Invalid URL: URL too long'). The job reported COMPLETED\nbut the result was that 422 download error — which 0.10.0 mis-reported as 'no\ndiffusers_lora_file.url'. fal's real \n[…]\n$0.025\n219 suite green (storage initiate+PUT mocked; zip round-trip) + typecheck clean.\nscripts/verify-trainstyle.ts added for re-verification.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(fal): upload training zip to fal storage — ai.trainStyle LIVE-VER…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-07T18:33:57Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "f2eee01e2a23d028084d623f76893aacec9ff824",
"body": "….10.1)\n\nsa's live pilot hit 'no diffusers_lora_file.url in result' — fal's real training\nresponse shape didn't match the offline mock. fal's official OpenAPI confirms the\nfield IS diffusers_lora_file, so the real cause is a wrapper / non-OK result body,\nnot a rename. Fixes:\n\n- extractTrainedFiles()\n[…]\ned: 219 suite green (incl. extractTrainedFiles shape-variance + a\nraw-shape-error test); typecheck clean. Still no FAL key here → sa re-pilots.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(fal): robust ai.trainStyle output parsing + diagnostics (F021, v0…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-07T18:17:40Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "b5f5dd6b952c5b73bc9fb11f2107022818fb0bbf",
"body": "…v0.10.0)\n\nNew reusable capability: train a brand/style LoRA from a set of images, then\ngenerate in that style every time. Backed by fal flux-lora-fast-training (train)\n+ flux-lora (inference).\n\n- ai.trainStyle({ images, isStyle?, triggerWord?, steps? }) → { loraUrl, configUrl, usage }\n- ai.image({ \n[…]\nrity). NB no FAL_KEY in this session → sa runs the live $2\npilot train on the 8 illustrations. Plan: docs/features/F021-lora-style-training.md.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(fal): ai.trainStyle LoRA style-training + ai.image loras (F021, …",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-07T18:00:24Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "55c588efb96ffd77c24b34543673fcb8f7e5161d",
"body": "…+ ai.image loras)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F021): plan — fal LoRA style-training capability (ai.trainStyle …",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-07T17:52:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "846d3d1e763eb280e4e86f7cd557f93ad289620c",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-06T22:49:13Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "02c6e3d7d8997d2216e2ac39a6484f194eb1e9a8",
"body": "… (v0.9.1)\n\nDeepSeek made the 75%-off promo permanent (2026-05-22): V4-Pro $0.435/$0.87,\nV4-Flash $0.098/$0.197 per 1M — matches OpenRouter /api/v1/models 1:1. Adds both\nto the pricing table (keyed openrouter:deepseek/deepseek-v4-*) so cost is never\nlogged $0, + a unit test and a live smoke script.\n\n[…]\nat goes API-billed on 15 Jun).\n\nInventory.json already carried both V4 entries, so the Model Advisor knew them;\nthis closes the cost-table gap.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(pricing): DeepSeek V4 via OpenRouter — official permanent prices…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-06T19:40:06Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "eb164b2c91e9ba0824ff40203c975e8a222807fc",
"body": "Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "chore: gitignore *.bak backup artifacts",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:57:35Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "1ae9d99ec3de2f4f9c90787ac90c7109bdcc814b",
"body": "Close the F020.3/F020.4 doc-AC gap surfaced during board-sweep auto-review:\nai.tts had no capabilities-table row and neither capability had a usage\nsection. Adds ai.tts row, a Podcast & speech section, and the named Danish\nvoice registry (soren/jesper/mads/noam/camilla).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "docs(F020): document ai.tts + ai.podcast usage + named Danish voices",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:47:23Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b69b680ef94b507d430a35affc79d19d10cd5e13",
"body": "…rch automation\n\nai.embedding (mistral-embed) + ai.transcribe (Voxtral) + ai.batch.* (50% async,\nF016.1/.3/.5). Monthly model-research GHA workflow + inventory cheap-model enrichment\n(F014.4/.5, F017.5/.6). All live-verified where the test keys allow (batch needs\nMistral billing; Voxtral is non-Danish).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.9.0 — Mistral embeddings/transcribe/batch + monthly resea…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:38:43Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "4af82fcc7d11786f99d12cdbd64589eb7115c5a0",
"body": "ai.batch.submit({requests:[{customId,prompt}]}) → {jobId,status}; status(jobId);\nresults(jobId). Mistral: upload JSONL via /v1/files (purpose=batch) → POST /v1/batch/jobs\n→ poll /batch/jobs/{id} → download /files/{output}/content (JSONL → {customId,text}).\nProviderAdapter.batchSubmit/Status/Results.\n[…]\nistral Batch API requires account billing (402 'enable billing')\n— the test key lacks batch access; full round-trip is async (≤24h) regardless.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(mistral): ai.batch.* — async batch chat at 50% cost (F016.1)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:38:05Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "92972cac52f9b6c5a35939f16e9f11ee81d1e718",
"body": "…f org blocks Actions PR-create\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "ci(research): resilient PR step — fall back to branch + compare URL i…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:19:53Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "de66987a79558d6cf7f52d20ee8fd6e1971e4c28",
"body": "…lert (F014.4/.5 + F017.5/.6)\n\nF014.4 + F017.5 — .github/workflows/research-models.yml: monthly (cron) + manual\n(workflow_dispatch). Fetches the live catalogue (OpenRouter public, no key), runs\nthe drift report, rebuilds inventory.json, and opens a PR when the inventory changes\nSUBSTANTIVELY (timest\n[…]\ns the build).\n\nLIVE-VERIFIED: --enrich 3 → real tags+summaries (e.g. liquid/lfm-2 → reasoning,coding,\nedge,fast). typecheck clean, suite green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(research): monthly GHA workflow + inventory enrichment + drift a…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:17:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3bf78845f454fc3dfccf44656e0ea76cc3c4e926",
"body": "ai.embedding via mistral-embed/codestral-embed (POST /v1/embeddings, per-token).\nai.transcribe via Voxtral (POST /v1/audio/transcriptions multipart, voxtral-mini-latest,\nper-minute $0.002). Both optional ProviderAdapter methods on the mistral adapter.\n\nLIVE-VERIFIED: mistral-embed → 1024-dim vectors\n[…]\norrect text ($0.000167). NB Voxtral does NOT support\nDanish (ar/en/de/es/fr/hi/it/nl/pt/zh/ru/ko/ja only) — Danish transcription needs Whisper.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(mistral): embeddings (F016.5) + Voxtral transcribe (F016.3)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:14:58Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "c447d0888d52afc14cfee5ad0e97cc35678652f4",
"body": "…tions)",
"is_bot": false,
"headline": "chore(cardmem): commit scaffolded onboarding config (.claude + conven…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:09:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a18fb721289329b5abd99ecdcee165ba106078fe",
"body": "Instant multi-voice podcasts: ai.podcast({script,voices}) → one episode MP3 via\nElevenLabs Text-to-Dialogue (eleven_v3). ai.tts({text,voice}) single voice. Named\nDanish voices (soren/jesper/mads/noam/camilla). Apps send a finished manuscript →\nfinished episode in one call. Live-verified (native Danish MP3s, per-char cost).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.8.0 — ai.podcast + ai.tts via ElevenLabs (F020)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-05T00:00:14Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "b6540ee8ea3cb008d82dcbdb986c7a212290c951",
"body": "…20.4)\n\nF020.3 — ELEVENLABS_DANISH_VOICES registry (soren/jesper/mads/noam/camilla → voiceId)\n+ resolveVoice(); ai.podcast voices map now accepts friendly names or raw IDs.\nF020.4 — ai.tts({text, voice}) single-voice capability over ElevenLabs\n(eleven_multilingual_v2, good Danish); ProviderAdapter.t\n[…]\nIFIED: ai.tts({voice:'soren'}) → real 81KB Danish MP3 ($0.012). Named-voice\nresolution + ai.tts unit-tested. Full suite green, typecheck clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(podcast): named Danish voices + ai.tts single-voice (F020.3 + F0…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T23:49:55Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "947ac5a7c1ac11a9b24fa747c3c5f6a608746c8c",
"body": "…bs (F020.1 + F020.2)\n\nNew ai.podcast({script:[{speaker,text}], voices:{speaker->voiceId}}) → one\nmulti-voice MP3 episode via ElevenLabs Text-to-Dialogue (eleven_v3), per-character\ncost. ElevenLabs provider adapter (dialogue + tts + listVoices). 'podcast' capability,\ndefault route elevenlabs/eleven_\n[…]\nequire\na PAID ElevenLabs plan (free-tier 402 on library voices via API); the 25 default voices\nwork on free + eleven_v3 speaks the Danish text.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(podcast): ai.podcast() instant multi-voice podcasts via ElevenLa…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T23:42:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "3a0c75749d3e0fa7d44084d116bb435242e8ac73",
"body": "…abs)\n\n[skip ci]",
"is_bot": true,
"headline": "docs(F020): plan — instant podcast generation (ai.podcast via ElevenL…",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-04T23:31:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "31099c3cd61674dcfbd84e593dc8632a602da5e3",
"body": "ai.ocr({document}) → {pages:[{index,markdown}], usage} (mistral-ocr, per-page) and\nai.moderate({input}) → {results:[{flagged,categories,categoryScores}], usage}\n(mistral-moderation, per-token). Both live-verified. FysioDK-launch-critical:\npatient-document OCR + moderate-client-notes-before-DB, EU/GDPR-hosted.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.7.0 — ai.ocr + ai.moderate via Mistral (F016.2 + F016.4)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T23:19:39Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "f6d1b462ac5b4fcbbe83d56cd4cf1ec270ddc5bb",
"body": "… F016.4\n\nai.ocr({document, mimeType?}) → {pages:[{index,markdown}], usage} via Mistral\n/ocr (mistral-ocr-latest), $0.002/page. ai.moderate({input}) → {results:[{flagged,\ncategories,categoryScores}], usage} via /moderations (mistral-moderation-latest),\nper-token ($0.10/M). Both optional ProviderAdap\n[…]\n Danish →\nflagged=false, threat → flagged=true (violence_and_threats 0.997), $0.0000117.\n200 tests green, typecheck clean. docs/API.md updated.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(mistral): ai.ocr (per-page) + ai.moderate (per-token) — F016.2 +…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T22:40:00Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8c63cfb1f5250a31742d8a95b9469cba21aa6983",
"body": "The 'sends inline + prices' + 'default tier' tests used createAI() with the\ndefault keyless gemini adapter — resolveKey() threw 'API key not set' in CI (no\n.env). Register geminiAdapter({apiKey:'test-key'}) instead; verified green with\n.env moved aside (195/195). Fixes the v0.6.0 publish-workflow failure.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "test(video): key the gemini adapter explicitly so CI (no .env) passes",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T21:17:40Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "bafbd34391ae47326a2451bfe39ac036a42b4d6b",
"body": "…der/prices\n\nai.video() ships: new video ContentPart + capability + 'video' tier\n(gemini-2.5-flash-lite). Live-verified on a real clip (gemini-flash-lite, gemma-4,\nnemotron). Also bundles the unreleased v0.5.x work: official Mistral provider +\nmistral.ai prices (F015), gemini-direct $0-cost fix + OpenRouter pricing drift fix.\ndocs/API.md documents ai.video.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "release: v0.6.0 — ai.video native video vision (F019) + Mistral provi…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T21:15:08Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "6a1ac6f43f508476286ac1c7f5d81da09526c17b",
"body": "…nemotron)\n\nai.video() proven end-to-end against the real OpenRouter API: both gemma-4\n($0.0003) and nvidia-nemotron ($0, free) described a real 2MB clip sent inline as\na base64 video_url data-URL. Confirms the openai-compatible video_url wire shape.\nAdds scripts/smoke-video.mjs for repeatability. Gemini-direct path (F019.2) works\nthe same once that key has credit.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(video): F019.3 OpenRouter video LIVE-verified (gemma-4 + nvidia-…",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T21:10:05Z",
"body_truncated": false,
"is_coding_agent": true
},
{
"oid": "cc5da12e89eca6f7ddeec64456fa4b1dfc30a2b6",
"body": "New 'video' ContentPart + ai.video({video, prompt, override?}) capability,\nrouted through the vision message path. Default 'video' tier → gemini-2.5-flash-lite\n(priced 0.1/0.4). Gemini adapter sends video inline as base64 (video mime); >~20MB\nclips need the Files API (not yet handled). OpenAI-compat\n[…]\n-flash-lite on the real clip) PENDING — the Gemini key's prepay\ncredits are depleted (429). Test clip compressed to 2MB (inline-ready) at /tmp.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "feat(video): ai.video() native video-vision capability (F019.1 + F019.2)",
"author_name": "Christian Broberg",
"author_login": "cbroberg",
"committed_at": "2026-06-04T20:34:44Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "7b6cfad3792bf50a87f0d8e59eea478619d5ccbc",
"body": "[skip ci]",
"is_bot": true,
"headline": "docs(F016): add embeddings (F016.5) + classifier (F016.6) stories",
"author_name": "projects[bot]",
"author_login": null,
"committed_at": "2026-06-04T20:24:18Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 39,
"commits_last_year": 179,
"latest_release_at": "2026-07-19T12:55:52Z",
"latest_release_tag": "v0.25.1",
"releases_from_tags": true,
"days_since_last_push": 6,
"active_weeks_last_year": 8,
"days_since_latest_release": 6,
"mean_days_between_releases": 2.9
},
"community": {
"has_readme": true,
"has_license": false,
"has_description": true,
"has_contributing": false,
"health_percentage": 25,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": false
},
"ecosystem": {
"packages": [
{
"name": "@broberg/ai-sdk",
"exists": true,
"license": "FSL-1.1-Apache-2.0",
"keywords": [],
"ecosystem": "npm",
"matches_repo": true,
"registry_url": "https://www.npmjs.com/package/@broberg/ai-sdk",
"is_deprecated": false,
"latest_version": "0.25.1",
"repository_url": "https://github.com/broberg-ai/ai-sdk",
"versions_count": 40,
"total_downloads": null,
"dependents_count": null,
"deprecation_note": null,
"maintainers_count": 1,
"monthly_downloads": 3525,
"first_published_at": "2026-06-02T08:09:43.990000Z",
"latest_published_at": "2026-07-19T22:38:34.392000Z",
"latest_version_yanked": null,
"days_since_latest_publish": 6
}
]
},
"popularity": {
"forks": 0,
"stars": 0,
"watchers": 0,
"fork_history": {
"days": [],
"complete": true,
"collected": 0,
"total_forks": 0
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0,
"collected_at": null
},
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [
"tsconfig.json"
],
"toolchain_manifests": [],
"largest_source_bytes": 29347,
"source_files_sampled": 130,
"oversized_source_files": 0,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 38283
},
"dependencies": {
"manifests": [
"package.json"
],
"advisories": {
"error": null,
"scope": "published_package",
"source": "osv",
"findings": [],
"collected": true,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 1,
"malicious_count": 0,
"assessed_package": "npm:@broberg/ai-sdk@0.25.1",
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"npm"
],
"dependencies": [
{
"name": "zod",
"manifest": "package.json",
"ecosystem": "npm",
"version_constraint": "^3.23.8"
}
],
"all_dependencies": {
"error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
"source": null,
"packages": [],
"collected": false,
"truncated": false,
"total_count": null,
"direct_count": null,
"indirect_count": null
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 1,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 0
},
"bus_factor": 1,
"bot_contributors": 0,
"top_contributors": [
{
"type": "User",
"login": "cbroberg",
"commits": 117,
"avatar_url": "https://avatars.githubusercontent.com/u/486755?v=4"
}
],
"contributors_sampled": 1,
"top_contributor_share": 1
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"publish.yml",
"research-models.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": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 6,
"reason": "project has 2 contributing companies or organizations -- score normalized to 6",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 0,
"reason": "no update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 0,
"reason": "license file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "project was created within the last 90 days. Please review its contents carefully",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": 10,
"reason": "packaging workflow detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 9,
"reason": "1 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "54389c48e062f418d8b3e34688388d7cc6e7a61c",
"ran_at": "2026-07-25T22:47:32Z",
"aggregate_score": 3.2,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-19T22:38:38Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2026-06-04T16:03:24Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/broberg-ai/ai-sdk",
"host": "github.com",
"name": "ai-sdk",
"owner": "broberg-ai"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"security": 46,
"vitality": 71,
"community": 24,
"governance": 53,
"engineering": 62
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "good",
"name": "Vitality",
"value": 71,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "moderate",
"name": "Development activity",
"note": null,
"notes": [],
"value": 60,
"inputs": {
"commits_last_year": 179,
"human_commit_share": 0.83,
"days_since_last_push": 6,
"active_weeks_last_year": 8
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 6 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 6
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "8/52 weeks with commits",
"points": 5.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 8
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "179 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 179
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 88,
"inputs": {
"releases_count": 39,
"latest_release_tag": "v0.25.1",
"releases_from_tags": true,
"days_since_latest_release": 6,
"mean_days_between_releases": 2.9
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "39 version tags (no GitHub releases)",
"points": 16.2,
"status": "partial",
"details": [
{
"code": "version_tags_no_releases",
"params": {
"count": 39
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 6 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 6
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~2.9 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 2.9
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "unverified",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": "repository_too_young",
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": null,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "maintenance record not established from the collected data",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_unverified",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "critical",
"name": "Community & Adoption",
"value": 24,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 1,
"inputs": {
"forks": 0,
"stars": 0,
"watchers": 0,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "0 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 0
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "0 watchers",
"points": 0,
"status": "missed",
"details": [
{
"code": "watchers",
"params": {
"count": 0
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "critical",
"name": "Community health",
"note": null,
"notes": [],
"value": 25,
"inputs": {
"has_readme": true,
"has_license": false,
"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": "no license file detected",
"points": 0,
"status": "missed",
"details": [
{
"code": "license_absent",
"params": {}
}
],
"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
}
]
},
{
"key": "ecosystem_adoption",
"band": "moderate",
"name": "Ecosystem adoption (downloads)",
"note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"registry_dependents"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 59,
"inputs": {
"packages": [
"@broberg/ai-sdk"
],
"dependents": null,
"ecosystems": "npm",
"total_downloads": null,
"monthly_downloads": 3525
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "3,525 downloads/month across npm",
"points": 47.3,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 3525,
"ecosystems": "npm"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "not reported by this ecosystem",
"points": 0,
"status": "excluded",
"details": [
{
"code": "not_reported_by_this_ecosystem",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "moderate",
"name": "Sustainability & Governance",
"value": 53,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "critical",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 16,
"inputs": {
"bus_factor": 1,
"contributors_sampled": 1,
"top_contributor_share": 1
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "1 contributor(s) cover half of all commits",
"points": 9,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 1
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 100% of commits",
"points": 0,
"status": "missed",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 100
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "1 contributors",
"points": 1.4,
"status": "partial",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 1
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 2 contributing companies or organizations -- score normalized to 6",
"points": 6,
"status": "partial",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "good",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 72,
"inputs": {
"merged_prs": 1,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 0
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "1/1 decided PRs merged",
"points": 38.2,
"status": "met",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 1,
"decided": 1
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "at_risk",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 40,
"inputs": {
"followers": 1,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "broberg-ai",
"public_repos": 10,
"account_age_days": 102
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "1 followers of broberg-ai",
"points": 2.2,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 1,
"login": "broberg-ai"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "10 public repos, account ~0 yr old",
"points": 8.1,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 10
}
},
{
"code": "account_age_years",
"params": {
"years": 0
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"@broberg/ai-sdk"
],
"ecosystems": "npm",
"any_deprecated": false,
"min_days_since_publish": 6
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on npm",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "npm"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 6 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 6
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "40 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 40
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 62,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "moderate",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 60,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": false,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "2 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 2
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 65,
"inputs": {
"topics": [],
"has_wiki": false,
"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": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 46,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 32,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 3.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 not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 2 contributing companies or organizations -- score normalized to 6",
"points": 1.5,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "no update tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "project was created within the last 90 days. Please review its contents carefully",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "1 existing vulnerabilities detected",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "dependency_advisories",
"band": "excellent",
"name": "Dependency advisories",
"note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:@broberg/ai-sdk@0.25.1 runtime dependency closure — what installing the published package pulls in — 1 packages. Reachability is not analyzed.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"no_advisories_left_outstanding"
]
}
},
{
"code": "weights_renormalized",
"params": {}
},
{
"code": "advisories_scope_published",
"params": {
"package": "npm:@broberg/ai-sdk@0.25.1",
"assessed": 1
}
},
{
"code": "advisories_reachability",
"params": {}
}
],
"value": 100,
"inputs": {
"source": "osv",
"advisories": 0,
"affected_packages": 0,
"assessed_packages": 1,
"unassessed_packages": 0,
"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": "no indirect dependency carries a known advisory",
"points": 25,
"status": "met",
"details": [
{
"code": "no_indirect_advisories",
"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": 1,
"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": 3
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "moderate",
"name": "AI Readiness",
"value": 68,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 1,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 38283
},
"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": "83 of 83 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 83,
"sampled": 83
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "at_risk",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 43,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [
"tsconfig.json"
],
"agent_commit_share": 0.67,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "tsconfig.json",
"points": 11,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "tsconfig.json"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "67 of the last 100 commits agent-authored or agent-credited",
"points": 10,
"status": "met",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 67,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "no automated dependency updates observed",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_dependency_automation",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "TypeScript",
"largest_source_bytes": 29347,
"source_files_sampled": 130,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "TypeScript (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "TypeScript"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/130 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 130,
"oversized": 0
}
}
],
"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": [
"GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
],
"report_type": "repository",
"generated_at": "2026-07-25T22:47:37.985501Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/b/broberg-ai/ai-sdk.svg",
"full_name": "broberg-ai/ai-sdk",
"license_state": "absent",
"license_spdx": null
}